twinkle-1.4.2/0000777000175000001440000000000011151327717010201 500000000000000twinkle-1.4.2/m4/0000777000175000001440000000000011151327700010511 500000000000000twinkle-1.4.2/m4/vl_lib_readline.m40000644000175000001440000000726511127670450014021 00000000000000# =========================================================================== # http://autoconf-archive.cryp.to/vl_lib_readline.html # =========================================================================== # # SYNOPSIS # # VL_LIB_READLINE # # DESCRIPTION # # Searches for a readline compatible library. If found, defines # `HAVE_LIBREADLINE'. If the found library has the `add_history' function, # sets also `HAVE_READLINE_HISTORY'. Also checks for the locations of the # necessary include files and sets `HAVE_READLINE_H' or # `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or # 'HAVE_HISTORY_H' if the corresponding include files exists. # # The libraries that may be readline compatible are `libedit', # `libeditline' and `libreadline'. Sometimes we need to link a termcap # library for readline to work, this macro tests these cases too by trying # to link with `libtermcap', `libcurses' or `libncurses' before giving up. # # Here is an example of how to use the information provided by this macro # to perform the necessary includes or declarations in a C file: # # #ifdef HAVE_LIBREADLINE # # if defined(HAVE_READLINE_READLINE_H) # # include # # elif defined(HAVE_READLINE_H) # # include # # else /* !defined(HAVE_READLINE_H) */ # extern char *readline (); # # endif /* !defined(HAVE_READLINE_H) */ # char *cmdline = NULL; # #else /* !defined(HAVE_READLINE_READLINE_H) */ # /* no readline */ # #endif /* HAVE_LIBREADLINE */ # # #ifdef HAVE_READLINE_HISTORY # # if defined(HAVE_READLINE_HISTORY_H) # # include # # elif defined(HAVE_HISTORY_H) # # include # # else /* !defined(HAVE_HISTORY_H) */ # extern void add_history (); # extern int write_history (); # extern int read_history (); # # endif /* defined(HAVE_READLINE_HISTORY_H) */ # /* no history */ # #endif /* HAVE_READLINE_HISTORY */ # # LAST MODIFICATION # # 2008-04-12 # # COPYLEFT # # Copyright (c) 2008 Ville Laurikari # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. AC_DEFUN([VL_LIB_READLINE], [ AC_CACHE_CHECK([for a readline compatible library], vl_cv_lib_readline, [ ORIG_LIBS="$LIBS" for readline_lib in readline edit editline; do for termcap_lib in "" termcap curses ncurses; do if test -z "$termcap_lib"; then TRY_LIB="-l$readline_lib" else TRY_LIB="-l$readline_lib -l$termcap_lib" fi LIBS="$ORIG_LIBS $TRY_LIB" AC_TRY_LINK_FUNC(readline, vl_cv_lib_readline="$TRY_LIB") if test -n "$vl_cv_lib_readline"; then break fi done if test -n "$vl_cv_lib_readline"; then break fi done if test -z "$vl_cv_lib_readline"; then vl_cv_lib_readline="no" LIBS="$ORIG_LIBS" fi ]) if test "$vl_cv_lib_readline" != "no"; then AC_DEFINE(HAVE_LIBREADLINE, 1, [Define if you have a readline compatible library]) AC_CHECK_HEADERS(readline.h readline/readline.h) AC_CACHE_CHECK([whether readline supports history], vl_cv_lib_readline_history, [ vl_cv_lib_readline_history="no" AC_TRY_LINK_FUNC(add_history, vl_cv_lib_readline_history="yes") ]) if test "$vl_cv_lib_readline_history" = "yes"; then AC_DEFINE(HAVE_READLINE_HISTORY, 1, [Define if your readline library has \`add_history']) AC_CHECK_HEADERS(history.h readline/history.h) fi fi ])dnl twinkle-1.4.2/src/0000777000175000001440000000000011151327752010767 500000000000000twinkle-1.4.2/src/im/0000777000175000001440000000000011151327737011377 500000000000000twinkle-1.4.2/src/im/msg_session.h0000644000175000001440000002444711127714043014021 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Instant message session. * SIP does not have a concept of message sessions. It's up to the * user interface to create the illusion of a session by grouping * messages between 2 users. */ #ifndef _MSG_SESSION_H #define _MSG_SESSION_H #include #include #include "id_object.h" #include "exceptions.h" #include "user.h" #include "sockets/url.h" #include "parser/media_type.h" #include "patterns/observer.h" using namespace std; namespace im { /** * Maximum length for inline text messages. Longer texts are shown * as attachments. */ const size_t MAX_INLINE_TEXT_LEN = 10240; /** Message direction. */ enum t_direction { MSG_DIR_IN, /**< Incoming. */ MSG_DIR_OUT /**< Outgoing. */ }; /** Text format. */ enum t_text_format { TXT_PLAIN, /**< Plain */ TXT_HTML, /**< HTML */ }; /** Message composing state. */ enum t_composing_state { COMPOSING_STATE_IDLE, COMPOSING_STATE_ACTIVE }; /** * Convert a state name a conveyed in an im_iscomposing body to a state. * @param state_name [in] The state name to convert. * @return The composing state. If the state name is unknown, then * COMPOSING_STATE_IDE is returned. */ t_composing_state string2composing_state(const string &state_name); /** * Convert a composing state to a string for an im_iscomposing body. * @param state [in] The composing state to convert. * @return The string. */ string composing_state2string(t_composing_state state); /** * Single message with meta information. * In the current implementation a message either contains a text message * or an attachment. * TODO: use multipart MIME to send a text message with an attachment. */ class t_msg : public t_id_object { public: string subject; /**< Subject of the message. */ string message; /**< The message text. */ t_direction direction; /**< Direction of the message. */ time_t timestamp; /**< Timestamp of the message. */ t_text_format format; /**< Text format. */ bool has_attachment; /**< Indicates if an attachment is present. */ string attachment_filename; /**< File name of stored attachment. */ t_media attachment_media; /**< Media type of attachment */ string attachment_save_as_name; /**< Suggested 'save as' filename */ /** Constructor. */ t_msg(); /** * Constructor. * Sets the timestamp to the current time. * @param msg [in] The message. * @param dir [in] Direction of the message. * @param fmt [in] Text format of the message. */ t_msg(const string &msg, t_direction dir, t_text_format fmt); /** * Add an attachment to the message. * @param filename [in] File name (full path) of the attachment. * @param media [in] Media type of the attachment. * @param save_as [in] Suggested file name for saving. */ void set_attachment(const string &filename, const t_media &media, const string &save_as); }; /** * Message session. * It's up to the user interface to create a message session and store * all messages in it. The session is just a container to store a * collection of page-mode messages. */ class t_msg_session : public patterns::t_subject { private: t_user *user_config; /**< User profile of the local user. */ t_display_url remote_party; /**< Remote party. */ list messages; /**< Messages sent/received. */ /** Indicates if a new message has been added to the list of message. */ bool new_message_added; bool error_recvd; /**< Indicates that an error has been received. */ string error_msg; /**< Received error message. */ /** Indicates that a delivery notification has been received. */ bool delivery_notification_recvd; /** Received delivery notification. */ string delivery_notification; bool msg_in_flight; /**< Indicates if an outgoing message is in flight. */ /** Indicates if a composing state indication must be sent to the remote party. */ bool send_composing_state; /** Message composing state of the local party. */ t_composing_state local_composing_state; /** Timeout in seconds till the active state of the local party expires. */ time_t local_idle_timeout; /** Timeout in seconds till a refresh of the active state indication must be sent. */ time_t local_refresh_timeout; /** Message composing state of the remote party. */ t_composing_state remote_composing_state; /** Timeout in seconds till the active state of the remote party expires. */ time_t remote_idle_timeout; public: /** * Constructor. * @param u [in] User profile of the local user. */ t_msg_session(t_user *u); /** * Constructor. * @param u [in] User profile of the local user. * @param _remote_party [in] URL of remote party. */ t_msg_session(t_user *u, t_display_url _remote_party); /** Destructor. */ ~t_msg_session(); /** @name getters */ //@{ t_user *get_user(void) const; t_display_url get_remote_party(void) const; const list &get_messages(void) const; t_composing_state get_remote_composing_state(void) const; //@} /** @name setters */ //@{ void set_user(t_user *u); void set_remote_party(const t_display_url &du); void set_send_composing_state(bool enable); //@} /** * Get the last message of the session. * @return The last message. * @throws empty_list_exception There are no messages. */ t_msg get_last_message(void); /** Check if a new message has been added. */ bool is_new_message_added(void) const; /** * Set the display name of the remote party if it is not yet set. * @param display [in] The display name to set. */ void set_display_if_empty(const string &display); /** * Add a received message to the session. * @param msg [in] The message to add. */ void recv_msg(const t_msg &msg); /** * Send a message to the remote party. * The message will be added to the list of messages. * @param message [in] Message to be sent. * @param format [in] Text format of the message. */ void send_msg(const string &message, t_text_format format); /** * Send a message with file attachment to the remote party. * The message will be added to the list of messages. * @param filename [in] Name of file to be sent. * @param media [in] Mime type of the file. * @param subject [in] Subject of message. */ void send_file(const string &filename, const t_media &media, const string &subject); /** * Set the error message of the session. * @param message [in] Error message. * @post @ref error_msg == message * @post @ref error_recvd == true */ void set_error(const string &message); /** * Check if an error has been received. * @return true, if an error has been received. * @return false, otherwise */ bool error_received(void) const; /** * Take the error message from the session. * @return Error message. * @pre @ref error_received() == true * @post @ref error_received() == false */ string take_error(void); /** * Set the delivery notification of the session. * @param notification [in] Delivery notification. * @post @ref delivery_notification == notification * @post @ref delivery_notification_recvd == true */ void set_delivery_notification(const string ¬ification); /** * Check if a delivery notification has been received. * @return true, if an error has been received. * @return false, otherwise */ bool delivery_notification_received(void) const; /** * Take the delivery notification from the session. * @return Delivery notification. * @pre @ref delivery_notification_received() == true * @post @ref delivery_notification_received() == false */ string take_delivery_notification(void); /** * Check if the session matches with a particular user and * remote party. * @param user [in] The user * @param remote_party [in] URL of the remote party * @return true, if there is a match * @return false, otherwise */ bool match(t_user *user, t_url _remote_party); /** * Set the message in flight indicator. * @param in_flight [in] Indicator value to set. */ void set_msg_in_flight(bool in_flight); /** * Check if a message is in flight. * @return true, message is in flight. * @return false, no message is in flight. */ bool is_msg_in_flight(void) const; /** * Set the local composing state. * If the state transitions to a new state, then a composing indication * is sent to the remote party. * The local idle timeout and refresh timeout timers are updated depending * on the current state. * @param state [in] The new local composing state. */ void set_local_composing_state(t_composing_state state); /** * Set the remote composing state. * The remote idle timeout timer is updated depending on the state. * @param state [in] The new remote composing state. * @param idle_timeout [in] The idle timeout value when state == active. * @note When state == idle, then the idle_timout argument has no meaning. */ void set_remote_composing_state(t_composing_state state, time_t idle_timeout = 120); /** * Decrement the timeout values for the local composing state if * the current state is active. * If the idle timeout reaches zero, then the state transitions * to idle, and an idle indication is sent to the remote party. * If the refresh timeout reaches zero, then an active indication * is sent to the remote party. * If the current state is idle, then nothing is done. */ void dec_local_composing_timeout(void); /** Decrement the timeout values for the remote composing state if * the current state is active. * If the idle timeout reaches zero, then the state transitions * to idle. * If the current state is idle, then nothing is done. */ void dec_remote_composing_timeout(void); }; }; // end namespace #endif twinkle-1.4.2/src/im/im_iscomposing_body.cpp0000644000175000001440000001162411134632653016054 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "im_iscomposing_body.h" #include #include #include "log.h" #include "util.h" #include "audits/memman.h" #define IM_ISCOMPOSING_NAMESPACE "urn:ietf:params:xml:ns:im-iscomposing" #define IS_IM_ISCOMPOSING_TAG(node, tag) IS_XML_TAG(node, tag, IM_ISCOMPOSING_NAMESPACE) #define IS_IM_ISCOMPOSING_ATTR(attr, attr_name) IS_XML_ATTR(attr, attr_name, IM_ISCOMPOSING_NAMESPACE) bool t_im_iscomposing_xml_body::extract_data(void) { assert(xml_doc); state_.clear(); refresh_ = 0; xmlNode *root_element = NULL; // Get root root_element = xmlDocGetRootElement(xml_doc); if (!root_element) { log_file->write_report("im-iscomposing document has no root element.", "t_im_iscomposing_xml_body::extract_data", LOG_NORMAL, LOG_WARNING); return false; } // Check if root is if (!IS_IM_ISCOMPOSING_TAG(root_element, "isComposing")) { log_file->write_report("im-iscomposing document has invalid root element.", "t_im_iscomposing_xml_body::extract_data", LOG_NORMAL, LOG_WARNING); return false; } xmlNode *child = root_element->children; // Process children of root. bool state_present = false; for (xmlNode *cur_node = child; cur_node; cur_node = cur_node->next) { if (IS_IM_ISCOMPOSING_TAG(cur_node, "state")) { state_present = process_node_state(cur_node); } else if (IS_IM_ISCOMPOSING_TAG(cur_node, "refresh")) { process_node_refresh(cur_node); } } // The state node is mandatory, so return only true if it is present. return state_present; } bool t_im_iscomposing_xml_body::process_node_state(xmlNode *node) { assert(node); xmlNode *child = node->children; if (child && child->type == XML_TEXT_NODE) { state_ = tolower((char*)child->content); } else { log_file->write_report(" element has no content.", "t_im_iscomposing_xml_body::process_node_state", LOG_NORMAL, LOG_WARNING); return false; } return true; } void t_im_iscomposing_xml_body::process_node_refresh(xmlNode *node) { assert(node); xmlNode *child = node->children; if (child && child->type == XML_TEXT_NODE) { refresh_ = atoi((char*)child->content); } else { log_file->write_report(" element has no content.", "t_im_iscomposing_xml_body::process_node_refresh", LOG_NORMAL, LOG_WARNING); } } void t_im_iscomposing_xml_body::create_xml_doc( const string &xml_version, const string &charset) { t_sip_body_xml::create_xml_doc(xml_version, charset); // isComposing xmlNode *node_iscomposing = xmlNewNode(NULL, BAD_CAST "isComposing"); xmlNs *ns_im_iscomposing = xmlNewNs(node_iscomposing, BAD_CAST IM_ISCOMPOSING_NAMESPACE, NULL); xmlDocSetRootElement(xml_doc, node_iscomposing); // state xmlNewChild(node_iscomposing, ns_im_iscomposing, BAD_CAST "state", BAD_CAST state_.c_str()); // refresh if (refresh_ > 0) { xmlNewChild(node_iscomposing, ns_im_iscomposing, BAD_CAST "refresh", BAD_CAST int2str(refresh_).c_str()); } } t_im_iscomposing_xml_body::t_im_iscomposing_xml_body() : t_sip_body_xml (), state_(IM_ISCOMPOSING_STATE_IDLE), refresh_(0) {} t_sip_body *t_im_iscomposing_xml_body::copy(void) const { t_im_iscomposing_xml_body *body = new t_im_iscomposing_xml_body(*this); MEMMAN_NEW(body); // Clear the xml_doc pointer in the new body, as a copy of the // XML document must be copied to the body. body->xml_doc = NULL; copy_xml_doc(body); return body; } t_body_type t_im_iscomposing_xml_body::get_type(void) const { return BODY_IM_ISCOMPOSING_XML; } t_media t_im_iscomposing_xml_body::get_media(void) const { return t_media("application", "im-iscomposing+xml"); } bool t_im_iscomposing_xml_body::parse(const string &s) { if (t_sip_body_xml::parse(s)) { if (!extract_data()) { MEMMAN_DELETE(xml_doc); xmlFreeDoc(xml_doc); xml_doc = NULL; } } return (xml_doc != NULL); } string t_im_iscomposing_xml_body::get_state(void) const { return state_; } time_t t_im_iscomposing_xml_body::get_refresh(void) const { return refresh_; } void t_im_iscomposing_xml_body::set_state(const string &state) { state_ = state; } void t_im_iscomposing_xml_body::set_refresh(time_t refresh) { refresh_ = refresh; } twinkle-1.4.2/src/im/Makefile.am0000644000175000001440000000031211134651104013330 00000000000000AM_CPPFLAGS = -Wall $(CCRTP_CFLAGS) $(XML2_CFLAGS) -I$(top_srcdir)/src noinst_LIBRARIES = libim.a libim_a_SOURCES =\ im_iscomposing_body.cpp\ msg_session.cpp\ im_iscomposing_body.h\ msg_session.h twinkle-1.4.2/src/im/Makefile.in0000644000175000001440000003731311151323406013354 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/im DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libim_a_AR = $(AR) $(ARFLAGS) libim_a_LIBADD = am_libim_a_OBJECTS = im_iscomposing_body.$(OBJEXT) \ msg_session.$(OBJEXT) libim_a_OBJECTS = $(am_libim_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libim_a_SOURCES) DIST_SOURCES = $(libim_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = -Wall $(CCRTP_CFLAGS) $(XML2_CFLAGS) -I$(top_srcdir)/src noinst_LIBRARIES = libim.a libim_a_SOURCES = \ im_iscomposing_body.cpp\ msg_session.cpp\ im_iscomposing_body.h\ msg_session.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/im/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/im/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libim.a: $(libim_a_OBJECTS) $(libim_a_DEPENDENCIES) -rm -f libim.a $(libim_a_AR) libim.a $(libim_a_OBJECTS) $(libim_a_LIBADD) $(RANLIB) libim.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/im_iscomposing_body.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg_session.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/im/msg_session.cpp0000644000175000001440000002437211134633032014345 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "msg_session.h" #include #include #include "im_iscomposing_body.h" #include "log.h" #include "phone.h" #include "translator.h" #include "parser/media_type.h" #include "utils/file_utils.h" #define COMPOSING_LOCAL_IDLE_TIMEOUT 15 #define COMPOSING_LOCAL_REFRESH_TIMEOUT 90 extern t_phone *phone; using namespace im; using namespace utils; t_composing_state im::string2composing_state(const string &state_name) { if (state_name == IM_ISCOMPOSING_STATE_ACTIVE) { return COMPOSING_STATE_ACTIVE; } return COMPOSING_STATE_IDLE; } string im::composing_state2string(t_composing_state state) { switch (state) { case COMPOSING_STATE_IDLE: return "idle"; case COMPOSING_STATE_ACTIVE: return "active"; default: assert(false); } return "idle"; } // class t_msg t_msg::t_msg() : has_attachment(false) { struct timeval t; gettimeofday(&t, NULL); timestamp = t.tv_sec; } t_msg::t_msg(const string &msg, t_direction dir, t_text_format fmt) : message(msg), direction(dir), format(fmt), has_attachment(false) { struct timeval t; gettimeofday(&t, NULL); timestamp = t.tv_sec; } void t_msg::set_attachment(const string &filename, const t_media &media, const string &save_as) { attachment_filename = filename; attachment_media = media; attachment_save_as_name = save_as; has_attachment = true; } // class t_msg_session t_msg_session::t_msg_session(t_user *u) : user_config(u), new_message_added(false), error_recvd(false), delivery_notification_recvd(false), msg_in_flight(false), send_composing_state(u->get_im_send_iscomposing()), local_composing_state(COMPOSING_STATE_IDLE), local_idle_timeout(0), local_refresh_timeout(0), remote_composing_state(COMPOSING_STATE_IDLE), remote_idle_timeout(0) {} t_msg_session::t_msg_session(t_user *u, t_display_url _remote_party) : user_config(u), remote_party(_remote_party), new_message_added(false), error_recvd(false), delivery_notification_recvd(false), msg_in_flight(false), send_composing_state(u->get_im_send_iscomposing()), local_composing_state(COMPOSING_STATE_IDLE), local_idle_timeout(0), local_refresh_timeout(0), remote_composing_state(COMPOSING_STATE_IDLE), remote_idle_timeout(0) {} t_msg_session::~t_msg_session() { // Remove temporary files. for (list::iterator it = messages.begin(); it != messages.end(); ++it) { // Temporary files are created for incoming messages only. if (it->has_attachment && it->direction == MSG_DIR_IN) { // Defensive check to make sure we are deleting tmp files only. if (sys_config->is_tmpfile(it->attachment_filename)) { log_file->write_header("t_msg_session::~t_msg_session"); log_file->write_raw("Remove tmp file "); log_file->write_raw(it->attachment_filename); log_file->write_endl(); log_file->write_footer(); unlink(it->attachment_filename.c_str()); } } } } t_user *t_msg_session::get_user(void) const { return user_config; } t_display_url t_msg_session::get_remote_party(void) const { return remote_party; } t_composing_state t_msg_session::get_remote_composing_state(void) const { return remote_composing_state; } void t_msg_session::set_user(t_user *u) { user_config = u; } void t_msg_session::set_remote_party(const t_display_url &du) { remote_party = du; } void t_msg_session::set_send_composing_state(bool enable) { send_composing_state = enable; } t_msg t_msg_session::get_last_message(void) { new_message_added = false; if (messages.empty()) { throw empty_list_exception(); } return messages.back(); } bool t_msg_session::is_new_message_added(void) const { return new_message_added; } void t_msg_session::set_display_if_empty(const string &display) { if (remote_party.display.empty()) { remote_party.display = display; } } const list &t_msg_session::get_messages(void) const { return messages; } void t_msg_session::recv_msg(const t_msg &msg) { // RFC 3994 3.3 // The composing state of the remote party transitions to idle // when a message is received. remote_composing_state = COMPOSING_STATE_IDLE; remote_idle_timeout = 0; messages.push_back(msg); new_message_added = true; notify(); } void t_msg_session::send_msg(const string &message, t_text_format format) { // RFC 3994 3.2 // If a content message is sent before the idle threshold expires, no // "idle" state indication is needed. // The local state is set to idle without sending an indication to the // remote party. local_composing_state = COMPOSING_STATE_IDLE; local_idle_timeout = 0; local_refresh_timeout = 0; t_msg msg(message, im::MSG_DIR_OUT, format); messages.push_back(msg); new_message_added = true; bool ret = phone->pub_send_message(user_config, remote_party.url, remote_party.display, msg); if (ret) { msg_in_flight = true; } else { set_error(TRANSLATE("Failed to send message.")); } notify(); } void t_msg_session::send_file(const string &filename, const t_media &media, const string &subject) { // RFC 3994 3.2 // If a content message is sent before the idle threshold expires, no // "idle" state indication is needed. // The local state is set to idle without sending an indication to the // remote party. local_composing_state = COMPOSING_STATE_IDLE; local_idle_timeout = 0; local_refresh_timeout = 0; t_msg msg; msg.set_attachment(filename, media, strip_path_from_filename(filename)); msg.subject = subject; msg.direction = MSG_DIR_OUT; messages.push_back(msg); new_message_added = true; bool ret = phone->pub_send_message(user_config, remote_party.url, remote_party.display, msg); if (ret) { msg_in_flight = true; notify(); } else { // Notify user interface about the sent message before // setting the error. notify(); set_error(TRANSLATE("Failed to send message.")); } } void t_msg_session::set_error(const string &message) { error_msg = message; error_recvd = true; notify(); } bool t_msg_session::error_received(void) const { return error_recvd; } string t_msg_session::take_error(void) { if (!error_recvd) return ""; error_recvd = false; return error_msg; } void t_msg_session::set_delivery_notification(const string ¬ification) { delivery_notification = notification; delivery_notification_recvd = true; notify(); } bool t_msg_session::delivery_notification_received(void) const { return delivery_notification_recvd; } string t_msg_session::take_delivery_notification(void) { if (!delivery_notification_recvd) return ""; delivery_notification_recvd = false; return delivery_notification; } bool t_msg_session::match(t_user *user, t_url _remote_party) { return user == user_config && _remote_party == remote_party.url; } void t_msg_session::set_msg_in_flight(bool in_flight) { msg_in_flight = in_flight; notify(); } bool t_msg_session::is_msg_in_flight(void) const { return msg_in_flight; } void t_msg_session::set_local_composing_state(t_composing_state state) { if (!remote_party.is_valid()) { // The session is not yet established return; } switch (local_composing_state) { case COMPOSING_STATE_IDLE: switch (state) { case COMPOSING_STATE_IDLE: break; case COMPOSING_STATE_ACTIVE: local_composing_state = state; local_idle_timeout = COMPOSING_LOCAL_IDLE_TIMEOUT; local_refresh_timeout = COMPOSING_LOCAL_REFRESH_TIMEOUT - 10; if (send_composing_state) { (void)phone->pub_send_im_iscomposing( user_config, remote_party.url, remote_party.display, IM_ISCOMPOSING_STATE_ACTIVE, COMPOSING_LOCAL_REFRESH_TIMEOUT); } break; default: assert(false); } break; case COMPOSING_STATE_ACTIVE: switch (state) { case COMPOSING_STATE_IDLE: local_composing_state = state; local_idle_timeout = 0; local_refresh_timeout = 0; if (send_composing_state) { (void)phone->pub_send_im_iscomposing( user_config, remote_party.url, remote_party.display, IM_ISCOMPOSING_STATE_IDLE, COMPOSING_LOCAL_REFRESH_TIMEOUT); } break; case COMPOSING_STATE_ACTIVE: local_idle_timeout = COMPOSING_LOCAL_IDLE_TIMEOUT; break; default: assert(false); } break; default: assert(false); } } void t_msg_session::set_remote_composing_state(t_composing_state state, time_t idle_timeout) { switch (remote_composing_state) { case COMPOSING_STATE_IDLE: switch (state) { case COMPOSING_STATE_IDLE: break; case COMPOSING_STATE_ACTIVE: remote_composing_state = state; remote_idle_timeout = idle_timeout; notify(); break; default: assert(false); } break; case COMPOSING_STATE_ACTIVE: switch (state) { case COMPOSING_STATE_IDLE: remote_composing_state = state; remote_idle_timeout = 0; notify(); break; case COMPOSING_STATE_ACTIVE: remote_idle_timeout = idle_timeout; break; } break; default: assert(false); } } void t_msg_session::dec_local_composing_timeout(void) { if (local_composing_state == COMPOSING_STATE_IDLE) return; local_idle_timeout--; if (local_idle_timeout == 0) { set_local_composing_state(COMPOSING_STATE_IDLE); } else { local_refresh_timeout--; if (local_refresh_timeout == 0) { local_refresh_timeout = COMPOSING_LOCAL_REFRESH_TIMEOUT - 10; if (send_composing_state) { (void)phone->pub_send_im_iscomposing( user_config, remote_party.url, remote_party.display, IM_ISCOMPOSING_STATE_ACTIVE, COMPOSING_LOCAL_REFRESH_TIMEOUT); } } } } void t_msg_session::dec_remote_composing_timeout(void) { if (remote_composing_state == COMPOSING_STATE_IDLE) return; remote_idle_timeout--; if (remote_idle_timeout == 0) { set_remote_composing_state(COMPOSING_STATE_IDLE); } } twinkle-1.4.2/src/im/im_iscomposing_body.h0000644000175000001440000000446511127714043015522 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * RFC 3994 im-iscomposing+xml body */ #ifndef _IM_ISCOMPOSING_BODY_H #define _IM_ISCOMPOSING_BODY_H #include #include #include #include "parser/sip_body.h" using namespace std; //@{ /** @name Message composition states */ #define IM_ISCOMPOSING_STATE_IDLE "idle" #define IM_ISCOMPOSING_STATE_ACTIVE "active" //@} /** RFC 3994 im-iscomposing+xml body */ class t_im_iscomposing_xml_body : public t_sip_body_xml { private: string state_; /**< Composition state */ time_t refresh_; /**< Refresh interval in seconds */ /** Extract information elements from the XML document. */ bool extract_data(void); /** * Process the state element. * @param node [in] The state element. */ bool process_node_state(xmlNode *node); /** * Process the refresh element. * @param node [in] The refresh element. */ void process_node_refresh(xmlNode *node); protected: /** * Create a im-iscomposing document from the values stored in the attributes. */ virtual void create_xml_doc(const string &xml_version = "1.0", const string &charset = "UTF-8"); public: /** Constructor */ t_im_iscomposing_xml_body(); virtual t_sip_body *copy(void) const; virtual t_body_type get_type(void) const; virtual t_media get_media(void) const; virtual bool parse(const string &s); /** @name Getters */ //@{ string get_state(void) const; time_t get_refresh(void) const; //@} /** @name Setters */ //@{ void set_state(const string &state); void set_refresh(time_t refresh); //@} }; #endif twinkle-1.4.2/src/gui/0000777000175000001440000000000011151327752011553 500000000000000twinkle-1.4.2/src/gui/buddyform.ui.h0000644000175000001440000001073511127714044014252 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void BuddyForm::init() { getAddressForm = 0; } void BuddyForm::destroy() { if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } } void BuddyForm::showNew(t_buddy_list &_buddy_list, QListViewItem *_profileItem) { user_config = _buddy_list.get_user_profile(); edit_mode = false; buddy_list = &_buddy_list; profileItem = _profileItem; QDialog::show(); } void BuddyForm::showEdit(t_buddy &buddy) { user_config = buddy.get_user_profile(); edit_mode = true; edit_buddy = &buddy; buddy_list = edit_buddy->get_buddy_list(); nameLineEdit->setText(buddy.get_name().c_str()); phoneLineEdit->setText(buddy.get_sip_address().c_str()); subscribeCheckBox->setChecked(buddy.get_may_subscribe_presence()); phoneLineEdit->setEnabled(false); phoneTextLabel->setEnabled(false); addressToolButton->hide(); QDialog::show(); } void BuddyForm::validate() { QString name = nameLineEdit->text().stripWhiteSpace(); QString address = phoneLineEdit->text().stripWhiteSpace(); if (name.isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a name.").ascii(), MSG_CRITICAL); nameLineEdit->setFocus(); return; } string dest = ui->expand_destination(user_config, address.ascii()); t_url dest_url(dest); if (!dest_url.is_valid()) { ((t_gui *)ui)->cb_show_msg(this, tr("Invalid phone.").ascii(), MSG_CRITICAL); phoneLineEdit->setFocus(); return; } if (edit_mode) { // Edit existing buddy bool must_subscribe = false; bool must_unsubscribe = false; if (edit_buddy->get_may_subscribe_presence() != subscribeCheckBox->isChecked()) { if (subscribeCheckBox->isChecked()) { must_subscribe = true;; } else { must_unsubscribe = true; } } edit_buddy->set_name(nameLineEdit->text().stripWhiteSpace().ascii()); edit_buddy->set_sip_address(phoneLineEdit->text().stripWhiteSpace().ascii()); edit_buddy->set_may_subscribe_presence(subscribeCheckBox->isChecked()); if (must_subscribe) edit_buddy->subscribe_presence(); if (must_unsubscribe) edit_buddy->unsubscribe_presence(); } else { // Add a new buddy t_buddy buddy; buddy.set_name(nameLineEdit->text().stripWhiteSpace().ascii()); buddy.set_sip_address(phoneLineEdit->text().stripWhiteSpace().ascii()); buddy.set_may_subscribe_presence(subscribeCheckBox->isChecked()); t_buddy *new_buddy = buddy_list->add_buddy(buddy); new BuddyListViewItem(profileItem, new_buddy); new_buddy->subscribe_presence(); } string err_msg; if (!buddy_list->save(err_msg)) { QString msg = tr("Failed to save buddy list: %1").arg(err_msg.c_str()); ((t_gui *)ui)->cb_show_msg(this, msg.ascii(), MSG_CRITICAL); } accept(); } void BuddyForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &, const QString &)), this, SLOT(selectedAddress(const QString &, const QString &))); getAddressForm->show(); } void BuddyForm::selectedAddress(const QString &name, const QString &phone) { nameLineEdit->setText(name); phoneLineEdit->setText(phone); } twinkle-1.4.2/src/gui/lang/0000777000175000001440000000000011151327754012476 500000000000000twinkle-1.4.2/src/gui/lang/Makefile.am0000644000175000001440000000220711120014300014417 00000000000000pkglangdir = $(pkgdatadir)/lang pkglang_DATA = \ twinkle_nl.qm \ twinkle_de.qm \ twinkle_cs.qm \ twinkle_fr.qm \ twinkle_ru.qm \ twinkle_sv.qm CLEANFILES = $(pkglang_DATA) EXTRA_DIST = \ twinkle_nl.ts \ twinkle_de.ts \ twinkle_cs.ts \ twinkle_fr.ts \ twinkle_ru.ts \ twinkle_sv.ts \ twinkle_xx.ts twinkle_nl.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_nl.ts -qm $@ twinkle_de.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_de.ts -qm $@ twinkle_cs.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_cs.ts -qm $@ twinkle_fr.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_fr.ts -qm $@ twinkle_ru.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_ru.ts -qm $@ twinkle_sv.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_sv.ts -qm $@ twinkle-1.4.2/src/gui/lang/Makefile.in0000644000175000001440000003367611151323406014464 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/gui/lang DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(pkglangdir)" pkglangDATA_INSTALL = $(INSTALL_DATA) DATA = $(pkglang_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ pkglangdir = $(pkgdatadir)/lang pkglang_DATA = \ twinkle_nl.qm \ twinkle_de.qm \ twinkle_cs.qm \ twinkle_fr.qm \ twinkle_ru.qm \ twinkle_sv.qm CLEANFILES = $(pkglang_DATA) EXTRA_DIST = \ twinkle_nl.ts \ twinkle_de.ts \ twinkle_cs.ts \ twinkle_fr.ts \ twinkle_ru.ts \ twinkle_sv.ts \ twinkle_xx.ts all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/gui/lang/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/gui/lang/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh uninstall-info-am: install-pkglangDATA: $(pkglang_DATA) @$(NORMAL_INSTALL) test -z "$(pkglangdir)" || $(mkdir_p) "$(DESTDIR)$(pkglangdir)" @list='$(pkglang_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(pkglangDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglangdir)/$$f'"; \ $(pkglangDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglangdir)/$$f"; \ done uninstall-pkglangDATA: @$(NORMAL_UNINSTALL) @list='$(pkglang_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pkglangdir)/$$f'"; \ rm -f "$(DESTDIR)$(pkglangdir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(pkglangdir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-pkglangDATA install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am uninstall-pkglangDATA .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-pkglangDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-info-am uninstall-pkglangDATA twinkle_nl.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_nl.ts -qm $@ twinkle_de.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_de.ts -qm $@ twinkle_cs.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_cs.ts -qm $@ twinkle_fr.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_fr.ts -qm $@ twinkle_ru.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_ru.ts -qm $@ twinkle_sv.qm: $(top_builddir)/src/gui/twinkle $(top_srcdir)/src/gui/twinkle.pro lrelease $(LRELEASEOPTION) $(srcdir)/twinkle_sv.ts -qm $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/gui/lang/twinkle_de.ts0000644000175000001440000103674211151060223015105 00000000000000 AddressCardForm Twinkle - Address Card Twinkle - Adresseintrag &Remark: Anme&rkung: Infix name of contact. Mittlerer Name oder Titel. First name of contact. Vorname oder allg. linker Namensbestandteil. Sortierschlüssel! &First name: &Vorname: You may place any remark about the contact here. Feld für beliebige Anmerkungen. Eigene Spalte, nach der sortiert werden kann - klicken Sie hierzu einfach auf den Spaltenkopf in der Adressliste. &Phone: &Telefon: &Infix name: &Titel: Phone number or SIP address of contact. Telefonnummer oder SIP-Adresse des Kontakts. Last name of contact. Nachname oder allg. rechter Namensbestandteil. &Last name: &Nachname: &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Alt+C Alt+C You must fill in a name. Sie müssen einen Namen angeben. You must fill in a phone number or SIP address. Sie müssen eine Nummer oder SIP-Adresse angeben. AuthenticationForm Twinkle - Authentication Twinkle - Anmeldung user No need to translate The user for which authentication is requested. Der anzumeldende Benutzer. profile No need to translate The user profile of the user for which authentication is requested. Das anzumeldende Benutzerprofil. User profile: Benutzerprofil: User: Benutzer: &Password: &Passwort: Your password for authentication. Ihr Anmeldepasswort. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ihr SIP-Anmeldename. Häufig identisch mit Ihrem SIP-Nutzernamen, dann leerlassen. Falls nicht, wird Ihr Provider dies mitteilen. &User name: N&utzername : &OK &Cancel Abbruch (Es&c) Login required for realm: Login nötig für Realm: realm No need to translate The realm for which you need to authenticate. Der Realm, für den Sie sich anmelden müssen. BuddyForm Twinkle - Buddy Twinkle - Buddy Address book Adressbuch Select an address from the address book. Name und Rufnummer/SIP-Adresse aus Adressbuch kopieren. &Phone: &Telefon: Name of your buddy. Lokaler Name für Buddy-Eintrag. &Show availability Online-&Status anzeigen Alt+S Alt+S Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. Wenn aktiviert, erfragt Twinkle den Online-Status (Erreichbarkeit) des Buddy. Diese Funktion muss vom Provider des Buddy und gegebenenfalls auch von Ihrem Provider durch bereitstellen eines "presence agent" im Netz unterstützt werden, um zu funktionieren. &Name: &Name: SIP address your buddy. SIP-Adresse des Buddy. &OK &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Alt+C Alt+C You must fill in a name. Sie müssen einen Namen angeben. Invalid phone. Unzulässige SIP-Adresse. Failed to save buddy list: %1 Fehler beim Speichern der Buddyliste: "%1" BuddyList Availability Online-Status unknown unbekannt offline offline online online request rejected Abfrage nicht angenommen not published nicht bekanntgegeben failed to publish Bekanntgeben nicht möglich request failed Abfrage fehlgeschlagen Click right to add a buddy. Mit Rechtsklick Buddy hinzufügen. CoreAudio Failed to open sound card Fehler beim Öffnen Soundkarte Failed to create a UDP socket (RTP) on port %1 Fehler beim Erzeugen des UDP socket (RTP) für Port %1 Failed to create audio receiver thread. Fehler beim Erzeugen "audio receiver thread". Failed to create audio transmitter thread. Fehler beim Erzeugen "audio transmitter thread". CoreCallHistory local user lokal remote user Gegenstelle failure Fehler unknown unbekannt in kommend out gehend DeregisterForm Twinkle - Deregister Twinkle - Abmelden deregister all devices alle Endgeräte abmelden &OK &Cancel Abbruch (Es&c) DiamondcardProfileForm Twinkle - Diamondcard User Profile Your Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. &Account ID: &PIN code: &Your name: <p align="center"><u>Sign up for a Diamondcard account</u></p> &OK Alt+O &Cancel Abbruch (Es&c) Alt+C Fill in your account ID. Fill in your PIN code. A user profile with name %1 already exists. Your Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> DtmfForm Twinkle - DTMF Keypad Tastatur 2 3 Over decadic A. Normally not needed. Funktionstaste A. Selten benötigt. 4 5 6 Over decadic B. Normally not needed. Funktionstaste B. Selten benötigt. 7 8 9 Over decadic C. Normally not needed. Funktionstaste C. Selten benötigt. Star (*) Stern (*) 0 Pound (#) Raute (#) Over decadic D. Normally not needed. Funktionstaste D. Selten benötigt. 1 &Close S&chliessen Alt+C Alt+C FreeDeskSysTray Show/Hide Wiederherstellen/Minimieren Quit Beenden GUI Failed to create a UDP socket (SIP) on port %1 Fehler beim Erzeugen des UDP socket (SIP) für Port %1 The following profiles are both for user %1 Die folgenden Benutzerprofile verwenden den gleichen SIP-Benutzernamen "%1" You can only run multiple profiles for different users. Gleichzeitig aktive Benutzerprofile müssen eindeutige SIP-Benutzernamen haben. Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Twinkle kann kein aktives Netzwerk-Interface finden, und nutzt nun 127.0.0.1 als lokale IP-Adresse. Wenn Sie später eine Netzwerkverbindung herstellen, müssen Sie Twinkle neu starten, damit es die korrekte Netzadresse finden und funktionieren kann. Line %1: incoming call for %2 Leitung %1: eingehender Ruf für %2 Call transferred by %1 Ruf weitervermittelt durch %1 Line %1: far end cancelled call. Leitung %1: Gegenstelle hat Ruf abgebrochen. Line %1: far end released call. Leitung %1: beendet durch Gegenstelle. Line %1: SDP answer from far end not supported. Leitung %1: SDP Antwort der GgSt. nicht unterstützt. Line %1: SDP answer from far end missing. Leitung %1: keine SDP Antwort der Gegenstelle. Line %1: Unsupported content type in answer from far end. Leitung %1: Inhaltstyp in Antwort der Ggst nicht unterstützt. Line %1: no ACK received, call will be terminated. Leitung %1: kein ACK von Ggst, Ruf wird beendet. Line %1: no PRACK received, call will be terminated. Leitung %1: kein PRACK von Ggst, Ruf wird beendet. Line %1: PRACK failed. Leitung %1: PRACK Fehler. Line %1: failed to cancel call. Leitung %1: Fehler bei Ruf beenden. Line %1: far end answered call. Leitung %1: Ggst hat angenommen. Line %1: call failed. Leitung %1: Ruf erfolglos. The call can be redirected to: Der Ruf kann umgeleitet werden nach: Line %1: call released. Leitung %1: Anruf beendet. Line %1: call established. Leitung %1: Verbindung hergestellt. Response on terminal capability request: %1 %2 Antwort GgSt auf Abfrage der Eigenschaften: %1 %2 Terminal capabilities of %1 Fähigkeiten Gegenstelle %1 Accepted body types: Erlaubte "body types": unknown unbekannt Accepted encodings: Erlaubte "encodings": Accepted languages: Erlaubte Sprachen: Allowed requests: Erlaubte "requests": Supported extensions: Unterstützte "extensions": none keine End point type: Endgeräte-Typ: Line %1: call retrieve failed. Leitung %1: Fehler bei "Gespräch fortsetzen". %1, registration failed: %2 %3 %1, Anmeldung erfolglos: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, Anmeldung erfolgreich (gültig %2 Sek.) %1, registration failed: STUN failure %1, Anmeldung erfolglos: STUN Fehler %1, de-registration succeeded: %2 %3 %1, Abmeldung erfolgreich: %2 %3 %1, fetching registrations failed: %2 %3 %1, Fehler bei Abfrage Anmeldungen: %2 %3 : you are not registered : Sie sind nicht angemeldet : you have the following registrations : folgende Anmeldungen aktiv : fetching registrations... : Abfrage Anmeldungen läuft... Line %1: redirecting request to Leitung %1: leite Anfrage um nach Redirecting request to: %1 Leite Anfrage um nach: %1 Line %1: DTMF detected: Leitung %1: DTMF empfangen: invalid DTMF telephone event (%1) Ungültiges DTMF-Ereignis (%1) Line %1: send DTMF %2 Leitung %1: sende DTMF %2 Line %1: far end does not support DTMF telephone events. Leitung %1: GgSt unterstützt keine DTMF-Ereignisse. Line %1: received notification. Leitung %1: Mitteilung empfangen. Event: %1 Ereignis: %1 State: %1 Status: %1 Reason: %1 Ursache: %1 Progress: %1 %2 Fortschritt: %1 %2 Line %1: call transfer failed. Leitung %1: Rufweitervermittlung erfolglos. Line %1: call succesfully transferred. Leitung %1: Ruf wurde weitervermittelt. Line %1: call transfer still in progress. Leitung %1: Rufweitervermittlung läuft... No further notifications will be received. Gegenstelle stoppt Mitteilungsversand. Line %1: transferring call to %2 Leitung %1: Rufweitervermittlung an %2 Transfer requested by %1 Rufweitervermittlung angefordert von %1 Line %1: Call transfer failed. Retrieving original call. Leitung %1: Rufweitervermittlung erfolglos. Ursprüngliches Gespräch wird fortgesetzt. Redirecting call Ruf wird umgeleitet User profile: Benutzerprofil: User: Benutzer: Do you allow the call to be redirected to the following destination? Möchten Sie Rufumleitung zu folgendem Ziel gestatten? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. In den Benutzerprofil-Einstellungen unter "SIP-Protokoll" können Sie festlegen, ob diese Frage angezeigt wird oder nicht. Redirecting request Leite Anfrage um Do you allow the %1 request to be redirected to the following destination? Möchten Sie die Umleitung der %1-Anforderung zu folgendem Ziel gestatten? Transferring call Ruf wird weitervermittelt Request to transfer call received from: Weitervermittlung angefordert durch: Do you allow the call to be transferred to the following destination? Möchten Sie Rufweitervermittlung zu folgendem Ziel gestatten? Info: Info: Warning: Warnung: Critical: Kritisch: Firewall / NAT discovery... Firewall / NAT Analyse... Abort Abbrechen Line %1 Leitung %1 Click the padlock to confirm a correct SAS. Klicken Sie auf das Vorhängeschloss, um korrektes SAS-Geheimwort zu bestätigen. The remote user on line %1 disabled the encryption. Die Gegenstelle an Leitung %1 hat Verschlüsselung abgeschaltet. Line %1: SAS confirmed. Leitung %1: SAS bestätigt. Line %1: SAS confirmation reset. Leitung %1: SAS Bestätigung gelöscht. Line %1: call rejected. Leitung %1: Ruf abgelehnt. Line %1: call redirected. Leitung %1: Ruf umgeleitet. Failed to start conference. Konferenz konnte nicht geschaltet werden. Override lock file and start anyway? Sperrdatei ignorieren und trotzdem starten? %1, STUN request failed: %2 %3 %1, STUN Anfrage fehlgeschlagen: %2 %3 %1, STUN request failed. %1, STUN Anfrage fehlgeschlagen. %1, voice mail status failure. %1, Fehler Voice-Mail Status. %1, voice mail status rejected. %1, Voice-Mail Status abgelehnt. %1, voice mailbox does not exist. %1, Voice-Mailbox existiert nicht. %1, voice mail status terminated. %1, keine weitere Voice-Mail Statusübermittlung. %1, de-registration failed: %2 %3 %1, Abmeldung erfolglos: %2 %3 Request to transfer call received. GgSt fordert Vermittlung an. If these are users for different domains, then enable the following option in your user profile (SIP protocol) Wenn diese Profile unterschiedliche Domains verwenden, bitte in einem unter SIP-Protololl folgende Option aktivieren Use domain name to create a unique contact header Domain-Name benutzen für eindeutigen Contact-Header Failed to create a %1 socket (SIP) on port %2 Fehler beim Anlegen: %1 socket (SIP) auf port %2 Accepted by network Akzeptiert durch Netzwerk Failed to save message attachment: %1 Fehler beim Speichern des Nachrichtenanhangs: "%1" Transferred by: %1 Cannot open web browser: %1 Configure your web browser in the system settings. GetAddressForm Twinkle - Select address Twinkle - Auswahl Adresse Name Name Type Typ Phone Telefon &Show only SIP addresses Nur &SIP-Adressen zeigen Alt+S Alt+S Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". Wenn aktiviert, werden nur Kontakte angezeigt, die eine gültige SIP-Adresse enthalten, also beginnend mit "<b>sip:</b>". &Reload Aktualisie&ren Alt+R Alt+R Reload the list of addresses from KAddressbook. Adressliste aus KAddressbook erneut einlesen.<br> Ein Schliessen und erneutes Öffnen des Fensters führt <i>nicht</i> zum Neueinlesen.<br> Änderungen im Adressbestand werden erst durch "Aktualisieren" in Twinkle sichtbar. &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Alt+C Alt+C &KAddressBook This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. Diese Adressliste stammt aus <b>KAddressbook</b> (bzw Kontact). Adressen/Kontakte, die keine Telefonnr oder SIP-Adresse enthalten, sind nicht aufgeführt. Nutzen Sie zum Anlegen und Bearbeiten Ihrer systemweiten Adressinformationen das Programm KAddressbook bzw Kontact. &Local address book &Lokales Adressbuch Remark Anmerkung Contacts in the local address book of Twinkle. Kontakte des lokalen Twinkle-Adressbuchs. &Add &Neu Alt+A Alt+N Add a new contact to the local address book. Neuen Kontakt im lokalen Adressbuch anlegen. &Delete &Löschen Alt+D Alt+L Delete a contact from the local address book. Ausgewählten Kontakt aus dem lokalen Adressbuch löschen. &Edit B&earbeiten Alt+E Alt+E Edit a contact from the local address book. Ausgewählten Kontakt im lokalen Adressbuch bearbeiten. <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> <p><b>KAddressbook</b> bzw <b>Kontact</b> scheint keine Einträge mit Telefonnr zu enthalten, die Twinkle dort auslesen könnte. Bitte nutzen Sie eines dieser Programme, um Ihre Adressdaten zu bearbeiten.</p> <p>Weiterhin steht Ihnen Twinkles lokales Adressbuch unabhängig von o.g. Programmen zur Verfügung.</p> GetProfileNameForm Twinkle - Profile name Twinkle - Name Benutzerprofil &OK &Cancel Abbruch (Es&c) Enter a name for your profile: Name für das neue Profil: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> Der <b>Name, unter dem das neue Profil angelegt</b> wird, in dem dann alle zusammengehörenden Daten wie Provider, SIP-Nutzername, Passwort usw gespeichert werden. (entsprechend z.B. einer "Identität" unter KMail)<br><br> Da Sie bei Twinkle mehrere Benutzerprofile anlegen können, z.B. um mehrere SIP-Provider zu nutzen, muss jedes Profil einen Namen erhalten. Unter diesem Namen finden Sie es später in Auswahllisten, Meldungen usw.<br> Es bietet sich an, hier Ihre SIP-Adresse als Name zu verwenden, also <b>meinname@meinprovider.de</b>, aber Sie können letztendlich beliebige Namen wählen.<br> <p> <b>Bevor Sie hier Ihr erstes SIP-Profil anlegen, sollten Sie sich bei einem SIP-Provider (vertraglich) angemeldet haben</b> und sich notieren, welche <b>SIP-Zugangsdaten</b> dieser für Sie zur Verfügung gestellt hat. </p> Cannot find .twinkle directory in your home directory. Kann den Ordner ".twinkle" in Ihrem home-Ordner ("/home/ihrname/") nicht finden. Profile already exists. Profil mit diesem Namen existiert bereits. Rename profile '%1' to: Profil "%1" umbenennen in: HistoryForm Twinkle - Call History Twinkle - Liste Anrufe Time Uhreit In/Out Ank/Abg From/To Gegenstelle Subject Betreff Status Status Call details Details Details of the selected call record. Details zum ausgewählten Anruf. View Anzeigen &Incoming calls E&ingehende Anrufe Alt+I Alt+I Check this option to show incoming calls. Wenn aktiviert, werden Anrufe angezeigt bei denen Sie von jemand angerufen wurden. &Outgoing calls Ab&gehende Anrufe Alt+O Alt+G Check this option to show outgoing calls. Wenn aktiviert, werden Anrufe angezeigt die Sie selbst getätigt haben. &Answered calls Be&antwortete Anrufe Alt+A Alt+A Check this option to show answered calls. Wenn aktiviert, werden Anrufe angezeigt die zustande kamen. &Missed calls A&nrufversuche Alt+M Alt+N Check this option to show missed calls. Wenn aktiviert, werden Anrufe angezeigt die nicht zustande kamen. Current &user profiles only N&ur aktive Benutzerprofile Alt+U Alt+U Check this option to show only calls associated with this user profile. Wenn aktiviert, nur Anrufe zeigen, die mit/zu einem der aktuell aktivierten Benutzerprofile getätigt wurden. C&lear &Liste löschen Alt+L Alt+L <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> Löscht das gesamte Anrufe-Protokoll,<br> <b>inklusive</b> aller evtl gerade über "Anzeigen" <b>ausgeblendeten Einträge.</b> Alt+C Alt+E Close this window. Fenster schliessen. Call start: Anruf Start: Call answer: Angenommen: Call end: Anruf Ende: Call duration: Anrufdauer: Direction: Richtung: From: Von: To: An: Reply to: Antwort auf: Referred by: Über: Subject: Betreff: Released by: Beendet von: Status: Status: Far end device: Typ Gegenstelle: User profile: Benutzerprofil: conversation Gespräch Call... Anrufen... (Doppelklick) Delete Eintrag löschen Re: Aw: Call selected address. Markierte Adresse/Nummer anrufen. Clo&se &Schliessen (Esc) Alt+S Alt+S &Call Anrufen (&Enter) Number of calls: ### Total call duration: InviteForm Twinkle - Call Twinkle - Anrufen &To: An (&Telnr): Optionally you can provide a subject here. This might be shown to the callee. Sie können hier einen Betreff angeben, der ebenso wie Ihr Displayname von der Gegenstelle angezeigt werden kann. Address book Adressbuch Select an address from the address book. Adresse/Nr aus dem KDE-Adressbuch auswählen. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Der Anschluss, den Sie anrufen möchten. Dies kann eine vollständige SIP-Adresse sein, wie <b>sip:example@example.com</b>, oder auch nur eine Telephonnummer bzw. der Benutzername einer SIP-Adresse, dann ergänzt Twinkle sie mit der im Benutzerprofil eingetragenen Domain zur vollständigen SIP-Adresse. The user that will make the call. Das Benutzerprofil -und damit der Provider- mit dem der Ruf gestartet wird. &Subject: &Betreff: &From: &Von: &OK &Cancel Abbruch (Es&c) &Hide identity Absenderangaben &unterdrücken Alt+H Alt+U <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> <p>Mit dieser Option weisen Sie Ihren SIP-Provider an, Ihre Absenderangaben (z.B. Telefonnr, SIP-Adresse) nicht an die Gegenstelle weiterzuleiten. Prinzipbedingt wird Ihre IP-Adresse <b>immer</b> der Gegenstelle mitgeteilt.</p> <p><b>Achtung: </b>Nicht alle Provider unterstützen diese Funktion!</p> Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. Nicht alle SIP-Provider unterstützen die Funktion "Absenderangaben unterdrücken". Bitte vergewissern Sie sich, bevor Sie sich auf diese Funktion verlassen. F10 LogViewForm Twinkle - Log Contents of the current log file (~/.twinkle/twinkle.log) Inhalt der aktuellen Logdatei (~/.twinkle/twinkle.log) &Close S&chliessen Alt+C Alt+C C&lear &Löschen Alt+L Alt+L Clear the log window. This does <b>not</b> clear the log file itself. Die Anzeige des Fensters löschen. Die Logdatei selbst wird <b>nicht</b> gelöscht oder geleert. MessageForm Twinkle - Instant message Twinkle - Instant Message &To: &An (Adr): The user that will send the message. Als Absender verwendetes Benutzerprofil. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Die Adresse/Nummer der Gegenstelle, an die Sie eine Instant Message senden möchten. Wie immer bei Twinkle kann dies eine vollständige Adresse oder ein Username sein. Wenn Sie nur den Usernamen angeben, ergänzt Twinkle die Domain aus dem verwendeten Absender-Benutzerprofil. Address book Adressbuch Select an address from the address book. Adresse/Nr aus dem KDE-Adressbuch auswählen. &User profile: Ben&utzerprofil: Conversation Dialog The exchanged messages. Die gesendeten und empfangenen Nachrichten. Gesendete schwarz, empfangene blau. Type your message here and then press "send" to send it. Schreiben Sie hier Ihre Nachricht und klicken Sie "senden" oder drücken Sie "Enter" zum abschicken. &Send &Senden Alt+S Alt+S Send the message. Nachricht senden. Delivery failure Übertragungsfehler Delivery notification Übertragungsbestätigung Instant message toolbar Instant Message Werkzeugleiste Send file... Sende Datei... Send file Sende Datei image size is scaled down in preview Bild in Vorschau verkleinert Open with %1... Öffnen mit %1... Open with... Öffnen mit... Save attachment as... Anhang speichern unter... File already exists. Do you want to overwrite this file? Datei dieses Namens existiert bereits! Löschen und durch neue Datei ersetzen? Failed to save attachment. Fehler beim Speichern des Anhangs. %1 is typing a message. %1 schreibt gerade eine Nachricht. F10 Size MessageFormView sending message Nachricht wird gesendet MphoneForm Twinkle &Call: Label in front of combobox to enter address &Nummer: The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Der Anschluss, den Sie anrufen möchten. Dies kann eine vollständige SIP-Adresse sein, wie <b>sip:example@example.com</b>, oder auch nur eine Telephonnummer bzw. der Benutzername einer SIP-Adresse, dann ergänzt Twinkle sie mit der im Benutzerprofil eingetragenen Domain zur vollständigen SIP-Adresse. The user that will make the call. Das Benutzerprofil -und damit der Provider- mit dem der Ruf gestartet wird. &User: &Profil: Dial Wählen Dial the address. Startet den Anruf . Address book Adressbuch Select an address from the address book. Rufnummer/SIP-Adresse aus Adressbuch wählen. Auto answer indication. Anzeige und Einstellen des Dienstes "Automatisch annehmen". Message waiting indication. Anzeige der Nachrichten auf Voice-Mailboxen; Anklicken zum Abhören der Nachrichten. Call redirect indication. Anzeige und Einstellen des Dienstes "Rufumleitung". Do not disturb indication. Anzeige und Einstellen des Dienstes "Bitte nicht stören". Missed call indication. Anzeige "Anrufe in Abwesenheit" und Öffnen der Anruferliste. Registration status. Anzeige und Abruf der Anmeldezustände. Die Ergebnisse des Abrufs werden in der Detailanzeige dargestellt. Display Detailanzeige Line status Leitungsstatus Line &1: Leitung &1: Alt+1 Alt+1 Click to switch to line 1. Anklicken (oder Alt+1), um auf Leitung 1 zu schalten. From: Von: To: An: Subject: Betreff: Visual indication of line state. Optische Anzeige des Leitungsstatus. idle No need to translate Call is on hold Anruf gehalten Voice is muted stummgeschaltet Conference call Konferenz Transferring call Ruf wird weitervermittelt <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> <p> Das Vorhängeschloss erscheint, wenn eine abhörsicher verschüsselte Verbindung zur Übertragung der Sprachdaten aufgebaut werden konnte. </p> <h3>SAS - Short Authentication String</h3> <p> Beide Teilnehmer eines verschlüsselten Gesprächs bekommen bei der ersten Kontaktaufnahme den SAS angezeigt, einen nicht fälschbaren eindeutigen "Fingerabdruck" der ausgehandelten Verschlüsselung. Durch Vergleich dieses SAS können Sie und Ihr Gesprächspartner sicherstellen, dass Sie tatsächlich <i>direkt</i> miteinander verbunden sind. Stichwort "man-in-the-middle attack" (MitM). </p> <p> Da ein Angreifer schlecht mitten im Gespräch die Stimme Ihres Gesprächspartners imitieren kann, reicht es völlig, beim ersten Telefonat den SAS vorzulesen. Bei Übereinstimmung klicken Sie auf das Vorhängeschloss, und Twinkle merkt sich die (den "Ausweis" der) Gegenstelle als "persönlich bekannt" und lässt sich bei zukünftigen Anrufen von/zu dieser GgSt nicht täuschen ("Ausweiskontrolle"). Das Schloss wird mit einem Häkchen dargestellt, und signalisiert so, dass die GgSt auf ihre Identität überprüft und eindeutig erkannt wurde, und also eine direkte Verbindung besteht. </p> <p>Klick auf ein Schloss <i>mit</i> Häkchen löscht die Vertrauensbeziehung und Sie können/müssen den SAS neu vergleichen</p> sas No need to translate Short authentication string SAS - Geheimwort (Short authentication string) g711a/g711a No need to translate Audio codec 0:00:00 Call duration Anrufdauer sip:from No need to translate sip:to No need to translate subject No need to translate photo No need to translate Line &2: Leitung &2: Alt+2 Alt+2 Click to switch to line 2. Anklicken (oder Alt+2), um auf Leitung 2 zu schalten. &File &Datei &Edit B&earbeiten C&all &Anruf Activate line Leitung auswählen &Registration A&nmeldung &Services Dien&ste &View Ans&icht &Help &Hilfe Call Toolbar Anruf Werkzeugleiste Quit Abmelden und Twinkle beenden &Quit B&eenden Ctrl+Q About Twinkle Über Twinkle &About Twinkle Ü&ber Twinkle Call someone Anrufen - erweiterte Nummerneingabe, Betreff... F5 Answer incoming call Anruf entgegennehmen - landläufig "Abheben" F6 Release call Anruf beenden Reject incoming call Eingehenden Ruf ablehnen F8 Put a call on hold, or retrieve a held call Ein Gespräch halten, oder ein gehaltenes fortsetzen Redirect incoming call without answering Eingehenden Ruf umleiten ohne Gesprächsannahme Open keypad to enter digits for voice menu's Öffnet eine Wähltastatur zur Eingabe von Tastenbefehlen - für Steuerung von zB. Anrufbeantwortern Register Anmelden beim SIP-Sever &Register An&melden Deregister Abmelden &Deregister Abmel&den Deregister this device Dieses Telefon abmelden Show registrations Anmeldungen bei den Servern abfragen &Show registrations Anmeldungen &zeigen Terminal capabilities Fähigkeiten Gegenstelle Request terminal capabilities from someone Abfrage der "terminal capabilities", der Eigenschaften einer Gegenstelle Do not disturb Bitte nicht stören &Do not disturb &Bitte nicht stören Call redirection Rufumleitung Call &redirection... &Rufumleitung... Repeat last call Wahlwiederholung, wählt letzten Ruf erneut F12 About Qt Über Qt About &Qt Über &Qt User profile Benutzerprofil bearbeiten &User profile... Ben&utzerprofil... Join two calls in a 3-way conference Leitung1, 2 und lokal zu einer 3er Konferenz zusammenschalten Mute a call Das Mikrofon für diese Leitung ab- oder wieder anschalten Transfer call Gespräch weitervermitteln System settings Systemeinstellungen bearbeiten &System settings... &Systemeinstellungen... Deregister all Abmelden alle Endg Deregister &all &Abmelden alle Endger. Deregister all your registered devices Abmelden aller Geräte unter dieser Benutzerkennung Auto answer Autom. Annehmen &Auto answer &Autom. Annehmen Log SystemLog anzeigen &Log... Call history Liste der letzen Anrufe anzeigen Call &history... Liste aller Anru&fe... F9 Change user ... Benutzerprofile ... &Change user ... &Benutzerprofile ... Activate or de-activate users Benutzerprofile de/aktivieren, bearbeiten usw. What's This? "Was ist das?"-Kontexthilfe What's &This? Was ist &das? Shift+F1 Shift+F1 Line 1 Leitung 1 Line 2 Leitung 2 idle frei dialing wählt attempting call, please wait versuche Rufaufbau, bitte warten incoming call ankommender Ruf establishing call, please wait Verbindungsaufbau, bitte warten established Verbindung hergestellt established (waiting for media) Verbindung hergestellt (warte auf Daten) releasing call, please wait trenne Verbindung, bitte warten unknown state unbekannter Status Voice is encrypted Sprachübertragung verschlüsselt Click to confirm SAS. SAS bestätigen. Click to clear SAS verification. SAS Bestätigung löschen. User: Benutzer: Call: Ruf: Registration status: Anmeldungsstatus: Registered angemeldet Failed fehlgeschlagen Not registered nicht angemeldet No users are registered. Kein Benutzer angemeldet. Do not disturb active for: "Bitte nicht stören" aktiviert für: Redirection active for: Rufumleitung aktiviert für: Auto answer active for: "Automatisch annehmen" aktiviert für: Do not disturb is not active. "Bitte nicht stören" nicht aktiviert. Redirection is not active. Rufumleitung nicht aktiviert. Auto answer is not active. "Automatisch annehmen" nicht aktiviert. You have no missed calls. Keine Anrufe in Abwesenheit. You missed 1 call. 1 Anruf in Abwesenheit. You missed %1 calls. %1 Anrufe in Abwesenheit. Click to see call history for details. Anklicken öffnet Anrufliste mit Details . Starting user profiles... Starte Benutzerprofile... The following profiles are both for user %1 Die folgenden Benutzerprofile verwenden die gleiche SIP-Adresse %1 You can only run multiple profiles for different users. Sie können nicht für einen SIP-Account gleichzeitig mehrere Profile aktivieren. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. Der SIP UDP port wurde geändert, dies wird erst beim nächsten Start von Twinkle wirksam. Esc Esc Transfer consultation Rückfrage Hide identity Absenderangaben unterdrücken Click to show registrations. Anklicken: Anmeldungen abfragen. %1 new, 1 old message %1 neue, 1 alte Mitteilung %1 new, %2 old messages %1 neue, %2 alte Mitteilungen 1 new message 1 neue Mitteilung %1 new messages %1 neue Mitteilungen 1 old message 1 alte Mitteilung %1 old messages %1 alte Mitteilungen Messages waiting Mitteilungen da No messages Keine Mitteilungen <b>Voice mail status:</b> <b>Voice-Mail Status:</b> Failure Fehler Unknown Unbekannt Click to access voice mail. Anklicken: Voice-Mail abrufen. Click to activate/deactivate Anklicken: (de/)aktivieren Click to activate Anklicken: aktivieren not provisioned nicht eingetragen You must provision your voice mail address in your user profile, before you can access it. Sie müssen die Adresse/Nr Ihres Anrufbeantworters im Profil eintragen, damit dies geht. The line is busy. Cannot access voice mail. Kann Voice-Mail nicht abrufen - Leitung belegt. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Die Voice-Mail-Adresse "%1" is ungültig. Bitte korregieren Sie die Einstellungen im Benutzerprofil. Call toolbar text Anruf+ &Call... call menu text Anruf+... (&Call) Answer toolbar text Ja? &Answer menu text &Annehmen Bye toolbar text Ende &Bye menu text Auflegen (&Bye) Reject toolbar text Nein! &Reject menu text Ab&weisen Hold toolbar text Halten &Hold menu text &Halten Redirect toolbar text Umleit R&edirect... menu text Uml&eiten... Dtmf toolbar text DTMF &Dtmf... menu text &DTMF... &Terminal capabilities... menu text &Fähigkeiten Gegenstelle... Redial toolbar text -> -> &Redial menu text Wahlwiederholun&g Conf toolbar text 3er-K. &Conference menu text Konferen&z Mute toolbar text Stumm &Mute menu text Stu&mm Xfer toolbar text Vmtlg Trans&fer... menu text Vermitte&ln... Voice mail Anrufbeantworter &Voice mail A&nrufbeantworter Access voice mail Voice-Mailbox abfragen F11 Buddy list Buddyliste &Message &Mitteilung Msg Msg Instant &message... Instant &Message... Instant message Instant Message senden &Call... Anrufen (&Call)... &Edit... B&earbeiten... &Delete &Löschen O&ffline O&ffline &Online &Online &Change availability Online-&Status ändern &Add buddy... Neuen Buddy &anlegen... Failed to save buddy list: %1 Fehler beim Speichern der Buddyliste: "%1" You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. Die Liste Ihrer <b>Benutzerprofile (fett)</b> und Buddies <i>(deutsch: "Kumpels". Ihre wichtigen Kontakte)</i> für die einzelnen Profile.<br> Über das Kontextmenü des einzelnen Benutzerprofils erzeugen Sie neue Buddy-Einträge und stellen Ihren eigenen Online-Status ein.<br> Der Online-Status der Buddies wird durch gelbe (=online) und graue (=offline) Icons dargestellt. Details erscheinen, wenn Sie den Cursor über das Icon stellen.<br> <br> Um Ihren eigenen Online-Status zu veröffentlichen, brauchen Sie die Unterstützung durch einen öffentlichen "presence server" <i>Ihres</i> Providers.<br> Um den Online-Status eines Buddies abzufragen, muss <i>dessen</i> Provider einen "presence server" im Netz ereichbar halten, und dieser muss Ihre Abfrage gestatten. Es ist daher sinnvoll, Buddies mit einem bestimmten Provider (thomas@<b>DerProvider.de</b>) unter einem gültigen eigenen Benutzerprofil mit dem selben Provider (ich.selber@<b>DerProvider.de</b>) anzulegen, da viele "presence server" nur dann die Abfrage gestatten. &Buddy list &Buddyliste &Display &Detailanzeige F10 Diamondcard Manual &Manual Sign up &Sign up... Recharge... Balance history... Call history... Admin center... Recharge Balance history Admin center NumberConversionForm Twinkle - Number conversion Twinkle - Umwandlung Rufnummer &Match expression: &Suchausdruck: &Replace: &Ersetzung: Perl style format string for the replacement number. Formatstring wie in Perl für die Ersetzung der Nummer. Perl style regular expression matching the number format you want to modify. Regulärer Ausdruck (Perl regex), der die zu ändernde Rufnummer beschreibt. &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Alt+C Alt+C Match expression may not be empty. Leerer Suchausdruck ist ungültig. Replace value may not be empty. Leerer Ersetzungsausdruck ist ungültig. Invalid regular expression. Ungültige regular expression. RedirectForm Twinkle - Redirect Twinkle - Rufumleitung Redirect incoming call to Ankommenden Ruf umleiten nach You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Es können bis zu 3 Ziele für die Rufumleitung angegeben werden. Wird der Ruf vom ersten Ziel nicht angenommen, werden das zweite und dann das dritte verwendet. &3rd choice destination: &3. Ziel: &2nd choice destination: &2. Ziel: &1st choice destination: &1. Ziel: Address book Adressbuch Select an address from the address book. Rufnummer/SIP-Adresse aus Adressbuch wählen. &OK &Cancel Abbruch (Es&c) F10 F12 F11 SelectNicForm Twinkle - Select NIC Twinkle - Netzwerkanschluss wählen Select the network interface/IP address that you want to use: Bitte wählen Sie den zu verwendenden Anschluss / IP-Adr.: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. Auf Ihrem Rechner sind mehrere IP-Adressen verfügbar. Bitte wählen Sie diejenige, unter der Ihr Rechner aus dem Internet bzw -wenn Sie einen Router verwenden- in ihrem lokalen Netz erreichbar ist. Diese IP-Adresse verwendet Twinkle dann in den SIP-Datenpaketen als Absenderangabe. Set as default &IP &IP-Adr. als Standard Alt+I Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Die ausgewählte IP-Adresse als default setzen. In Zukunft verwendet Twinkle beim Start automatisch diese Adresse. Set as default &NIC A&nschl. als Standard Alt+N Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. Den ausgewählten Netzwerkanschluss als default setzen. In Zukunft verwendet Twinkle beim Start automatisch diesen Anschluss. &OK Alt+O Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. Die Defaulteinstellungen für IP bzw. Anschluss lassen sich jederzeit in den Systemeinstellungen löschen oder ändern. SelectProfileForm Twinkle - Select user profile Twinkle - Auswahl Benutzerprofil Select user profile(s) to run: Wählen Sie die Benutzerprofile, die verwendet werden sollen: User profile Benutzerprofil Tick the check boxes of the user profiles that you want to run and press run. Markieren Sie die Benutzerprofile, mit denen Twinkle arbeiten soll und drücken Sie dann "Anwenden". &New &Neu Alt+N Alt+N Create a new profile with the profile editor. Anlegen eines neuen Benutzerprofils mit dem Profil-Editor. &Wizard Alt+W Alt+W Create a new profile with the wizard. Anlegen eines neuen Benutzerprofils mit dem Wizard. &Edit Änd&ern Alt+E Alt+E Edit the highlighted profile. Das ausgewählte Benutzerprofil bearbeiten. &Delete &Löschen Alt+D Alt+L Delete the highlighted profile. Das ausgewählte Benutzerprofil löschen. Ren&ame &Umbenennen Alt+A Alt+U Rename the highlighted profile. Das ausgewählte Benutzerprofil umbenennen. &Set as default Als &Standard Alt+S Alt+S Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. Die ausgewählten Profile als default verwenden. In Zukunft verwendet Twinkle beim Start automatisch diese Benutzerprofile. &Run &Anwenden Alt+R Alt+A Run Twinkle with the selected profiles. Twinkle startet die markierten Benutzerprofile. S&ystem settings S&ystemeinstellungen Alt+Y Alt+Y Edit the system settings. Systemeinstellungen bearbeiten. &Cancel Abbruch (Es&c) Alt+C Alt+C <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> <html>Bevor Sie Twinkle benutzen können, müssen Sie ein Benutzerprofil anlegen.<br>Klicken Sie OK um ein neues Profil anzulegen.</html> <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>Choose what method you wish to use.</html> <html>Sie können zum Erzeugen des Benutzerprofils den Profileditor verwenden. Dieser erlaubt detailierte Einstellungen für SIP-Protokoll, RTP sowie viele weitere Bereiche.<br><br>Oder Sie nutzen den Wizard, um schnell und einfach die wichtigsten Einstellungen für ein Benutzerprofil vorzunehmen. Der Wizard erfragt von Ihnen nur die absolut notwendigen Daten, die Sie von Ihrem SIP-Provider bei der Anmeldung mitgeteilt bekommen haben sollten. Für einige Provider werden Ihnen sogar viele dieser Daten vorgeschlagen. Wenn Sie den Wizard nutzen, können Sie später immer noch alle Details mit Hilfe des Editors nach Wunsch ändern und ergänzen.<br><br>Hilfe erhalten Sie überall in Twinkle entweder durch Drücken von "Umschalt + F1", über das Kontextmenü via rechten Mausknopf, oder durch Anklicken des "?" oben rechts am Fensterrand.<br><br>Bitte wählen Sie, wie Sie das Benutzerprofil anlegen wollen.</html> <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> <html>Als nächstes können und sollten Sie die Systemeinstellungen kontrollieren und anpassen. Insbesondere die Einstellung zu Mikrophon und Lautsprecher im Bereich Audio sollte zu der in Ihrem Rechner vorhandenen Hardware passen<br><br>Klicken Sie OK um in die Systemeinstellungen zu gelangen. Sie können auch später jederzeit alle Systemeinstellungen ändern</html> You did not select any user profile to run. Please select a profile. Sie haben kein Benutzerprofil zur Verwendung ausgewählt. Bitte wählen Sie mindestens ein Profil. Are you sure you want to delete profile '%1'? Benutzerprofil %1 wirklich löschen? Delete profile Benutzerprofil löschen Failed to delete profile. Fehler beim Löschen des Benutzerprofils. Failed to rename profile. Fehler beim Umbenennen des Benutzerprofils. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> <p>Die Defaulteinstellungen lassen sich jederzeit in den Systemeinstellungen löschen oder ändern. </p> Cannot find .twinkle directory in your home directory. Kann den Ordner ".twinkle" in Ihrem home-Ordner ("/home/ihrname/") nicht finden. &Profile editor &Profil-Editor Create profile Ed&itor Alt+I Alt+I Dia&mondcard Alt+M Modify profile Startup profile &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> SelectUserForm Twinkle - Select user Twinkle - Auswahl Benutzerprofile &Cancel Abbruch (Es&c) Alt+C Alt+C &Select all Alle au&swählen Alt+S Alt+S &OK Alt+O Alt+O C&lear all Alle abwäh&len Alt+L Alt+L purpose No need to translate User Benutzer Register Anmelden Select users that you want to register. Benutzerprofile zum Anmelden wählen. Deregister Abmelden Select users that you want to deregister. Benutzerprofile zum Abmelden wählen. Deregister all devices Abmelden aller Geräte Select users for which you want to deregister all devices. Benutzerprofile zum Abmelden (alle Geräte) wählen. Do not disturb Bitte nicht stören Select users for which you want to enable 'do not disturb'. Benutzerprofile wählen, für die der Dienst "Bitte nicht stören" aktiviert werden soll. Auto answer Autom. Annehmen Select users for which you want to enable 'auto answer'. Benutzerprofile wählen, für die der Dienst "Automatisch Annehmen" aktiviert werden soll. SendFileForm Twinkle - Send File Twinkle - Sende Datei Select file to send. Dateiauswahl für Senden. &File: &Datei: &Subject: &Betreff: &OK &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Alt+C Alt+C File does not exist. Datei existiert nicht. Send file... Sende Datei... SrvRedirectForm Twinkle - Call Redirection Twinkle - Rufumleitung User: Benutzer: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> Es gibt 3 Arten von Rufumleitung:<p> <b>Immer:</b> alle Anrufe umleiten </p> <p> <b>Besetzt:</b> Anruf umleiten, wenn beide Leitungen besetzt </p> <p> <b>Keine Antwort:</b> Anruf nach Ablauf der "keine-Antwort"-Zeit umleiten </p> &Unconditional &Immer &Redirect all calls &Alle Anrufe umleiten Alt+R Alt+A Activate the unconditional redirection service. Den Dienst "alle Anrufe umleiten" aktivieren. Redirect to Umleiten nach You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Es können bis zu 3 Ziele für die Rufumleitung angegeben werden. Wird der Ruf vom ersten Ziel nicht angenommen, werden das zweite und dann das dritte verwendet. &3rd choice destination: &3. Ziel: &2nd choice destination: &2. Ziel: &1st choice destination: &1. Ziel: Address book Adressbuch Select an address from the address book. Rufnummer/SIP-Adresse aus Adressbuch wählen. &Busy &Besetzt &Redirect calls when I am busy &Anrufe umleiten, wenn alle Leitungen besetzt Activate the redirection when busy service. Den Dienst "Umleiten, wenn besetzt" aktivieren. &No answer &keine Antwort &Redirect calls when I do not answer &Anrufe umleiten, wenn Benutzer nicht reagiert Activate the redirection on no answer service. Den Dienst "Umleiten, wenn keine Antwort" aktivieren. &OK Alt+O Alt+O Accept and save all changes. Änderungen speichern. &Cancel Abbruch (Es&c) Alt+C Alt+C Undo your changes and close the window. Änderungen verwerfen und Fenster schliessen. You have entered an invalid destination. Ungültige Zieladresse eingegeben. F10 F11 F12 SysSettingsForm Twinkle - System Settings Twinkle - Systemeinstellungen General Allgemein Audio Audio Ring tones Klingeltöne Address book Adressbuch Network Netzwerk Log Log Select a category for which you want to see or modify the settings. Bereich wählen, den Sie ändern wollen. Sound Card Audiogeräte Select the sound card for playing the ring tone for incoming calls. Audioanschluss wählen, über den der Klingelton abgespielt werden soll. Darf identisch mit Kopfhörer-Anschluss sein. Select the sound card to which your microphone is connected. Audioanschluss für Mikrofon wählen. Select the sound card for the speaker function during a call. Audioanschluss für Kopfhörer(/Lautsprecher) wählen. Darf identisch mit Anschluss für Klingelton sein. &Speaker: &Kopfhörer: &Ring tone: &Klingelton: Other device: Anderer Anschluss: &Microphone: &Mikrofon: When using ALSA, it is not recommended to use the default device for the microphone as it gives poor sound quality. Wenn Ihr Gesprächspartner schlechte Tonqualität beklagt, versuchen Sie für ALSA ein anderes Gerät statt "default". Reduce &noise from the microphone Spezielle Störgeräusch-U&nterdrückung für manche defekte Gateways Alt+N Alt+N Recordings from the microphone can contain noise. This could be annoying to the person on the other side of your call. This option removes soft noise coming from the microphone. The noise reduction algorithm is very simplistic. Sound is captured as 16 bits signed linear PCM samples. All samples between -50 and 50 are truncated to 0. Diese Option setzt alle Tonsamples mit -50 < Messwert < 50 auf 0. Michel hat diesen Hack entwickelt, als er mit fehlerhaften A/D-Wandlern in einigen Provider-Gateways konfrontiert war. Im Normalfall führt das Aktivieren eher zu einer kaum bemerkbaren Verschlechterung der Tonqualität. Advanced Spezielle Einstellungen OSS &fragment size: OSS &Fragmentgrösse: 16 32 64 128 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. Die play period size bestimmt vereinfacht gesagt die Grösse der Pakete, in denen die Soundkarte die Daten geliefert bekommt. Viele kleine Pakete belasten den Prozessor mehr, aber der Verlust eines Pakets stört dann weniger. Bei Problemen mit Aussetzern oder Rattern im Ton sollten Sie hier mit anderen Werten ein wenig experimentieren. ALSA &play period size: ALSA &play (LS) period size: &ALSA capture period size: &ALSA capture (MIC) period size: The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. Die OSS period size bestimmt vereinfacht gesagt die Grösse der Pakete, in denen die Soundkarte die Daten geliefert bekommt/liefert. Viele kleine Pakete belasten den Prozessor mehr, aber der Verlust eines Pakets stört dann weniger. Bei Problemen mit Aussetzern oder Rattern im Ton sollten Sie hier mit anderen Werten ein wenig experimentieren. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. Die capture period size bestimmt vereinfacht gesagt die Grösse der Pakete, in denen die Soundkarte die Daten des Mikrofons liefert. Viele kleine Pakete belasten den Prozessor mehr, aber der Verlust eines Pakets stört dann weniger. Bei Klagen der Gegenstelle über Aussetzer oder Rattern im Ton sollten Sie hier mit anderen Werten ein wenig experimentieren. &Max log size: &Max. Grösse System-Log: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. Das SystemLog wird nur von Experten zur Fehlersuche benötigt. Dieser Wert legt die maximale Grösse fest, die die Logbuch-Datei annehmen kann. Bei Erreichen dieser Grösse wird sie von twinkle.log in twinkle.log.old umbenannt, wobei eine schon existierende ältere Datei gleichen Namens gelöscht wird. Das Log wird in eine neue leere Datei twinkle.log fortgesetzt. Im Normalfall reicht hier 1MB völlig aus. MB Log &debug reports &Debug-Meldungen loggen Alt+D Alt+D Indicates if reports marked as "debug" will be logged. Aktiviert das Loggen von "debug"-Ausgaben. Log &SIP reports &SIP-Meldungen loggen Alt+S Alt+S Indicates if SIP messages will be logged. Aktiviert das Loggen von Ausgaben für SIP-Ereignisse. Log S&TUN reports S&TUN-Meldungen loggen Alt+T Alt+T Indicates if STUN messages will be logged. Aktiviert das Loggen von Ausgaben für STUN-Ereignisse. Log m&emory reports Sp&eicher-Meldungen loggen Alt+E Alt+E Indicates if reports concerning memory management will be logged. Aktiviert das Loggen von RAM-Anforderungs/Freigabe Protokollen. System tray Systemabschnitt Create &system tray icon on startup Bei &Start Icon in Systemabschnitt erzeugen Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. Mit dieser Option erzeugt Twinkle beim Start ein Twinkle-Sternchen im Systemabschnitt , über das Sie jederzeit auf Twinkle zugreifen können und eingehende Rufe gemeldet bekommen. &Hide in system tray when closing main window Bei "Fenster sc&hliessen" in Systemabschnitt minimieren Alt+H Alt+H Enable this option if you want Twinkle to hide in the system tray when you close the main window. Wenn aktiviert, wird Twinkle durch Schliessen des Hauptfensters nicht beendet, sondern erzeugt das Sternchen im Systemabschnitt. Zum Beenden müssen Sie dann "Beenden" im Menü "Datei" oder im Kontextmenü des Sternchens wählen. Startup Programmstart Next time you start Twinkle, this IP address will be automatically selected. This is only useful when your computer has multiple and static IP addresses. Eine hier eingetragene IP-Adresse wird beim Start des Programms automatisch verwendet. Nur sinnvoll, wenn Ihr Rechner mehrere Netzwerkanschlüsse und für den Internetzugang eine unveränderliche IP-Adresse hat. Default &IP address: Default &IP-Addresse: Next time you start Twinkle, the IP address of this network interface be automatically selected. This is only useful when your computer has multiple network devices. Wenn Ihr Rechner mehrere Netzwerkanschlüsse hat, können Sie hier festlegen, welchen davon Twinkle beim Start verwenden soll. Sie werden dann nicht beim Start nach dem zu verwendenden Anschluss gefragt. Default &network interface: Default &Netzwerkanschluss: S&tartup hidden in system tray Minimiert im Sys&temabschnitt starten Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. Twinkle öffnet beim Start kein Fenster, sondern startet minimiert im Systemabschnitt - also in Form des Sternchens. Dafür sollten Sie auch ein Default-Benutzerprofil einstellen, sonst erscheint doch ein Auswahlfenster beim Start. Default user profiles Default Benutzerprofile If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. Die hier eingestellten Benutzerprofile werden beim Programmstart automatisch aktiviert. Sie können trotzdem jederzeit über "Datei" "Benutzerprofile..." Profile aktivieren/deaktivieren. Services Dienste Call &waiting &Anklopfen Alt+W Alt+A With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. Wenn "Anklopfen" aktiviert ist, kann bei einer belegten Leitung über die zweite ein weiterer Anrufer klingeln. Wenn deaktiviert, bekommt er "besetzt". Hang up &both lines when ending a 3-way conference call. Bei Beenden 3er-Konferenz &beide Leitungen auflegen. Alt+B Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. Wenn aktiviert, werden durch "Auflegen" beide Verbindungen getrennt. Sonst trennt "Auflegen" nur die aktive Leitung, das Gespräch auf der anderen Leitung kann weitergeführt werden. &Maximum calls in call history: &max. Anzahl Einträge in Anrufliste: The maximum number of calls that will be kept in the call history. Die Länge der Anrufliste wird auf die hier angegebene Anzahl Einträge begrenzt. Ältere Eintäge werden automatisch entfernt. &Auto show main window on incoming call after Bei &Anruf Hauptfenster öffnen nach Alt+A Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Wenn das Twinkle-Hauptfenster geschlossen oder minimiert ist, wird es bei eingehendem Ruf nach der angegebenen Sekundenzahl automatisch wiederhergestellt. Number of seconds after which the main window should be shown. Zeit in Sekunden, nach der das Fenster wiederhergestellt wird. secs Sekunden The UDP port used for sending and receiving SIP messages. Der UDP Port, über den das SIP-Protokoll läuft. Standard:5060, ihr Provider kann aber einen anderen Port vorschreiben. &RTP port: &RTP-Port: The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. Der erste UDP Port, über den das RTP-Protokoll zur Sprachdatenübertragung läuft. Ein zeitgleich geführtes 2. Gespräch nutzt einen um 2 höheren Port. Rufvermittlung weitere 2. Also beispielsweise: 1.Ltg:8000(+8001), 2.Ltg:8002(+8003), Vermitteln:8004(+8005). Standard: abhängig vom Provider meist 8000 oder 5004. Bei mehreren an einem Anschluss betriebenen SIP-fons braucht jedes seinen eigenen Bereich Ports! Also das 2. Twinkle z.B. dann 8006. &SIP UDP port: &SIP UDP Port: Ring tone Klingelton &Play ring tone on incoming call Bei eingeh. Ruf Klingelton s&pielen Alt+P Alt+P Indicates if a ring tone should be played when a call comes in. Wenn aktiviert, spielt Twinkle bei eingehenden Anrufen einen Klingelton über den dafür eingestellten Audioanschluss ab. &Default ring tone &Default Klingelton Play the default ring tone when a call comes in. Spielt den Standard-Klingelton, wenn Anruf ankommt. C&ustom ring tone individueller &Ton Alt+U Alt+T Play a custom ring tone when a call comes in. Selbst ausgewählten Klingelton abspielen bei eingehendem Anruf. Specify the file name of a .wav file that you want to be played as ring tone. Geben Sie hier den Namen der .wav-Datei für Ihren individuellen Klingelton an. Ring back tone Freizeichen P&lay ring back tone when network does not play ring back tone Freizeichen (Rufton) abspie&len, wenn Tel-netz keinen liefert Alt+L Alt+L <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> <p>Freizeichen abspielen, wenn die Telefongesellschaft nicht selber eines einspielt. </p> <p>Das Freizeichen ist in D das "tuuut tuuut"", welches dem Anrufer das Klingeln beim Gerufenen anzeigt. </p> <p>Twinkle spielt dann den eigenen "call back tone" ab, falls nicht eine der beteiligten Vermittlungsstellen selber einen entsprechenden Signalton oder eine Ansage liefert.</p> D&efault ring back tone D&efault Freizeichen Play the default ring back tone. Den Standard-Signalton für Rückmeldung des Klingelns bein Angerufenen (=Freizeichen) verwenden. Cu&stom ring back tone Individuelle&s Freizeichen Play a custom ring back tone. Individuellen Signalton für Rückmeldung des Klingelns bein Angerufenen (=Freizeichen) verwenden. Specify the file name of a .wav file that you want to be played as ring back tone. Geben Sie hier den Namen der .wav-Datei für Ihr individuelles Freizeichen an. &Lookup name for incoming call Zu Nummer der Gegenstelle Name ermitte&ln Ove&rride received display name Gemeldeten An&rufernamen ersetzen Alt+R Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. Die Gegenstelle kann selber einen Namen (displayname) mitschicken. Aktivieren sie diese Option, wenn Sie lieber den aus der Nummer/Adresse ermittelten Eintrag aus Ihrem Adressbuch angezeigt bekommen möchten. Lookup &photo for incoming call Nach &Foto für Gegenstelle suchen Lookup the photo of a caller in your address book and display it on an incoming call. Wenn aufgrund der Nummer/Adresse der Gegenstelle ein Datensatz in Ihrem Adressbuch gefunden wird, zeigt Twinkle ein dort gegebenenfalls hinterlegtes Foto an. &OK Alt+O Alt+O Accept and save your changes. Änderungen übernehmen und speichern. &Cancel Abbruch (Es&c) Alt+C Alt+C Undo all your changes and close the window. Fenster schliessen ohne Änderungen zu übernehmen. none This is the 'none' in default IP address combo auto none This is the 'none' in default network interface combo auto Either choose a default IP address or a default network interface. Sie dürfen nur entweder einen Default-Anschluss oder eine Default-IP-Adresse angeben. Ring tones Description of .wav files in file dialog Klingeltöne Choose ring tone Auswahl Klingelton Ring back tones Description of .wav files in file dialog Signaltöne Choose ring back tone Auswahl Freizeichen &Validate devices before usage Audioeinstellungen prüfen &vor Benutzung Alt+V Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. <p>Wenn aktiviert, prüft Twinkle die eingestellten Audiodevices, um zu verhindern dass eine Verbindung ohne entsprechende Ton-Ein/Ausgabe aufgebaut wird.</p> <p>Bein Programmstart warnt Twinkle, falls eines der Audiodevices nicht verfügbar ist.<br> Bei Anrufen werden Mikrofon- und Lautsprecherdevice geprüft.</p> <p>Versuche, einen abgehenden Ruf zu tätigen, werden bei gefundenen Audio-Problemen abgebrochen,<br> eingehende Rufe werden nicht entgegengenommen. <br> Stattdessen zeigt Twinkle in beiden Fällen eine Warnung.</p> On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. Twinkle versucht, einen zur Nummer/Adresse der Gegenstelle passenden Eintrag im Adressbuch zu finden. Die Details dieses Eintrags werden dann angezeigt. Select ring tone file. Dateiauswahl Klingelton. Select ring back tone file. Dateiauswahl Freizeichen. Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. Max. zulässige Größe in Byte (0-65535) für ankommende SIP-Nachrichten über UDP. &SIP port: &SIP port: Max. SIP message size (&TCP): Max. SIP-Nachrichtengröße (&TCP): The UDP/TCP port used for sending and receiving SIP messages. Die Portnummer, über die SIP-Nachrichten sowohl per UDP als auch TCP gesendet und empfangen werden. Max. SIP message size (&UDP): Max. SIP-Nachrichtengröße (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. Max. zulässige Größe in Byte (0-4294967295) für ankommende SIP-Nachrichten über TCP. W&eb browser command: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. SysTrayPopup Answer Annehmen Reject Abweisen Incoming Call TermCapForm Twinkle - Terminal Capabilities Twinkle - Fähigkeiten Gegenstelle &From: &Von: Get terminal capabilities of Fähigkeiten folgender Gegenstelle abfragen &To: &Adr: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Die Adresse/Nummer der Gegenstelle, deren Fähigkeiten Sie erfragen möchten (OPTION request). Wie immer bei Twinkle kann dies eine vollständige Adresse oder ein Username sein. Address book Adressbuch Select an address from the address book. Rufnummer/SIP-Adresse aus Adressbuch wählen. &OK &Cancel Abbruch (Es&c) F10 TransferForm Twinkle - Transfer Twinkle - Vermitteln Transfer call to Ruf weitervermitteln an &To: &Adr: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Die Adresse/Nummer der Gegenstelle, an die Sie weitervermitteln möchten. Wie immer bei Twinkle kann dies eine vollständige Adresse oder ein Username sein. Address book Adressbuch Select an address from the address book. Rufnummer/SIP-Adresse aus Adressbuch wählen. &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Type of transfer Art der Vermittlung &Blind transfer &Ohne Rücksprache Alt+B Alt+O Transfer the call to a third party without contacting that third party yourself. Das Gespräch wird an den dritten, neuen Teilnehmer umgelenkt, ohne dass Sie vorher mit diesem Rücksprache halten. D.h. wenn der neue Teilnehmer abhebt, ist er sofort mit Ihrem bisherigen Gesprächspartner verbunden. T&ransfer with consultation Mit &Rücksprache Alt+R Alt+R Before transferring the call to a third party, first consult the party yourself. Sie können mit dem neuen Teilnehmer sprechen und den vermittelten Gesprächspartner ankündigen. Nach Ende dieser Rücksprache wird Ihr bisheriger Gesprächspartner mit der neuen Gegenstelle verbunden. Transfer to other &line Vermitteln an andere &Leitung Alt+L Alt+L Connect the remote party on the active line with the remote party on the other line. Die beiden GgSt an Leitung 1 und 2 zueinander vermitteln. Hierbei ist die GgSt der gerade aktiven Ltg die vermittelte, also den Ruf aufbauende. F10 TwinkleCore Failed to create log file %1 . Fehler beim Anlegen der Logdatei "%1". Cannot open file for reading: %1 Kann Datei "%1" nicht zum Lesen öffnen File system error while reading file %1 . Dateisystem-Fehler beim Lesen aus "%1". Cannot open file for writing: %1 Kann Datei "%1" nicht zum Schreiben öffnen File system error while writing file %1 . Dateisystem-Fehler beim Schreiben in "%1". Excessive number of socket errors. Zu hohe Anzahl von socket-Fehlern. Built with support for: Erstellt mit Unterstützung für: Contributions: Beiträge: This software contains the following software from 3rd parties: Diese Software enthält folgende Teile Dritter: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * G.711/G.726 codecs from Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ For RTP the following dynamic libraries are linked: Translated to english by <your name> Deutsche Übersetzung: ©left 20080810-0830 Reisenweber tech+it-consult<br> joerg.twinklephone(AT)gmx.de Directory %1 does not exist. Ordner "%1" nicht gefunden. Cannot open file %1 . Datei "%1" nicht zugreifbar. (nicht vorhanden / schreibgeschützt?). %1 is not set to your home directory. "%1" zeigt nicht auf Ihren home-Ordner. Directory %1 (%2) does not exist. Ordner "%1" (%2) existiert nicht. Cannot create directory %1 . Ordner "%1" kann nicht erstellt werden. Lock file %1 already exist, but cannot be opened. Sperrdatei "%1" existiert schon, kann aber nicht geöffnet werden. %1 is already running. Lock file %2 already exists. "%1" ist offenbar schon gestartet. Sperrdatei "%2" existiert schon. Cannot create %1 . "%1" kann nicht angelegt werden. Cannot write to %1 . Kann in "%1" nicht schreiben. Syntax error in file %1 . Syntaktische Struktur in Datei "%1" fehlerhaft. Failed to backup %1 to %2 Fehler beim Backup von "%1" nach "%2" unknown name (device is busy) Gerät unbekannt oder schon belegt Default device Standard Anschluss Anonymous Anonym Warning: Warnung: Call transfer - %1 Vermittlung - %1 Sound card cannot be set to full duplex. Audiodevice kann nicht auf "voll duplex" eingestellt werden. Cannot set buffer size on sound card. Puffergrösse f. Audiodevice kann nicht eingestellt werden. Sound card cannot be set to %1 channels. Audiodevice kann nicht auf %1 Kanäle eingestellt werden. Cannot set sound card to 16 bits recording. Audiodevice kann nicht auf 16Bit-Aufnahme eingestellt werden. Cannot set sound card to 16 bits playing. Audiodevice kann nicht auf 16Bit-Wiedergabe eingestellt werden. Cannot set sound card sample rate to %1 Audio Samplerate kann nicht auf %1 eingestellt werden. Opening ALSA driver failed Fehler beim Öffnen des ALSA-Treibers Cannot open ALSA driver for PCM playback ALSA-Treiber kann nicht f. PCM-Wiederg. geöffnet werden. Cannot resolve STUN server: %1 Kann URL d. STUN-Servers nicht auflösen: %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. Sie befinden sich hinter einer "symetric NAT". STUN kann hier nicht funktionieren. Sie müssen in Twinkles Benutzerprofil/NAT eine "fest voreingestellte Adresse" einstellen. In Ihrem Router/Firewall/NAT leiten Sie bitte folgende öffentliche Ports auf lokale Ports zum Twinkle-PC weiter: public IP: %1 --> private IP: %2 (SIP signaling) IP öffentl.: %1 --> IP lokal: %2 (SIP Protokoll) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) IP öff.: %1 - %2 --> IP lok.: %3 - %4 (RTP/RTCP) Cannot reach the STUN server: %1 Kann STUN-Server "%1" nicht erreichen. Port %1 (SIP signaling) Port %1 (SIP Protokoll) NAT type discovery via STUN failed. NAT Analyse mittels STUN fehlgeschlagen. If you are behind a firewall then you need to open the following UDP ports. Wenn Sie sich hinter einer Firewall befinden, müssen Sie folgende Ports öffnen: Ports %1-%2 (RTP/RTCP) Ports %1-%2 (RTP/RTCP) Cannot access the ring tone device (%1). "%1", Audiodevice f. Klingelton nicht zugreifbar. Cannot access the speaker (%1). "%1", Audiodevice f. Lautsprecher nicht zugreifbar. Cannot access the microphone (%1). "%1", Audiodevice f. Mikrofon nicht zugreifbar. Cannot open ALSA driver for PCM capture ALSA-Treiber kann nicht für PCM-Aufnahme geöffnet werden Cannot receive incoming TCP connections. Kann eingehende TCP-Verbindungen nicht annehmen. Failed to create file %1 Fehler beim Anlegen der Datei "%1" Failed to write data to file %1 Fehler beim Schreiben in Datei "%1" Failed to send message. Fehler beim Senden der Nachricht. Cannot lock %1 . UserProfileForm Twinkle - User Profile Twinkle - Benutzerprofil User profile: Benutzerprofil: Select which profile you want to edit. Zu bearbeitendes Benutzerprofil wählen. User Benutzer SIP server SIP Server RTP audio RTP Audio SIP protocol SIP-Protokoll Address format Adress-Format Timers Zeitgeber Ring tones Signaltöne Scripts Security Sicherheit Select a category for which you want to see or modify the settings. Bereich wählen, den Sie ändern wollen. &OK Alt+O Alt+O Accept and save your changes. Änderungen übernehmen und speichern. &Cancel Abbruch (Es&c) Alt+C Alt+C Undo all your changes and close the window. Fenster schliessen ohne Änderungen zu übernehmen. SIP account SIP-Provider Benutzerdaten &User name*: N&utzername *: &Domain*: Or&ganization: Or&ganisation: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. Der Nutzername, den Sie von Ihrem Provider zugewiesen bekommen haben. Dieser ist der erste Teil ihrer vollständigen SIP-Adresse <b>nutzername</b>@domain.com . Viele Provider bezeichnen diesen -eigentlich falsch- als Telefonnummer. <br><br> *DATEN FÜR DIESES FELD SIND ZWINGEND NOTWENDIG. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Die Domain oder IP-Adresse, unter der Sie von Ihrem Provider geführt werden bzw. im Internet erreichbar sind. Dies ist der zweite Teil ihrer vollständigen SIP-Adresse nutzername@<b>domain.com</b>, bzw. die Domain Ihres SIP-Proxys. Bei vielen Providern identisch mit der Domain des Providers. Für direct-IP-to-IP (siehe Handbuch) ist hier die Adresse (DynDNS oder IP) einzutragen, unter der <b>Ihr Rechner</b> zu erreichen ist. <br><br> *DATEN FÜR DIESES FELD SIND ZWINGEND NOTWENDIG. You may fill in the name of your organization. When you make a call, this might be shown to the called party. In deutsch etwa Firma. Dieses Feld wird nur als Teil der Absenderangaben zur angerufenen/rufenden Gegenstelle übertragen und dort evtl angezeigt. Beliebige Angabe, nicht zwingend erforderlich. Vermeiden Sie moeglichst Umlaute und Sonderzeichen, manche Gegenstellen haben damit Probleme. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Ihr Absendername oder Pseudonym. Dieses Feld wird nur als Teil der Absenderangaben (display name) zur angerufenen/rufenden Gegernstelle übertragen und dort evtl angezeigt. Beliebige Angabe, nicht zwingend erforderlich. Vermeiden Sie moeglichst Umlaute und Sonderzeichen, manche Gegenstellen haben damit Probleme. &Your name: &Absender: SIP authentication SIP-Anmeldedaten &Realm: Authentication &name: Anmelde&name: &Password: &Passwort: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. Der "Realm"-Wert (deutsch etwa: Bereich) zur Anmeldung. Wird Ihnen, falls notwendig, gegebenfalls von Ihrem SIP-Provider mitgeteilt. Wenn leer, verwendet Twinkle SIP-Anmeldename und Passwort bei jeder Realm-Anfrage. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ihr SIP-Anmeldename. Häufig identisch mit Ihrem SIP-Nutzernamen, dann leerlassen. Falls nicht, wird Ihr Provider dies mitteilen. Your password for authentication. Ihr SIP-Anmeldepasswort. Wenn Sie dieses Feld leerlassen, müssen Sie das Passwort bei jeder Anmeldung in den dann erscheinenden Requester eintragen (hilfreich zum anfänglichen Testen!). Registrar Registrar (Anmelde-Server) &Registrar: &Registrar: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. Die Domain, IP oder Hostname Ihres SIP-Anmelde-Servers. Für die meisten SIP-Provider einfach leer lassen. Wenn unten ein Outbound-Proxy eingetragen ist, wird dieser bei leerem Feld auch hier verwendet. Ohne Outbound-Proxy gilt für beides die Benutzer-SIP-Domain. &Expiry: &haltbar: The registration expiry time that Twinkle will request. Die Gültigkeitsdauer in Sekunden, die Twinkle bei der Anmeldung anfordert. Nach dieser Zeit meldet sich Twinkle automatisch neu an. Unterbleibt dies, bemerkt der Provider nach dieser Zeit, dass Sie offline sind. Auch Änderungen Ihrer IP -z.B. durch Zwangstrennung- werden u.U. erst nach dieser Zeit berücksichtigt. Werte kleiner 120 sind nicht zu empfehlen. Standard: 3600 (=1h). seconds Sekunden Re&gister at startup Bei &Profilstart anmelden Alt+G Alt+P Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Wenn aktiviert, versucht Twinkle, dieses Benutzerprofil bei seiner Aktivierung automatisch beim Provider (genauer SIP-Anmelde-Server / Registrar) anzumelden. Für direct-IP-to-IP gibt es keinen Provider, also dann nicht aktivieren. Outbound Proxy &Use outbound proxy Outbound-Proxy ben&utzen Alt+U Alt+U Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Wenn aktiviert, verwendet Twinkle einen Outbound-Proxy (deutsch etwa: Stellvertreter/Vermittlung für abgehende Rufe), an den alle SIP-Anfragen gesendet werden. Dies kann z.B. ein SIP-Gateway ihres Firmen-LAN sein. Ohne Outbound-Proxy (Normalfall) versucht Twinkle selbst, die zu rufende Adresse zu einer IP aufzulösen, und sendet die SIP-Anfrage für den Anruf direkt dorthin. Outbound &proxy: Outbound-&Proxy: &Send in-dialog requests to proxy In-Dialog-Anfragen an Proxy &senden Alt+S Alt+S SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. Wenn aktiviert, SIP-Anfragen <b>immer</b> an den Outbound-Proxy senden. Twinkle sendet normalerweise SIP-Anfragen während eines laufenden SIP-Dialogs (d.h. während eines Gesprächs) an die Adresse im zu Gesprächsbeginn erhaltenen Contact-Header, also direkt an die Gegenstelle. &Don't send a request to proxy if its destination can be resolved locally. SIP-Anfragen mit lokal auflösbarer A&dresse nicht an Proxy, sondern direkt senden. Alt+D Alt+D When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) Wenn aktiviert, versucht Twinkle zunächst selbst, die Zieladresse zu einer gültigen IP-Adresse aufzulösen und die SIP-Anfrage direkt dorthin zu schicken. Gelingt die Adressauflösung nicht, wird die Anfrage trotzdem an den Proxy geschickt, wie bei nicht aktivierter Option (Beachten Sie: In-Dialog-Anfragen werden in diesem Fall nur an den Proxy gesendet, wenn auch die vorherige Option aktiviert ist) The hostname, domain name or IP address of your outbound proxy. Der Domainname, IP-Adresse oder Hostname Ihres Outbound-Proxy. Co&decs Codecs Available codecs: Verfügbare Codecs: G.711 A-law G.711 u-law GSM speex-nb (8 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) List of available codecs. Liste der verfügbaren, nicht aktivierten Codecs. Abhängig von den Compile-options können manche Codecs nicht verfügbar sein. Move a codec from the list of available codecs to the list of active codecs. Codec aktivieren. Move a codec from the list of active codecs to the list of available codecs. Codec deaktivieren. Active codecs: Aktive Codecs: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. Liste der aktiven Codecs. Diese werden beim Gesprächsaufbau der Gegenstelle zur Benutzung angeboten bzw. akzeptiert. Es wird bevorzugt der am weitesten oben in der Liste stehende Codec genutzt, auf den sich die beiden Endgeräte einigen können. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. Codec in der Liste nach oben verschieben, d.h. höheren Vorrang für Benutzung einräumen. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. Codec in der Liste nach unten verschieben, d.h. niedrigeren Vorrang für Benutzung einräumen. &G.711/G.726 payload size: &G.711/G.726 Nutzdatengrösse: The preferred payload size for the G.711 and G.726 codecs. Die bevorzugte Grösse der Nutzdaten pro RTP-Paket für G.711 and G.726 Codecs. ms &iLBC iLBC i&LBC payload type: i&LBC Nutzdaten-Typ: iLBC &payload size (ms): iLBC &Nutzdatengrösse: The dynamic type value (96 or higher) to be used for iLBC. Die für iLBC verwendete dynamische Nutzdatentypkennung (nicht kleiner 96). 20 30 The preferred payload size for iLBC. Die bevorzugte Grösse der Nutzdaten pro RTP-Paket für iLBC. &Speex Speex Perceptual &enhancement Tonqualität v&erbessern Alt+E Alt+E Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). "Tonqualität verbessern" (engl: perceptual enhancement) ist eine Sammlung von Funktionen des Codecs, die den Ton unter Beachtung der Eigenschaften des menschlichen Hörens so bearbeiten, dass weniger Störgeräusche wahrgenommen werden. Obwohl sich die Übertragung bei Anwendung dieser Funktionen unter messtechnischen Gesichtspunkten (S/N Rauschabstand) verschlechtert und weniger dem Original gleicht, ist letztendlich doch die empfundene Tonqualität besser. &Ultra wide band payload type: &Ultra wide band Nutzdaten-Typ: Alt+V Alt+V When enabled, voice activity detection detects whether the audio being encoded is speech or silence/background noise. VAD is always implicitly activated when encoding in VBR, so the option is only useful in non-VBR operation. In this case, Speex detects non-speech periods and encode them with just enough bits to reproduce the background noise. This is called "comfort noise generation" (CNG). Wenn aktiviert, prüft VAD (Voice Activity Detection, deutsch etwa: Sprache/Pause-Erkennung), ob gerade gesprochen wird. Nicht als Sprache erkannte Geräusche werden nicht übertragen, sondern es wird stattdessen ein wesentlich weniger Daten-Bandbreite benötigendes "Pausesignal" oder (siehe DTX) gar nichts gesendet. VBR (siehe dort) macht VAD unnötig. &Wide band payload type: &wide band Nutzdaten-Kennung: Alt+B Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. Variable Bit-Rate (VBR) erlaubt es dem Codec, die Menge der übertragenen Daten entsprechend der Komplexität des Audiosignals anzupassen. Zischlaute wie "s", "f" z.B. und besonders Sprechpausen (siehe VAD) können mit wenigen Daten qualitativ gut beschrieben werden, während für Laute mit starken Änderungen im zeitlichen Verlauf ("p", "k", "r"...) vergleichsweise hohe Datenmengen nötig sind. Durch VBR kann bei gegebener Datenrate also insgesamt bessere Tonqualität erreicht werden, oder niedrigere Datenraten für gleiche Qualität. Allerdings ist bei Festlegung einer bestimmten einzuhaltenden Qualität nicht mehr vorhersagbar, welche Datenrate dafür ausreichend sein wird. Bei Echtzeitanwendungen wie VoIP ist aber gerade die maximal benötigte und nicht die durchschnittliche Datenrate kritisch. The dynamic type value (96 or higher) to be used for speex wide band. Die für speex wide band verwendete dynamische Nutzdatentyp-Kennung (nicht kleine 96). Co&mplexity: Ko&mplexität: Alt+X Alt+X Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. Discontinuous transmission (deutsch etwa: nicht kontinuierliche Datenübertragung) ist eine Erweiterung der VAD/VBR-Übertragung. Bei gleichbleibenden Audiosignal (insbesondere bei erkannten Sprechpausen) wird statt ständig der gleichen Nutzdaten einfach gar nichts übertragen. Senkt die durchschnittliche Datenrate etwas. Bei Störungen auf dem Übertragungsweg kann diese Option zu den von Mobiltelefonen der Anfangszeit bekannten absurden Tonstörungen (hängenbleiben des Tons, Artefakte) führen. The dynamic type value (96 or higher) to be used for speex narrow band. Die für speex narrow band verwendete dynamische Nutzdatentyp-Kennung (nicht kleiner 96). With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. Bei Speex kann die Komplexität (=Genauigkeit) festgelegt werden, mit der der Codec arbeitet. Hierzu wird die Tiefe des Suchvorgangs mit einem Wert von 1 bis 10 gesteuert, ähnlich der -1 bis -9 Option von gzip und bzip2. Im Normalbetrieb ist bei 1 der Rauschabstand 1 bis 2dB schlechter und die CPU-Auslastung nur 10-20% im Vergleich zu 10. In der Praxis bewährt sich für Sprache eine Einstellung von 2 - 4, Inband-DTMF z.B. und andere technische Signale, oder auch Musik, profitieren u.U. von höheren Einstellungen. &Narrow band payload type: &Narrow band Nutzdatentyp-Kennung: G.726 G.726 &40 kbps payload type: G.726 &40 kb/s Nutzdatentyp-Kennung: The dynamic type value (96 or higher) to be used for G.726 40 kbps. Die für G.726 40 kb/s verwendete dynamische Nutzdatentypkennung (nicht kleiner 96). The dynamic type value (96 or higher) to be used for G.726 32 kbps. Die für G.726 32 kb/s verwendete dynamische Nutzdatentypkennung (nicht kleiner 96). G.726 &24 kbps payload type: G.726 &24 kb/s Nutzdatentyp-Kennung: The dynamic type value (96 or higher) to be used for G.726 24 kbps. Die für G.726 24 kb/s verwendete dynamische Nutzdatentypkennung (nicht kleiner 96). G.726 &32 kbps payload type: G.726 &32 kb/s Nutzdatentyp-Kennung: The dynamic type value (96 or higher) to be used for G.726 16 kbps. Die für G.726 16 kb/s verwendete dynamische Nutzdatentypkennung (nicht kleiner 96). G.726 &16 kbps payload type: G.726 &16 kb/s Nutzdatentyp-Kennung: DT&MF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). Die für DTMF (RFC2833) verwendete dynamische Nutzdatentypkennung (nicht kleiner 96). DTMF vo&lume: DTMF &Lautstärke: The power level of the DTMF tone in dB. Die Lautstärke der gesendeten DTMF-Töne in dB, sowohl für reale Töne inband als auch Pegelkennung bei RFC2833. Sollte -10 bis -6 sein. The pause after a DTMF tone. Dauer der Pause zwischen 2 DTMF-Tönen. Zu kleine Werte können dazu führen, dass Folgen von gleichen "Ziffern" vom gesteuerten Gerät nicht mehr getrennt und als nur eine erkannt werden. Hohe Werte sind unschädlich, sofern Sie es nicht eilig haben. DTMF &duration: DTMF-&Dauer: DTMF payload &type: D&TMF Nutzdatentyp-Kennung: DTMF &pause: DTMF-&Pause: dB Duration of a DTMF tone. Dauer eines DTMF-Tons in Millisekunden. Bei zu kleinem Wert kann das gesteuerte Gerät die "Ziffer" nicht mehr erkennen. 200 klappt meist auch mit alten Geräten. DTMF t&ransport: DTMF &Methode: Auto RFC 2833 Inband Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> <p><h3>RFC 2833</h3> Sende DTMF-Töne als RFC 2833 telephone events (Symbole im RTP-Audiodatenstrom).</p> <p><h3>Inband</h3> Sende DTMF inband (tatsächliche Töne, die Twinkle ins Tonsignal einmischt).</p> <p><h3>Auto</h3> Wenn die Gegenstelle RFC 2833 unterstützt, dann DTMF-Töne als RFC 2833 telephone events senden, ansonsten inband.</p> <p><h3>Out-of-band (SIP INFO)</h3> Sende DTMF nur out-of-band via SIP INFO request.</p> General Allgemein Redirection Rufweiterleitung abgehende Rufe &Allow redirection Rufweiterleitung erl&auben Alt+A Alt+A Indicates if Twinkle should redirect a request if a 3XX response is received. Wenn aktiviert, befolgt Twinkle die Anforderung (3XX) der gerufenen Gegenstelle, wenn dort Rufumleitung aktiviert wurde. Ask user &permission to redirect Benutzer vor &Weiterleitung fragen Alt+P Alt+W Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Wenn aktiviert, fragt Twinkle bei Empfang einer 3XX-Anfrage, ob der abgehende Ruf auf ein alternatves Ziel umgeleitet werden darf. Max re&directions: Max. Anz. &Umleit.: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. Die Anzahl von Weiterleitungen eines abgehenden Rufes (von A nach B nach C...), nach der Twinkle aufgibt. Verhindert Endlosweiterleitungen im Kreis (A -> B -> A...). Protocol options Protokoll-Optionen Call &Hold variant: Gespräch-&halten Variante: RFC 2543 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. Auswahl, ob RFC 2543 (set media IP address in SDP to 0.0.0.0) oder RFC 3264 (use direction attributes in SDP) benutzt wird, um ein Gespräch zu halten. Allow m&issing Contact header in 200 OK on REGISTER Erlaube fehlenden Contact header in 200 OK bei REG&ISTER Alt+I Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. Eine "200 OK"-Antwort auf ein "REGISTER" muss einen Contact header enthalten. Einige Provider schicken trotzdem keinen oder einen fehlerhaften. Wenn aktiviert, wird Twinkle versuchen, diesen Fehler auszugleichen. &Max-Forwards header is mandatory &Max-Forwards-Header verlangen Alt+M Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Nach RFC3261 ist der Max-Forwards header vorgeschrieben, wird aber oft trotzdem nicht gesendet. Wenn aktiviert, lehnt Twinkle SIP-Anfragen ohne Max-Forwards header ab. Put &registration expiry time in contact header Anmeldedaue&r im Contact-Header übertragen Alt+R Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. In einer REGISTER-Anfrage kann die Ablaufzeit (expiry, "haltbar:") der Anmeldung sowohl im Contact-Header als auch im Expires-Header übertragen werden. Wenn aktiviert, sendet Twinkle im Contact-header, sonst im Expires-header. &Use compact header names &kompakte Headernamen Indicates if compact header names should be used for headers that have a compact form. Wenn aktiviert, für Headernamen die kurze Form verwenden, soweit eine existiert. Allow SDP change during call setup Erlaube SDP-Änderungen beim Rufaufbau <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> <p>Ein SIP UAS kann ein SDP in einer 1XX Antwort für early media, z.B. bei "Freizeichen", senden. Wenn das Gespräch aufgebaut wird, sollte der SIP UAS das selbe SDP in der "200 OK"-Antwort senden. Nach Empfang eines SDP sollten alle folgenden verworfen werden. Soweit die reine Lehre nach RFC 3261.</p> <p>Wenn erlaubt wird, dass sich SDP wahrend des Gesprächsaufbaus ändert, verwirft Twinkle SDPs in Folgeantworten nicht, sondern ändert die Eigenschaften des RTP-Mediastreams (z.B. codec) entsprechend. Ein geändertes SDP muss eine neue Versionsnummer in der "o="-Zeile haben.</p> <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> <p>Wenn aktiviert, erzeugt Twinkle einen eindeutigen contact header Wert durch Kombination des SIP-Nutzernamens und der Domain: <br> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> So haben 2 Benutzerprofile mit selbem SIP-Nutzernamen aber unterschiedlicher Domain eindeutige contact Adressen und können so gleichzeitig aktiviert werden. </p> <p> Viele Proxies können mit solchen contact header Werten nicht umgehen. Wenn diese Option deaktiviert ist, sendet Twinkle contact header in folgendem Format: <br> <tt>&nbsp;user@local_ip</tt> </p> <p> Dieses Format wird von fast allen SIP-Telefonen verwendet. </p> <p> <b>Nutzen Sie diese Option nur, wenn Sie sie wirklich brauchen! Also wenn Sie mehrere Profile mit gleichem SIP-Benutzernamen haben.</b></p> &Encode Via, Route, Record-Route as list Via, Route, Record-Route als List&e senden The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. Die Via-, Route- und Record-Route-Header können als Liste von durch Komma getrennten Werten oder als einzelne Werte übertragen werden. SIP extensions SIP Erweiterungen &100 rel (PRACK): disabled deaktiviert supported erlaubt required erforderlich preferred bevorzugt Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. Definiert die Art der Unterstützung für 100rel extension (PRACK):<br><br> <b>deaktiviert</b>: 100rel extension wird nicht unterstützt <br><br> <b>erlaubt</b>: 100rel wird unterstützt (wird im "supported header" abgehender INVITEs übertragen). Eine Gegenstelle kann dann ein PRACK auf eine 1xx Antwort anfordern. <br><br> <b>erforderlich</b>: 100rel wird angefordert (wird im "require header" abgehender INVITEs übertragen). Wenn die Gegenstelle ein INVITE sendet (=anruft) und darin signalisiert, dass sie 100rel unterstützt, dann fordert Twinkle beim senden einer 1xx-Antwort PRACK an. Unterstützt die Gwegenstelle 100rel nicht, kommt die Verbindung nicht zustande. <br><br> <b>bevorzugt</b>: Wie "erforderlich", ausser dass auch dann ein Gespräch zustande kommt, wenn die Gegenstelle 100rel nicht unterstützt. Diese Einstellung beeinflusst das Verhalten bei "early media" (z.B. "Freizeichen"). REFER Call transfer (REFER) Rufweitervermittlung (REFER) Allow call &transfer (incoming REFER) GgSt darf vermi&tteln (eingehender REFER) Alt+T Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. Wenn aktiviert, befolgt Twinkle die Anfrage der Gegenstelle (REFER), Sie zu einer anderen Gegenstelle weiterzuvermitteln. Dies kann für Sie Kosten verursachen. As&k user permission to transfer Benutzer vor &Vermittlung fragen Alt+K Alt+V Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Wenn aktiviert, fragt Twinkle bei eingehender Vermittlungsanfrage (REFER) vor Abbau der bisherigen und Anwählen der neuen Verbindung. Im Gegensatz zum Fest- und GSM-Netz trägt bei SIP nicht der Vermittler, sondern der "Anrufende" (also der, der an die neue Gegenstelle weitervermittelt wird) die eventuellen Kosten für das neue vermittelte Gespräch. Hold call &with referrer while setting up call to transfer target T&winkle hält Gespräch als Vermittelter Alt+W Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Wenn aktiviert, übernimmt bei eingehender Vermittlungsaufforderung Twinkle es, den bisherigen Anruf zu halten. Normalerweise sollte die vermittelnde Gegenstelle dies tun. Siehe folgende Option. Standard: deaktiviert. Ho&ld call with referee before sending REFER Twink&le hält Gespräch als Vermittler Alt+L Alt+L Indicates if Twinkle should put the current call on hold when you transfer a call. Wenn aktiviert, schaltet Twinkle als Vermittler das bisherige Gespräch in den Gehalten-Zustand, bevor es der Gegenstelle ein REFER schickt. So muss die Gegenstelle dies nicht tun - siehe vorherige Option. Standard: aktiviert. Auto re&fresh subscription to refer event while call transfer is not finished Subscription &für REFER automatisch erneuern, bis Vermittlung beendet Alt+F Alt+F While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. Während eines Vermittlungvorgangs sendet der Vermittelte NOTIFY-Mitteilungen über den Fortgang des Gesprächsaufbaus an den Vermittler, allerdings nur für eine kurze Zeitspanne, die der Vermittelte festlegt. Wenn aktiviert, sendet der Vermittler (Twinkle) automatisch SUBCRIBEs, um diese Zeit zu verlängern bis der Vermittlungsvorgang abgeschlossen ist. NAT traversal NAT Durchtunnelung &NAT traversal not needed &NAT Durchtunnelung unnötig Alt+N Alt+N Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. Wählen Sie diese Option, wenn sich zwischen Twinkle und Ihrem SIP-Proxy keine NAT (Router) befindet, wenn zwar eine NAT existiert, aber ein Application Level Gateway (ALG) im Router den SIP-Betrieb unterstützt, oder wenn Ihr SIP-Provider "hosted NAT traversal" unterstützt (ein Weg, wie der Provider Probleme mit NAT umgehen kann). Im Zweifelsfall sollten Sie zuerst versuchen, ob diese Einstellung bei Ihnen funktioniert, auch wenn Sie einen Router / NAT haben. &Use statically configured public IP address inside SIP messages Fest voreingestellte &Adresse in SIP-Telegrammen verwenden Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Wenn aktiviert, verwendet Twinkle in SIP-Telegrammen, also Headern und Body, die im nächsten Feld angegebene öffentliche Adresse anstatt der automatisch ermittelten Adresse Ihres Netzwerkanschlusses.<br><br> Wenn Sie diese Option verwenden, müssen Sie auch in Ihrer NAT die entsprechenden RTP-Ports auf Ihren Rechner durchleiten. Use &STUN &STUN aktivieren Choose this option when your SIP provider offers a STUN server for NAT traversal. Aktivieren Sie diese Option, wenn Ihr SIP-Provider einen STUN-Server zum Durchtunneln der NAT anbietet. S&TUN server: S&TUN-Server: The hostname, domain name or IP address of the STUN server. Der Domainname, IP-Adresse oder Hostname des STUN-Servers (gegebenenfalls incl ":<portnr>", also z.B. "stunsrv.de:10000"). &Public IP address: Öffentl. &Adresse: The public IP address of your NAT. Die öffentliche Adresse (IP, DynDNS-domain), unter der Ihre NAT(/Router) im Internet erreichbar ist. Diese Option ist nur bei unveränderlicher Adresse sinnvoll. Telephone numbers Telefonnummern Only &display user part of URI for telephone number Bei Telefonnumern nur User-Teil &der URI anzeigen If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. Wenn eine URI eine Telefonnummer darstellt, dann nur den User-Teil anzeigen. Kommt z.B. ein Anruf von sip:12345@einprovider.com, dann zeigt Twinkle nur "12345" als Adresse. Twinkle betrachtet eine URI als "Telefonnummer", wenn sie entweder den Zusatz "user=phone" enthält, oder wenn die nächste Option aktiv ist und Twinkle den User-Teil als Nummer einschätzt. &URI with numerical user part is a telephone number &URI mit numerischem User-Teil ist Telefonnummer If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. Wenn aktiviert, betrachtet Twinkle jede SIP-Adresse als "Telefonnummer", die nur Ziffern, *, #, + und Sonderzeichen (s.o.) im User-Teil hat. In abgehenden SIP-Mitteilungen hängt Twinkle an solche Adressen den Parameter "user=phone" an. Achtung: z.B. sipgate verändert(e) subtil sein Verhalten bei manchen Funktionen, sobald dieser Parameter mitgesendet wird. &Remove special symbols from numerical dial strings Sonde&rzeichen aus Wählstring entfernen Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. Telefonnumern werden oft unter Verwendung von Sonderzeichen wie "(", ")", " "(Leerzeichen), "-" usw. angegeben, um sie für Menschen leichter lesbar zu gestalten. Beim Wählen, insbesondere einer SIP-Adresse, dürfen diese Zeichen nicht mit angegeben werden. Um das Wählen durch Kopieren und Einfügen, direktes Anklicken im Adressbuch usw. zu vereinfachen, kann man Twinkle eine Liste mit unzulässigen Zeichen angeben, die vor dem eigentlichen Wählen automatisch zu löschen sind. &Special symbols: unzul. &Sonderzeichen: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. Liste aller Sonderzeichen, die Twinkle aus den zu wählenden Nummern entfernen soll. Number conversion Nummernkonvertierung Match expression Suchausdruck Replace Ersetzung <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> <p> Oftmals ist das Format der Telefonnummern, das z.B. der Provider erwartet, nicht identisch mit dem Format der im Adressbuch gespeicherten Nummern. Beispielsweise könnten Ihre Nummern mit "+" und dem Ländercode beginnen, Ihr Provider erwartet aber "00" statt des "+". Oder Sie sind an die lokale SIP-Installation in Ihrer Firma angeschlossen und müssen eine Amtsholziffer vorwählen. Hier können Sie unter Verwendung von Such- und Ersetzungs-Mustern (nach Art regulärer Ausdrücke a la Perl) allgemeingültige Regeln zur Umwandlung von Telefonnummern einrichten. </p> <p> Bei jeden Wahlversuch versucht Twinkle, für die zu wählende Nummer (den User-Teil der vollen SIP-Adresse) einen passenden Ausdruck in der Liste der Suchmuster zu finden. Der zum ersten passenden Suchmuster gehörende Ersetzungsausdruck ersetzt die Original-Nummer, wobei durch "(" ")" umschlossene Platzhalter im Suchausdruck (z.B. "([0-9]*)" für "beliebig viele Ziffern") die durch sie "geschluckten" Zeichen zur entsprechenden Variablen (z.B. "$1" für den ersten Platzhalter) im Ersetzungsausdruck transportieren (siehe `man 7 regex` oder konqueror:"#regex"). Wird kein passendes Suchmuster gefunden, bleibt die Nummer unverändert. </p> <p> Die Regeln werden auch auf die Absenderangaben eingehender Rufe angewendet, um diese Nummern gleich in das von Ihnen gewünschte Format zu wandeln. (!!! <i>[bug? Amtsziffer 0. d.Üs.]</i> ) </p> <h3>Beispiel 1</h3> <p> Angenommen Ihr Ländercode ist "49" für Deutschland, und Sie haben auch viele Inlandnummern in Ihrem Adressbuch in internationalem Nummernformat gespeichert, also z.B. +49 911 2345678. Ihr Provider erwartet für innerdeutsche Gespräche aber 0911 2345678. Also möchten Sie die '+49' durch '0' ersetzen. Für Auslandsgespräche möchten Sie '+' durch '00' ersetzen. </p> <p> Sie benötigen hierzu folgende Regeln, in dieser Reihenfolge: </p> <blockquote> <tt> Suchausdruck = \+49([0-9]*) , Ersetzung =0$1<br> Suchausdruck = \+([0-9]*) , Ersetzung = 00$1</br> </tt> </blockquote> <h3>Beispiel 2</h3> <p> Sie befinden sich an einer Telefonanlage und alle Nummern mit 0 als erste Ziffer sollen die Amtsholziffer 9 vorangestellt bekommen. </p> <blockquote> <tt> Suchausdruck = 0[0-9]* , Ersetzung = 9$&<br> </tt> </blockquote> ( $& ist eine spezielle Variable, die die gesamte Originalnummer überträgt)<br> Anmerkung: Sie können diese Regel nicht einfach nur als dritte nach denen aus Beispiel 1 angeben, denn es wird immer nur die erste zutreffende Regel angewendet. Stattdessen müssten die Ersetzungen der Regeln 1 und 2 in "90$1" u. "900$1" geändert werden Move the selected number conversion rule upwards in the list. Regel in der Liste nach oben verschieben. Move the selected number conversion rule downwards in the list. Regel in der Liste nach unten verschieben. &Add &Neu Add a number conversion rule. Neue Regel erzeugen. Re&move &Löschen Remove the selected number conversion rule. Die ausgewählte Regel löschen. &Edit B&earbeiten Edit the selected number conversion rule. Die ausgewählte Regel ändern. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. Tippen Sie eine Nummer und klicken Sie "Test", um das Ergebnis der Umwandlung durch die Regeln zu sehen. &Test &Testen Test how a number is converted by the number conversion rules. Die Regeln mit der Nummer links testen und Resultat anzeigen. for STUN Sekunden Keep alive timer for the STUN protocol. If you have enabled STUN, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. Zeitgeber für das STUN-Protokoll. Wenn STUN aktiviert ist, werden die STUN-keep-alive Datenpakete in diesem Zeitabstand von Twinkle gesendet. Damit der Router die Zuordnung zwischen interner und externer Adresse nicht aus der NAT-Adresstabelle löscht, frischen diese keep-alive-Pakete die Zuordnung in der NAT rechtzeitig auf. Dieser Wert ist daher von der eingesetzten NAT abhängig und sollte nicht zu gross gezählt werden. When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". Wenn ein Anruf eingeht, beginnt dieser Zeitgeber abzulaufen. Wird der Ruf bis zum Ende der Zeitspanne nicht angenommen, sendet Twinkle "480 User Not Responding" und weist so den Anruf ab. NAT &keep alive: &STUN NAT-keep-alive alle: &No answer: "&Nicht erreichbar" nach: Ring &back tone: &Freizeichen: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p>Geben Sie hier den Namen der .wav-Datei für das Freizeichen dieses Benutzerprofils an.</p> <p>Diese Einstellung ersetzt bei abgehendem Ruf von diesem Benutzerprofil die Auswahl für "Freizeichen" aus den Systemeinstellungen.</p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> <p>Geben Sie hier den Namen der .wav-Datei für den Klingelton dieses Benutzerprofils (="Nummer") an.</p> <p>Diese Einstellung ersetzt bei Anrufen an dieses Benutzerprofil die Auswahl "Klingelton" aus den Systemeinstellungen.</p> &Ring tone: &Klingelton: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn ein Gespräch durch Sie beendet wird. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der abgesendeten SIP BYE Anforderung werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <br> <b>SIPREQUEST_METHOD=BYE</b>. <br> <b>SIPREQUEST_URI</b> enthält die request-URI des BYE. <br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn ein eingehender Ruf nicht zustande kommt, also das Klingeln endet ohne dass "abgehoben" wurde. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der abgesendeten SIP failure Antwort werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <br> <b>SIPSTATUS_CODE</b> enthält den Statuscode der abgesendeten SIP failure Antwort. <br> <b>SIPSTATUS_REASON</b>enthält "reason phrase", also die "Fehler"ursache in Klartext.<br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn ein Gespräch durch die Gegenstelle beendet wird. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der eingehenden SIP BYE Anforderung werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <br> <b>SIPREQUEST_METHOD=BYE</b>. <br> <b>SIPREQUEST_URI</b> enthält die request-URI des BYE. <br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. </p> <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn das Gespräch durch die Gegenstelle angenommen wird. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der eingehenden "200 OK" Mitteilung werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <br> <b>SIPSTATUS_CODE=200</b>. <br> <b>SIPSTATUS_REASON</b> enthält "reason phrase"<br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn Sie einen Anruf entgegennehmen. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der gesendeten "200 OK" Antwort werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <br> <b>SIPSTATUS_CODE=200</b>. <br> <b>SIPSTATUS_REASON</b> enthält "reason phrase"<br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. Call released locall&y: Gespräch &lokal beendet: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn ein abgehender Anruf nicht zustande kommt, z.B. wegen timeout, DND usw. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der empfangenen SIP failure Antwort werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <br> <b>SIPSTATUS_CODE</b> enthält den Statuscode der abgesendeten SIP failure Antwort.<br> <b>SIPSTATUS_REASON</b> enthält "reason phrase", also die "Fehler"ursache in Klartext.<br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gestartet, wenn Sie einen Anruf tätigen. </p> <h3>Environment Variablen</h3> <p> Die Inhalte aller SIP header der abgesendeten SIP INVITE Anforderung werden in Environment Variablen ans Script übergeben. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>.<br> <b>SIPREQUEST_METHOD=INVITE</b>.<br> <b>SIPREQUEST_URI</b> enthält die request-URI des INVITE.<br> <b>TWINKLE_USER_PROFILE</b> enthält den Namen des aktuell genutzten Benutzerprofils. Outgoing call a&nswered: Abgehe&nder Ruf angenommen: Incoming call &failed: Eingehender Ruf er&folglos: &Incoming call: E&ingehender Ruf: Call released &remotely: Gesp&rächsende durch Gegenstelle: Incoming call &answered: Eingehender Ruf &angenommen: O&utgoing call: Abgehender R&uf: Out&going call failed: Ab&gehender Ruf erfolglos: &Enable ZRTP/SRTP encryption ZRTP/SRTP V&erschlüsselung When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. Wenn aktiviert, versucht Twinkle bei allen abgehenden und ankommenden Geprächen die Sprachdaten zu verschlüsseln. Hierzu muss natürlich die Gegenstelle ebenfalls ZRTP/SRTP unterstützen, andernfalls bleibt das Gespräch unverschlüsselt. ZRTP settings ZRTP Einstellungen O&nly encrypt audio if remote party indicated ZRTP support in SDP &Nur verschlüsseln, wenn Gegenstelle ZRTP-Unterstützung im SDP meldet A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. Eine ZRTP-fähige SIP-Gegenstelle kann diese Fähigkeit schon während des Gesprächsaufbaus mitteilen. Wenn aktiviert, versucht Twinkle nur bei solchen Gegenstellen, eine Verschlüsselung auszuhandeln. &Indicate ZRTP support in SDP ZRTP-Unterstützung &im SDP mitteilen Twinkle will indicate ZRTP support during call setup in its signalling. Wenn aktiviert, meldet Twinkle der Gegenstelle beim Gesprächsaufbau im SDP, dass es ZRTP unterstützt. &Popup warning when remote party disables encryption during call &Warnen, wenn Gegenstelle auf unverschlüsselt umschaltet A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. Die Gegenstelle kann während eines verschlüsselten Gesprächs ein ZRTP-go-clear Komando senden und damit die Verschlüsselung stoppen. Wenn aktiviert, macht Twinkle in diesem Fall mit einer Warnmeldung auf das Sicherheitsproblem aufmerksam. Dynamic payload type %1 is used more than once. Dynamische Nutzdatenkennung %1 mehrfach vergeben. You must fill in a user name for your SIP account. Sie müssen den Namensteil Ihrer SIP-Benutzerkennung angeben. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Sie müssen den domain-Teil (den Teil rechts nach @) Ihrer SIP-Benutzerkennung angeben. Häufig identisch mit der Domain Ihres SIP-Providers. Für direct-IP-to-IP, also ohne SIP-Provider, ist dies der (dyndns-)Name oder die öffentliche IP Ihres PC. Invalid user name. Unzulässiger Benutzername. Invalid domain. Unzulässige Benutzerdomain. Invalid value for registrar. Unzulässiger Wert für Registrar. Invalid value for outbound proxy. Unzulässiger Wert für outbound proxy. Value for public IP address missing. Keine öffentliche Adresse angegeben. Invalid value for STUN server. Unzulässiger Wert für STUN-Server. Ring tones Description of .wav files in file dialog Signaltöne Choose ring tone Auswahl Klingelton Ring back tones Description of .wav files in file dialog Signaltöne All files Alle Dateien Choose incoming call script Auswahl Script bei "eingehendem Ruf" Choose incoming call answered script Auswahl Script bei "eingehender Ruf angenommen" Choose incoming call failed script Auswahl Script bei "eingehender Ruf erfolglos" Choose outgoing call script Auswahl Script bei "abgehendem Ruf" Choose outgoing call answered script Auswahl Script bei "abgehender Ruf angenommen" Choose outgoing call failed script Auswahl Script bei "abgehender Ruf erfolglos" Choose local release script Auswahl Script bei "Gespräch lokal beendet" Choose remote release script Auswahl Script bei "Gespräch durch Gegenstelle beendet" Voice mail Anrufbeantworter &Follow codec preference from far end on incoming calls Gegenstelle wählt Codecs bei eingehendem Ru&f <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. Wenn aktiviert: Bei ankomendem Anruf richtet sich Twinkle bevorzugt nach der Liste erlaubter Codecs von der Gegenstelle (SDP offer). Konkret wird der erste Codec der Ggst.-Wunschliste verwendet, der auch von Twinkle in der aktuellen Einstellung unterstützt wird. Wenn deaktiviert, verwendet Twinkle den ertsen Codec der eigenen Liste, der auch von der GgSt. untersützt wird. Follow codec &preference from far end on outgoing calls Gegenstelle wählt Codecs bei a&bgehendem Ruf <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. Wenn aktiviert: Bei abgehendem Ruf richtet sich Twinkle bevorzugt nach der Liste erlaubter Codecs von der Gegenstelle (SDP answer). Konkret wird der erste Codec der Ggst.-Wunschliste verwendet, der auch von Twinkle in der aktuellen Einstellung unterstützt wird. Wenn deaktiviert, verwendet Twinkle den ertsen Codec der eigenen Liste, der auch von der GgSt. untersützt wird, also in der SDP-Answer-Liste steht. Codeword &packing order: Datenanordnung (codeword &packing order): RFC 3551 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. Es gibt 2 Methoden, die G.726 codewords in ein RTP-Paket anzuordnen. Standard ist RFC 3551. Einige SIP-Provider nutzen allerdings ATM AAL2. Wenn die Tonübertragung bei Verwendung des G.726-Codecs gestört ist, versuchen Sie hier die andere Einstellung. Replaces Replaces Indicates if the Replaces-extenstion is supported. Wenn aktiviert, unterstützt Twinkle Replaces-Extension bei PRACK. Attended refer to AoR (Address of Record) Vermittlung mit Rückfrage verwendet "Address of Record" An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. Eine Vermittlung mit Rückfrage sollte die Contact-URI als Zieladresse nutzen, um der vermittelten GgSt die neu zu schaltende Verbindung mitzuteilen. Diese Adresse kann allerdings evtl. nicht global gültig d.h. "route-"bar sein. Das vermittelte Gespräch kommt dann beim neuen Ziel nicht an. Alternativ kann Twinkle die AoR (Address of Record) nutzen. Nachteil hierbei: diese ist bei mehreren unter gleichem SIP-Benutzerkonto angemeldeten Endgeräten nicht eindeutig, so dass von der vermittelten GgSt (eigentlich vom Provider) alle Endgeräte angesprochen werden und einen Anuf signalisieren. Privacy Datenschutz Privacy options Datenschutz-Einstellungen &Send P-Preferred-Identity header when hiding user identity &Sende "P-Preferred-Identity Header" bei "Absender verbergen" Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. Wenn aktiviert, wird zusammen mit der Absenderangabe ein "P-Preferred-Identity Header" beim INVITE gesendet, falls "Absender verbergen" aktiv ist. <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dieses Script wird gerufen, wenn ein INVITE (Anruf) ankommt. <br> Bitte lesen Sie im Handbuch unter "/usr/share/doc/packages/twinkle/..." oder "http://twinklephone.com" die ausführliche Beschreibung! </p> <h3>Rückgabewerte</h3> - print nach STDOUT (z.B. `echo "action=dnd"`), ein Wert pro Zeile: <br> <tt>action=[ continue | reject | dnd | redirect | autoanswer ]<br></tt> <blockquote> <i>continue</i> - Anrufverarbeitung normal fortsetzen (default)<br> <i>reject</i> - Ruf abweisen<br> <i>dnd</i> - Ruf ablehnen mit Hinweis "do not disturb"<br> <i>redirect</i> - Ruf umleiten nach <tt>contact</tt> (siehe dort)<br> <i>autoanswer</i> - Ruf "automatisch" annehmen<br> </blockquote> <br> <tt>reason=&lt;string&gt; </tt>für dnd und reject (Anzeige bei GgSt)<br> <tt>contact=&lt;Umleitadresse&gt; </tt>für redirect<br> <tt>caller_name=&lt;neuer Displayname des Anrufers&gt; </tt>ersetzt evtl. vorh. displayname aus INVITE<br> <tt>ringtone=&lt;Dateiname des .wav file&gt; </tt>Klingelton, speziell f. diesen Anruf (nur bei <i>continue</i> ;-)<br> <tt>display_msg=&lt;belieb. Hinweis für Detailanzeige Hauptfenster&gt;</tt><br> <tt>end </tt>Twinkle wertet alle Rückgaben aus, schliesst STDOUT des Scripts(!), und arbeitet weiter<br> </tt> </p> <p> <h3>Environment Variablen</h3> <p> Die Werte aller SIP header des eingehenden INVITE werden in Environmentvariablen ans Script übergeben. Aufbau der Variablennamen: <b>SIP_&lt;HEADER_NAME&gt;</b> - z.B. SIP_FROM enthält Wert des "from header". </p> <p> TWINKLE_TRIGGER=in_call. <br> SIPREQUEST_METHOD=INVITE. <br> SIPREQUEST_URI enthält request-URI des INVITE.<br> TWINKLE_USER_PROFILE enthält Name des Benutzerprofils, für das der Ruf einging. &Voice mail address: Anrufbeantworter Nr/Adr: The SIP address or telephone number to access your voice mail. Die SIP-Adresse bzw. Telefonnr., unter der Ihr vom Provider zur Verfügung gestellter Anrufbeantworter abrufbar ist. Oft gibt der Provider zwei Nummern an, eine zum Abruf über beliebige Telefone (zB. "0049 211 58000111") und eine zum SIP-Abruf (zB. "50000") - dann sollte hier die SIP-Nummer angegeben werden. Unsollicited Asterisk-Modus Sollicited RFC 3842 <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> <H2>Message waiting indication Typ</H2> <p> Wenn Ihr SIP-Provider "message waiting indication" (MWI, Benachrichtigung über aufgezeichnete Nachrichten) anbietet, kann Twinkle Sie über neue und schon abgehörte Nachrichten auf Ihrem SIP-Anrufbeantworter informieren. Abhängig von Ihrem Provider bzw. dem von Ihnen genutzten Anrufbeantworterdienst müssen Sie hier eines der folgenden Verfahren einstellen: </p> <H3>Asterisk</H3> <p> Asterisk unterstützt im allg. "unsollicited message waiting indication". </p> <H3>RFC 3842</H3> <p> "Sollicited message waiting indication" entsprechend RFC 3842 Spezifikation (z.B. für "sipgate.de"). </p> &MWI type: &MWI Typ: Sollicited MWI RFC 3842 Subscription &duration: Anmel&dung gültig: Mailbox &user name: Mailbox Ben&utzername: The hostname, domain name or IP address of your voice mailbox server. Der Domainname, IP-Adresse oder Hostname des Voice-Mailbox-Servers. Versuchen Sie die Voreinstellung (=Domain Ihres Benutzernamens), falls Ihr Provider nichts anderes mitgeteilt hat. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Bei RFC 3842 MWI meldet sich das Endgerät (Twinkle) für eine gewisse Dauer beim Server zum Empfang von Benachrichtigungen an (SUBSCRIBE), und sollte diese Anmeldung vor Ablauf erneuern. Ähnlich der "expiry time" / "haltbar" für REGISTER, siehe SIP-Server. Your user name for accessing your voice mailbox. Ihr Benutzername zum Zugriff auf Ihre Voice-Mailbox (Anrufbeantworter). Wenn Ihr Provider nichts anderes mitteilt, versuchen Sie die Vorgabe (=Ihr SIP-Benutzername). Mailbox &server: Mailbox-&Server: Via outbound &proxy Via Outbound-&Proxy: Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. Wenn aktiviert, sendet Twinkle SIP-Anfragen an die Mailbox über den Outbound-Proxy. You must fill in a mailbox user name. Sie müssen einen Mailbox-Benutzernamen angeben. You must fill in a mailbox server Sie müssen den Mailbox-Server angeben. Invalid mailbox server. Unzulässiger Name für Mailbox-Server. Invalid mailbox user name. Unzulässiger Mailbox-Benutzername. Use domain &name to create a unique contact header value Domain-&Name benutzen für eindeutigen Contact-Header Select ring back tone file. Dateiauswahl Freizeichen. Select ring tone file. Dateiauswahl Klingelton. Select script file. Dateiauswahl Scriptfile / Programm. %1 converts to %2 Vor Konvertierung: <b>%1</b><br> Nach Konvertierung: <b>%2</b> Instant message Instant Message Presence Online-Status &Maximum number of sessions: &Max. Anzahl IM-Fenster: When you have this number of instant message sessions open, new incoming message sessions will be rejected. Hier können Sie die Anzahl gleichzeitig offener IM-Fenster für dieses Benutzerprofil als Empfänger begrenzen.<br> Bei Erreichen der Obergrenze erhält jeder weitere Absender einer Instant Message den Hinweis "468 Besetzt". <br> Sie können diese Einstellung auf 0 setzen, wenn Sie keine ankommenden Instant Messages wünschen. Your presence Ihr Online-Status &Publish availability at startup Erreichbarkeit beim Start &veröffentlichen Publish your availability at startup. Wenn aktiviert, veröffentlicht Twinkle Ihren Online-Status als "online", sobald das Benutzerprofil aktivieren. Beachten Sie, dass Sie trotz allem solange nicht erreichbar sind, bis Sie sich bei, SIP-Server angemeldet haben - siehe Menü "Anmeldung", sowie hier "SIP Server" "Bei Profilstart anmelden". Buddy presence Buddy Online-Status Publication &refresh interval (sec): Erneut ve&röffentlichen nach (Sek.): Refresh rate of presence publications. Die Refreshzeit für die Veröffentlichung des Online-Status in Sekunden. Damit der "presence server" z.B. eine unterbrochene Verbindung schnell bemerkt, kann es sinnvoll sein, hier wesentlich kürzere Werte als den Standard "3600" einzutragen. &Subscription refresh interval (sec): "&Subscribe" erneut nach (Sek.): Refresh rate of presence subscriptions. Die Refreshzeit für die Anmeldung durch "SUBSCRIBE" zum Erhalten von Online-Status-Mitteilungen über die Ereichbarkeit der Buddies unter diesem Benutzerprofil. Standard "3600". Transport/NAT Übertragung/NAT Add q-value to registration Verwende q-Wert bei der Anmeldung The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. Falls mehrere Geräte auf die gleiche SIP-Benutzerkennung angemeldet werden, kann der Provider den q-Wert dazu verwenden, die Reihenfolge festzulegen, in der ein eingehender Ruf an die Geräte zugetellt wird. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. Der q-Wert darf zwischen 0,000 und 1,000 liegen. Ein höherer Wert bedeutet höhere Priorität. Das Gerät mit der höchsten Priorität wird als erstes angesprochen. SIP transport SIP Übertragung UDP UDP TCP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. Übertragungsmodus (TCP oder UDP) für SIP. Bei "Automatisch" wird TCP verwendet, falls die Größe der zu übertragenden Nachricht das Limit für UDP übersteigt. T&ransport protocol: Übe&rtragungsprotokoll: UDP t&hreshold: UDP &Grenzwert: bytes Bytes Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. Nachrichten, die größer sind als der Grenzwert, werden über TCP gesendet, kleinere über UDP. Use &STUN (does not work for incoming TCP) &STUN benutzen (wirkungslos für eingehende TCP-Verbindungen) P&ersistent TCP connection TCP-V&erbindung aufrecht erhalten Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. Wenn aktiviert: Twinkle hält die TCP-Verbindung aufrecht, die bei der Registrierung verwendet wurde. So kann der SIP-Proxy diese Verbindung weiterhin benutzen, um ankommende Anfragen an Twinkle weiterzuleiten. Durch Senden von "Application ping Paketen" wird ständig überprüft, ob die Verbindung weiterhin besteht. &Send composing indications when typing a message. &Sende "compositing indication" beim Schreiben einer Nachricht. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. Wenn aktiviert, sendet Twinkle eine "compositing indication" wenn Sie eine Nachricht tippen. So kann der Empfänger erkennen, dass Sie gerade dabei sind, eine Nachricht zu verfassen. AKA AM&F: A&KA OP: Authentication management field for AKAv1-MD5 authentication. Operator variant key for AKAv1-MD5 authentication. Prepr&ocessing Preprocessing (improves quality at remote end) &Automatic gain control Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Automatic gain control &level: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. &Voice activity detection When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. &Noise reduction The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. Acoustic &Echo Cancellation In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Variable &bit-rate Discontinuous &Transmission &Quality: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. bytes Use tel-URI for telephone &number Expand a dialed telephone number to a tel-URI instead of a sip-URI. Accept call &transfer request (incoming REFER) Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. Enable NAT &keep alive Send UDP NAT keep alive packets. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. WizardForm Twinkle - Wizard The hostname, domain name or IP address of the STUN server. Der Domainname, IP-Adresse oder Hostname des STUN-Servers. Twinkle versucht, unter der hier genannten Domain die korrekten Daten beim DNS-Server zu erfragen (RFC 2782). Daher genügt bei Providern, die dies unterstützen, die Domain des Anmeldeservers als Angabe. S&TUN server: S&TUN-Server: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. Der Nutzername, den Sie von Ihrem Provider zugewiesen bekommen haben. Dieser ist der erste Teil Ihrer vollständigen SIP-Adresse <b>nutzername</b>@domain.com . Bei vielen Providern wird dieser -eigentlich falsch- als Telefonnummer bezeichnet. <br><br> *DATEN FÜR DIESES FELD SIND ZWINGEND NOTWENDIG. &Domain*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. Wählen Sie Ihren SIP-Provider aus, und tragen Sie dann Ihren SIP-Benutzernamen, gegebenenfalls Absendernamen, Anmeldenamen und Passwort ein.<br> Wenn Ihr SIP-Provider nicht in der Liste erscheint, wählen Sie <b>Anderer</b> und tragen Sie die Angaben entsprechend der von Ihrem Provider erhaltenen Daten ein. <p> Praktisch überall in Twinkle bekommen Sie mit <b>Umschalt-F1</b> oder <b>rechtem Mausklick</b> Hilfetexte wie diesen zu den einzelnen Feldern und Knöpfen. </p> &Authentication name: &Anmeldename: &Your name: Ihr &Absendername: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ihr SIP-Anmeldename. Häufig identisch mit Ihrem SIP-Nutzernamen, dann leerlassen. Falls nicht, wird Ihr Provider dies mitteilen. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Die Domain oder IP-Adresse, unter der Sie von Ihrem Provider geführt werden bzw. im Internet erreichbar sind. Dies ist der zweite Teil ihrer vollständigen SIP-Adresse nutzername@<b>domain.com</b>. Bei vielen Providern identisch mit der Domain des Providers. Für direct-IP-to-IP (siehe Handbuch) ist hier die Adresse (DynDNS oder IP) einzutragen, unter der <b>Ihr Rechner</b> zu erreichen ist. <br><br> *DATEN FÜR DIESES FELD SIND ZWINGEND NOTWENDIG. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Ihr Absendername oder Pseudonym. Dieses Feld wird nur als Teil der Absenderangaben zur angerufenen/rufenden Gegernstelle übertragen und dort evtl angezeigt. Beliebige Angabe, nicht zwingend erforderlich. SIP pro&xy: SIP-Pro&xy: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. Die Domain, IP-Adresse oder Hostname Ihres SIP-Proxy. Wenn dieser mit Ihrer Benutzerdomain identisch ist, lassen Sie dieses Feld leer. &SIP service provider: &SIP Service Provider (Umschalt-F1 für Hilfe): &Password: &Passwort: &User name*: N&utzername *: Your password for authentication. Ihr Anmeldepasswort. Wenn Sie dieses Feld leerlassen, müssen Sie das Passwort bei jeder Anmeldung in den dann erscheinenden Requester eintragen. &OK Alt+O Alt+O &Cancel Abbruch (Es&c) Alt+C Alt+C None (direct IP to IP calls) Keiner (direkt IP zu IP) Other Anderer User profile wizard: Benutzerprofil Wizard: You must fill in a user name for your SIP account. Sie müssen den Namensteil Ihrer SIP-Benutzerkennung angeben. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Sie müssen den domain-Teil (den Teil rechts nach @) Ihrer SIP-Benutzerkennung angeben. Häufig identisch mit der Domain Ihres SIP-Providers. Für direct-IP-to-IP, also ohne SIP-Provider, ist dies der (dyndns-)Name oder die öffentliche IP Ihres PC. Invalid value for SIP proxy. Unzulässiger Wert für SIP-Proxy. Invalid value for STUN server. Unzulässiger Wert für STUN-Server. YesNoDialog &Yes &Ja &No &Nein twinkle-1.4.2/src/gui/lang/twinkle_cs.ts0000644000175000001440000103603611151060224015117 00000000000000 AddressCardForm Twinkle - Address Card Twinkle - Adresářový záznam &Remark: P&oznámka: Infix name of contact. ProstÅ™ední jméno nebo titul. First name of contact. KÅ™estní jméno nebo jakékoliv jiné jméno. Bude třídicím klíÄem. &First name: &KÅ™estní jméno: You may place any remark about the contact here. PolíÄko pro libovolné poznámky. &Phone: &Telefon: &Infix name: &Titul: Phone number or SIP address of contact. Telefonní Äíslo nebo SIP adresa kontaktu. Last name of contact. Příjmení. &Last name: &Příjmení: &OK &OK Alt+O Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C Alt+C You must fill in a name. Musíte zadat jméno. You must fill in a phone number or SIP address. Musíte zadat jméno nebo SIP adresu. AuthenticationForm Twinkle - Authentication Twinkle - PÅ™ihlášení user No need to translate user The user for which authentication is requested. Uživatel, který má být pÅ™ihlášen. profile No need to translate profile The user profile of the user for which authentication is requested. Profil uživatele, pro kterého je pÅ™ihlášení vyžadováno. User profile: Uživatelský profil: User: Uživatel: &Password: &Heslo: Your password for authentication. VaÅ¡e pÅ™ijhlaÅ¡ovací heslo. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. VaÅ¡e pÅ™ihlaÅ¡ovací SIP jméno. ÄŒasto je identické s vaším uživatelským SIP jménem. Pokud ne, zeptejte se na nÄ›j vaÅ¡eho VoIP poskytovatele. &User name: Uži&vatelské jméno: &OK &OK &Cancel ZruÅ¡it (Es&c) Login required for realm: Pro Realm je nutné pÅ™ihlášení: realm No need to translate realm The realm for which you need to authenticate. Realm, ke kterému se musíte pÅ™ihlásit. BuddyForm Twinkle - Buddy Twinkle - Buddy Address book Adresář Select an address from the address book. vybrat adresu z adresáře . &Phone: &Telefon: Name of your buddy. Jméno vaÅ¡eho Buddy. &Show availability &Ukázat dostupnost Alt+S Alt+S Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. Vybrat tuto volbu pokud chcete vidÄ›t dostupnost vaÅ¡eho buddy. Toto bude fungovat pouze pokud váš VoIP poskytovatel nabízí funkci "prezenÄního agenta". &Name: &Jméno: SIP address your buddy. SIP adresa vaÅ¡eho buddy. &OK &OK Alt+O Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C Alt+C You must fill in a name. Musíte zadat jméno. Invalid phone. neplatné telefonní Äíslo. Failed to save buddy list: %1 NepodaÅ™ilo se uložit buddy seznam: %1 BuddyList Availability Dostupnost unknown neznámý offline offline online online request rejected požadavek odmítnut not published nepublikováno failed to publish publikování selhalho request failed požadavek selhal Click right to add a buddy. pravým kliknutím pÅ™idat buddyho. CoreAudio Failed to open sound card NepodaÅ™ilo se získat přístup ke zvukové kartÄ› Failed to create a UDP socket (RTP) on port %1 NepodaÅ™ilo se vytvoÅ™it UDP socket (RTP) na portu %1 Failed to create audio receiver thread. NepodaÅ™ilo se vytvoÅ™it proces pro audio příjem. Failed to create audio transmitter thread. NepodaÅ™ilo se vytvoÅ™it proces pro audio pÅ™enos. CoreCallHistory local user lokální uživatel remote user vzdálený uživatel failure Chyba unknown neznámý in příchozí out odchozí DeregisterForm Twinkle - Deregister Twinkle - Odhlášení deregister all devices Odhlásit vÅ¡echny koncové přístroje &OK &OK &Cancel ZruÅ¡it (Es&c) DiamondcardProfileForm Twinkle - Diamondcard User Profile Your Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. &Account ID: &PIN code: &Your name: <p align="center"><u>Sign up for a Diamondcard account</u></p> &OK Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C Fill in your account ID. Fill in your PIN code. A user profile with name %1 already exists. Your Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> DtmfForm Twinkle - DTMF Twinkle - DTMF Keypad Klávesnice 2 2 3 3 Over decadic A. Normally not needed. FunkÄní klávesa A. NormálnÄ› nepoužívaná. 4 4 5 5 6 6 Over decadic B. Normally not needed. FunkÄní klávesa B. Používaná zřídka používaná. 7 7 8 8 9 9 Over decadic C. Normally not needed. FunkÄní klávesa C. Používaná zřídka. Star (*) HvÄ›zdiÄka (*) 0 0 Pound (#) Křížek (#) Over decadic D. Normally not needed. FunÄní klávesa D. Používaná zřídka. 1 1 &Close Za&vřít Alt+C Alt+C FreeDeskSysTray Show/Hide Ukázat/Zminimalizovat Quit UkonÄit GUI Failed to create a UDP socket (SIP) on port %1 Chyba pÅ™i otevírání UDP socketu (SIP) na portu %1 The following profiles are both for user %1 Následující uživatelské profily používají stejnou SIP Adresu %1 You can only run multiple profiles for different users. Na jeden SIP úÄet si nemůžete aktivovat souÄasnÄ› více profilů. Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Twinkle nemůže najít žádné aktivní síťové rozhraní a používá nyní 127.0.0.1 jako svoji lokální IP adresu. Pokud se pÅ™ipojíte k nÄ›jaké síti pozdÄ›ji, musíte Twinkle spustit znovu. Tím umožníte nalezení nové a funkÄní síťové adresy. Line %1: incoming call for %2 Linka %1: příchozí hovor pro %2 Call transferred by %1 Volání pÅ™epojeno uživatelem %1 Line %1: far end cancelled call. Linka %1: Protistrana pÅ™eruÅ¡ila hovor. Line %1: far end released call. Linka %1: hovor ukonÄen protistranou. Line %1: SDP answer from far end not supported. Linka %1: SDP odpovÄ›Ä protistrany není podporována. Line %1: SDP answer from far end missing. Linka %1: žádná SDP odpovÄ›Ä protistrany. Line %1: Unsupported content type in answer from far end. Linka %1: Typ obsahu v odpovÄ›di protistrany není podporována. Line %1: no ACK received, call will be terminated. Linka %1: žádný ACK od protistrany, volání ukonÄeno. Line %1: no PRACK received, call will be terminated. Linka %1: žádný PRACK od protistrany, volání bude ukonÄeno. Line %1: PRACK failed. Linka %1: PRACK chyba. Line %1: failed to cancel call. Linka %1: Chyba pÅ™i pokusu o ukonÄení hovoru. Line %1: far end answered call. Linka %1: Protistrana odpovÄ›dÄ›la na volání. Line %1: call failed. Linka %1: Volání selhalo. The call can be redirected to: Hovor může být pÅ™epojen na: Line %1: call released. Linka %1: Hovor ukonÄen. Line %1: call established. Linka %1: Spojení navázáno. Response on terminal capability request: %1 %2 OdpovÄ›Ä protistrany na dotaz o výpis možností: %1 %2 Terminal capabilities of %1 Schopnosti protistrany %1 Accepted body types: Akceptované "body types": unknown neznámý Accepted encodings: Akceptovaná "encodings": Accepted languages: Akceptované jazyky: Allowed requests: Povolené "requests": Supported extensions: Podporované "extensions": none žádný End point type: Typ koncového zařízení: Line %1: call retrieve failed. Linka %1: Chyba pÅ™i pokusu o znovunavázání hovoru. %1, registration failed: %2 %3 %1, Neúspěšné pÅ™ihlášení: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, PÅ™ihlášení úspěšné (platné na %2 Sek.) %1, registration failed: STUN failure %1, PÅ™ihlášení neúspěšné: STUN chyba %1, de-registration succeeded: %2 %3 %1, Odhlášení probÄ›hlo: %2 %3 %1, fetching registrations failed: %2 %3 %1, Chyba pÅ™i dotazu na registraci: %2 %3 : you are not registered : Nejste pÅ™ihlášen : you have the following registrations : jsou aktivní následující pÅ™ihlášení : fetching registrations... : probíhá dotaz na pÅ™ihlášení... Line %1: redirecting request to Linka %1: pÅ™evést dotaz na Redirecting request to: %1 PÅ™evést dotaz na: %1 Line %1: DTMF detected: Linka %1: detekováno DTMF: invalid DTMF telephone event (%1) Neplatné vyhodnocení DTMF (%1) Line %1: send DTMF %2 Linka %1: vyÅ¡li DTMF %2 Line %1: far end does not support DTMF telephone events. Linka %1: Protistrana nepodporuje žádný DTMF dotaz. Line %1: received notification. Linka %1: Oznámení pÅ™ijato. Event: %1 Událost: %1 State: %1 Stav: %1 Reason: %1 PříÄina: %1 Progress: %1 %2 Postup: %1 %2 Line %1: call transfer failed. Linka %1: PÅ™esmÄ›rování hovoru selhalo. Line %1: call succesfully transferred. Linka %1: Hovor byl pÅ™esmÄ›rován. Line %1: call transfer still in progress. Linka %1: PÅ™esmÄ›rování hovoru probíhá. No further notifications will be received. Protistrana zastavila zasílání zpráv. Line %1: transferring call to %2 Linka %1: PÅ™esmÄ›rování hovoru na %2 Transfer requested by %1 PÅ™esnÄ›rování hovoru vyžádáno od %1 Line %1: Call transfer failed. Retrieving original call. Linka %1: PÅ™esmÄ›rování hovoru bylo neúspěšné. V původním hovoru bude pokraÄováno. Redirecting call Hovor bude pÅ™esmÄ›rován User profile: Uživatelský profil: User: Uživatel: Do you allow the call to be redirected to the following destination? Chcete dovolit aby hovor byl pÅ™esmÄ›rován na následující cíl? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. Pokud nechcete, aby jste zde byl neustále dotazován, musíte zmÄ›nit nastavení v sekci SIP protokol v uživatelském profilu. Redirecting request PÅ™esmÄ›rovat dotaz Do you allow the %1 request to be redirected to the following destination? Má být požadavek %1 pÅ™esmÄ›rován na následující destinaci? Transferring call PÅ™esmÄ›rování hovoru Request to transfer call received from: Požadavek na pÅ™esmÄ›rování hovoru pÅ™ijat od: Do you allow the call to be transferred to the following destination? Povolit pÅ™esmÄ›rování hovoru k následujícímu cíli? Info: Info: Warning: UpozornÄ›ní: Critical: Kritické: Firewall / NAT discovery... Firewall / NAT Analýza... Abort PÅ™eruÅ¡it Line %1 Linka %1 Click the padlock to confirm a correct SAS. Pro potvrzení správného SAS hesla kliknÄ›te na symbol zámeÄku. The remote user on line %1 disabled the encryption. protistrana na lince %1 vypnula zaÅ¡ifrování. Line %1: SAS confirmed. Linka %1: SAS potvrzeno. Line %1: SAS confirmation reset. Linka %1: SAS potvrzení smazáno. Line %1: call rejected. Linka %1: hovor odmítnut. Line %1: call redirected. Linka %1: Hovor pÅ™esmÄ›rován. Failed to start conference. NepodaÅ™ilo se otevřít konferenci. Override lock file and start anyway? Ignorovat blokovací soubor a pÅ™esto spustit? %1, STUN request failed: %2 %3 %1, STUN dotaz selhal: %2 %3 %1, STUN request failed. %1, STUN diatz selhal. %1, voice mail status failure. %1, Chyba stavu hlasové schránky. %1, voice mail status rejected. %1, odmítnut stav hlasové schránky. %1, voice mailbox does not exist. %1, hlasová schránka neexistuje. %1, voice mail status terminated. %1, ukonÄen pÅ™enos z hlasové schránky. %1, de-registration failed: %2 %3 %1, Neúspěšné odhlášení: %2 %3 Request to transfer call received. Protistrana si vyžádala pÅ™enos. If these are users for different domains, then enable the following option in your user profile (SIP protocol) Pokud jsou toto uživatelé pro různé domény, potom aktivujte následující volbu ve vaÅ¡em uživatelském profilu (SIP protocol) Use domain name to create a unique contact header Použijte doménové jméno k vytvoÅ™ení jedineÄné kontaktní hlaviÄky Failed to create a %1 socket (SIP) on port %2 Selhalo vytvoÅ™ení %1 socketu (SIP) na portu %2 Accepted by network Akceptováno sítí Failed to save message attachment: %1 Selhalo uložení přílohy zprávy: %1 Transferred by: %1 Cannot open web browser: %1 Configure your web browser in the system settings. GetAddressForm Twinkle - Select address Twinkle - VýbÄ›r adres Name Jméno Type Typ Phone Telefon &Show only SIP addresses Zobrazit pouze &SIP adresy Alt+S Alt+S Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". Pokud je aktivováno, budou zobrazeny pouze kontakty, které obsahují platnou SIP adresu (zaÄínající na <b>sip:</b>). &Reload Aktua&lizovat Alt+R Alt+R Reload the list of addresses from KAddressbook. Znovu naÄíst seznam adres z KAddressbook. ZavÅ™ení a opÄ›tovné otevÅ™ení okna <i>nevede</i> k novému naÄtení. ZmÄ›ny v adresáři budou v Twinkle viditelné až po aktivaci "Aktualizace". &OK &OK Alt+O Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C Alt+C &KAddressBook &KAddressBook This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. Tento seznam kontaktů pochází z <b>KAddressbook</b>. Kontakty, které neobsahují telefonní Äíslo nebo SIP adresu zde nejsou uvedeny. K vytvoÅ™ení nebo úpravÄ› kontaktů použijte program KAddressbook. &Local address book &Lokální adresář Remark Poznámka Contacts in the local address book of Twinkle. Kontakty v lokálním adresáři Twinkle. &Add &PÅ™idat Alt+A Alt+A Add a new contact to the local address book. Založit v lokálním adresáři nový kontakt. &Delete &Smazat Alt+D Alt+D Delete a contact from the local address book. Smazat vybraný kontakt z lokálního adresáře. &Edit &Upravit Alt+E Alt+E Edit a contact from the local address book. Upavit vybraný kontakt z lokálního adresáře. <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> Zdá se, že <p><b>KAddressbook</b> neobsahuje žádné záznamy s telefonními Äísly, které by Twinkle mohl naÄíst. Použijte prosím tento program k úpravÄ› nebo zanesení vaÅ¡ich kontaktů.</p> <p>Jako alternativa je vám k dispozici lokální adresář Twinkles, bez nutnosti mít výše jmenovaný program.</p> GetProfileNameForm Twinkle - Profile name Twinkle - Jméno uživatelského programu &OK &OK &Cancel ZruÅ¡it (Es&c) Enter a name for your profile: Vložte jméno pro nový profil: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> <b>Jméno pod kterým bude založen nový profil</b> <br><br> Profil obsahuje vÅ¡echna uživateslká nastavení jako je VoIP poskytovatel, uživatelské jméno SIP, Heslo atd. Pokus spustíte Twinkle bude zobrazen seznam vÅ¡ech profilů, ze kterého si lze vybrat ten se kterým má být pracováno. <br><br> Ke snadnému zapamatování si profilu je možné použít k oznaÄení profilu uživatelské jméno. NapÅ™. <b>example@example.com</b> <p>PÅ™ed založením prvního profilu je vhodné si nejprve vyřídit registraci u vaÅ¡eho SIP poskytovatele a poznaÄit si jaké <b>SIP přístupové parametry</b> jsou k pÅ™ihlášení potÅ™ebné. </p> Cannot find .twinkle directory in your home directory. Nelze najít adresář ".twinkle" ve vaÅ¡em domovském adresáři ("/home/vase-jmeno/"). Profile already exists. Profil s tímto jménem již existuje. Rename profile '%1' to: Profil "%1" pÅ™ejmenovat na: HistoryForm Twinkle - Call History Twinkle - Seznam volání Time ÄŒas In/Out Příchozí/Odchozí From/To Protistrana Subject PÅ™edmÄ›t Status Stav Call details Detaily hovoru Details of the selected call record. Detaily k vybranému hovoru. View Zobrazit &Incoming calls &Příchozí hovory Alt+I Alt+I Check this option to show incoming calls. ZaÅ¡krtnut tuto volbu, pokud mají být signalizovány příchozí hovory. &Outgoing calls &Odchozí hovory Alt+O Alt+O Check this option to show outgoing calls. Pokud je aktivováno, budou zobrazeny jen odchozí hovory. &Answered calls &PÅ™ijaté hovory Alt+A Alt+A Check this option to show answered calls. Pokud je aktivováno, budou zobrazeny jen pÅ™ijaté hovory. &Missed calls &ZmeÅ¡kaná volání Alt+M Alt+M Check this option to show missed calls. Pokud je aktivováno, budou zobrazeny jen zmeÅ¡kaná volání. Current &user profiles only &Pouze aktivní uživatelské profily Alt+U Alt+U Check this option to show only calls associated with this user profile. Pokud je aktivováno, budou zobrazeny jen hovory, které byly provedeny pod právÄ› aktivovním uživatelským profilem. C&lear &Smazat seznam Alt+L Alt+L <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> <p>Smazat celý protokol volání.</p> <p><b>Poznámka:</b> Tímto dojde ke smazání vÅ¡ech záznamů. VÄetnÄ› tÄ›ch, které nejsou zobrazeny dle zvolených parametrů v nastavení.</p> Alt+C Alt+C Close this window. Zavřít toto okno. Call start: Volání zahájeno: Call answer: Na volání odpovÄ›zeno: Call end: Hovor ukonÄen: Call duration: Délka hovoru: Direction: SmÄ›r: From: Od: To: Komu: Reply to: OdpovÄ›dÄ›t na: Referred by: PÅ™es: Subject: Název: Released by: UkonÄeno: Status: Status: Far end device: Zařízení protistrany: User profile: Uživatelský profil: conversation Rozhovor Call... Volat (dvojitý klik)... Delete Smazat záznam Re: Odp: Clo&se Za&vřít Alt+S Alt+S &Call &Volat Call selected address. Volat vybranou adresu. Number of calls: ### Total call duration: InviteForm Twinkle - Call Twinkle - Volání &To: Komu (&Telnr): Optionally you can provide a subject here. This might be shown to the callee. Zde můžete zadat nÄ›jaký název, který bude spolu s vaším jménem zobrazen na volané stanici. Address book Adresář Select an address from the address book. Vybrat adresu z KDE-Adressbook. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adresu, kterou chcete volat. Toto může být plnohodnotná SIP adresa jako napÅ™. <b>sip:example@example.com</b> nebo jen pouze telefonní Äíslo. Pokud není zadaná kompletní adresa twinkle ji doplní o doménové jméno aktuálního uživatelského profilu. The user that will make the call. Uživatelský profil a souÄasnÄ› i VoIP poskytovatel, se kterým bylo volání iniciováno. &Subject: &PÅ™edmÄ›t: &From: &Od: &OK &OK &Cancel ZruÅ¡it (Es&c) &Hide identity &skrýt identitu volajícího Alt+H Alt+H <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> <p>S touto volbou dáváte najevo vaÅ¡emu SIP poskytovateli, že nechcete aby byly na protistranu zaslánu informace o vaší identitÄ›. NapÅ™. vaÅ¡e SIP adresa nebo telefonná Äíslo. NicménÄ› vaÅ¡e IP adresa bude protistranÄ› <b>vždy</b> sdÄ›lena.</p> <p><b>UpozornÄ›ní: </b>Tuto možnost nenenabízejí vÅ¡ichni VoIP poskytovatelé!</p> Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. Ne vÅ¡ichni VoIP poskytovatelé umožňují skrytí identity. UjistÄ›te se o tom, pokud se na tuto funkci chcete spolehnout. F10 F10 LogViewForm Twinkle - Log Twinkle - Log Contents of the current log file (~/.twinkle/twinkle.log) Obsah aktuálního protokolovacího souboru (~/.twinkle/twinkle.log) &Close &Zavřít Alt+C Alt+C C&lear &Smazat Alt+L Alt+L Clear the log window. This does <b>not</b> clear the log file itself. Smazat protokolovací okno. Obsah samotného souboru s protokolem smazán <b>nebude</b>. MessageForm Twinkle - Instant message Twinkle - instantní zpráva &To: &Komu: The user that will send the message. Uživatel, který poÅ¡le zprávu. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adresa uživatele, kterému má být zpráva poslána. To může být buÄ SIP adresa, jako napÅ™. <b>sip:example@example.com</b> nebo telefonní Äíslo z kompletní adresy uživatele. Pokud se neuvede celá adresa, Twinkle doplni adresu hodnotou "Domain" z nastaveni uživatele v uživatelského profilu. Address book Adresář Select an address from the address book. VýbÄ›r adresy z adresáře. &User profile: &Uživatelský profil: Conversation Konverzace Type your message here and then press "send" to send it. Sem napsat zprávu a poté pro odeslání stisknout "Odeslat". &Send &Odeslat Alt+S Send the message. Odeslat zprávu. Delivery failure DoruÄení selhalo Delivery notification Potvrzení o doruÄení Instant message toolbar LiÅ¡ta s instantními zprávami Send file... Odeslat soubor... Send file Odeslat soubor image size is scaled down in preview obrázek je v náhledu zmenÅ¡en Open with %1... Otevřít s %1... Open with... Otevřít s... Save attachment as... Uložit přílohu jako... File already exists. Do you want to overwrite this file? Soubor již existuje. Chcete pÅ™epsat tento soubor? Failed to save attachment. Selhalo uložení přílohy. %1 is typing a message. %1 píše zprávu. F10 F10 Size MessageFormView sending message odesílání zprávy MphoneForm Twinkle Twinkle &Call: Label in front of combobox to enter address &Volané Äíslo: The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adresa protistrany, kterou chcete volat. Může to být kompletní SIP adresa ve formÄ› <b>sip:example@example.com</b> nebo také telefonní Äíslo, popÅ™. uživatelské Äást SIP adresy. Pokud není zadána celá adresa, twinkle doplní chybÄ›jící Äást doménovým jménem aktivního uživatelského profilu. The user that will make the call. Uživatel, který zahájí volání. &User: &Profil: Dial Volat Dial the address. Volat adresu. Address book Adresář Select an address from the address book. Vybrat volané Äíslo nebo SIP adresu z adresáře. Auto answer indication. Zobrazení a nastavení služby "Automatické pÅ™ijmutí hovoru". Call redirect indication. Zobrazení a nastavení služby "PÅ™esmÄ›rování hovoru". Do not disturb indication. Zobrazení a nastavení služby "NeruÅ¡it". Missed call indication. Zobrazení "Volání v nepřítomnosti" a otevÅ™ení seznamu volání. Registration status. Zobrazení stavu pÅ™ihlášení. Display Stavové hlášky Line status Stav linky Line &1: Linka &1: Alt+1 Alt+1 Click to switch to line 1. Zde kliknÄ›te pro pÅ™epnutí na linku 1. From: Od: To: Komu: Subject: PÅ™edmÄ›t: Visual indication of line state. Optické zobrazení stavu linky. idle No need to translate idle Call is on hold Hovor je podržen Voice is muted Hovor je ztiÅ¡en Conference call KonferenÄní hovor Transferring call Hovor bude pÅ™esmÄ›rován <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> <p> Symbol zámeÄku se zobrazí pokud je volání pÅ™enášeno pomocí Å¡ifrování a není možné ho odposlouchávat. </p> <h3>SAS - Short Authentication String</h3> <p> ObÄ›ma úÄastníkům zaÅ¡ifrovaného hovoru bude pÅ™i prvním kontaktu doruÄena tzv. SAS znaÄka. Porovnáním této znaÄky pÅ™i každém dalším volání s toutéž protistranou lze zjistit, v případÄ› že by se kód zmÄ›nil, že dochází k odposlouchávání hovoru. Å lo by o tzv. "man-in-the-middle attack". </p> <p> Pokud je SAS shodný na obou stranách, kliknÄ›te na ikonku zámeÄku. Lze se o tom pÅ™esvÄ›dÄit dotazem na tuto znaÄku u volaného. PÅ™i každém dalším volání na takto oznaÄený kontakt bude jeho identita automaticky ověřena a výsledek bude zobrazen ve formÄ› zatržítka na symbolu zámeÄku. </p> <p>OpÄ›tovným kliknutím na ikonku zámeÄku se zatržítkem dojde ke smazání ověřovací znaÄky SAS a k její nové aktivaci je nutné provést její nové vygenerování.</p> sas No need to translate sas Short authentication string SAS - znaÄka (Short authentication string) g711a/g711a No need to translate Audio codec Audio kodek 0:00:00 0:00:00 Call duration Doba trvání hovoru sip:from No need to translate sip:od sip:to No need to translate sip:komu subject No need to translate pÅ™edmÄ›t photo No need to translate foto Line &2: Linka &2: Alt+2 Alt+2 Click to switch to line 2. NakliknÄ›te k pÅ™epojení na linku 2 (nebo Alt+2). &File &Soubor &Edit &Upravit C&all &Hovor Activate line Vybrat linku &Registration &PÅ™ihlášení &Services &Služby &View &Zobrazit &Help &NápovÄ›da Call Toolbar LiÅ¡ta volání Quit UkonÄit &Quit &UkonÄit Ctrl+Q Ctrl+Q About Twinkle O programu Twinkle &About Twinkle O &programu Twinkle Call someone Volat - rozšířené zadávání Äísel F5 F5 Answer incoming call PÅ™ijmout příchozí hovor F6 F6 Release call UkonÄit hovor Reject incoming call Odmítnout příchozí hovor F8 F8 Put a call on hold, or retrieve a held call Podržet hovor nebo pokraÄovat v podrženém hovoru Redirect incoming call without answering PÅ™esmÄ›rovat příchozí hovor bez pÅ™ijmutí hovoru Open keypad to enter digits for voice menu's Otevřít numerickou klávesnici pro zadávání tónových příkazů (napÅ™. ovládání telefonních záznamníků) Register PÅ™ihlásit se &Register &PÅ™ihlásit se Deregister Odhlásit se &Deregister &Odhlásit se Deregister this device Odhlásit tento telefon Show registrations Zobrazit pÅ™ihlášení &Show registrations &Zobrazit pÅ™ihlášení Terminal capabilities Parametry protistrany Request terminal capabilities from someone Dotaz na parametry protistrany Do not disturb Prosím neruÅ¡it &Do not disturb &Prosím neruÅ¡it Call redirection PÅ™esmÄ›rování hovoru Call &redirection... &PÅ™esmÄ›rování hovoru... Repeat last call Opakované vytáÄení F12 F12 About Qt O prostÅ™edí Qt About &Qt O prostÅ™edí &Qt User profile Uživatelský profil &User profile... &Uživatelský profil... Join two calls in a 3-way conference PÅ™ipojit se ke konferenÄnímu hovoru 2 uživatelů Mute a call Vypnout/zapnout mikrofon Transfer call PÅ™esmÄ›rování hovoru System settings Systémová nastavení &System settings... &Systémová nastavení... Deregister all Odhlásit se od vÅ¡ech úÄtů Deregister &all &Odhlásit se od vÅ¡ech úÄtů Deregister all your registered devices Odhlásit vÅ¡echny zařízení pod tímto uživatelským profilem Auto answer Automaticky pÅ™ijmout volání &Auto answer &Automaticky pÅ™ijmout volání Log Protokol &Log... &Protokol... Call history Seznam vÅ¡ech volání Call &history... &Seznam vÅ¡ech volání... F9 F9 Change user ... ZmÄ›nit uživatelský profil ... &Change user ... &ZmÄ›nit uživatelský profil ... Activate or de-activate users Aktivovat/deaktivovat uživatelský profil What's This? Co je toto? What's &This? Co je &toto? Shift+F1 Shift+F1 Line 1 Linka 1 Line 2 Linka 2 idle volná dialing vytáÄení attempting call, please wait pokus o navázání spojení, prosím Äekejte incoming call Příchozí volání establishing call, please wait Pokus o spojení, prosím Äekejte established Spojení navázáno established (waiting for media) Spojení navázáno (Äeká se na data) releasing call, please wait Odpojení spojení, prosím Äekejte unknown state neznámý stav Voice is encrypted PÅ™enos hovoru je zaÅ¡ifrován Click to confirm SAS. Potvrdit znaÄku SAS. Click to clear SAS verification. Smazat SAS potvrzení. User: Uživatel: Call: Hovor: Registration status: Stav VOIP registrace: Registered Registrováno Failed NezdaÅ™ilo se Not registered Neregistrován No users are registered. NepÅ™ihlášen žádný uživatel. Do not disturb active for: "NeruÅ¡it" aktivováno pro: Redirection active for: PÅ™smÄ›rování aktivováno pro: Auto answer active for: "Automaticky pÅ™ijmout" aktivováno pro: Do not disturb is not active. "NeruÅ¡it" není aktivní. Redirection is not active. PÅ™esmÄ›rování volání není aktivováno. Auto answer is not active. "Automaticky pÅ™ijmout" není aktivováno. You have no missed calls. Žádná volání v nepřítomnosti. You missed 1 call. 1 zmeÅ¡kané volání v nepřítomnosti. You missed %1 calls. %1 volání v nepřítomnosti. Click to see call history for details. Kliknutím se otevÅ™e detailní záznam hovorů. Starting user profiles... Otevřít uživatelský profil... The following profiles are both for user %1 Následující uživatelské profily používají stejnou SIP adresu %1 You can only run multiple profiles for different users. Na jeden SIP úÄet je možné aktivovat pouze jeden uživatelský profil. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. Byl zmÄ›nÄ›n SIP UDP port. Toto nastavení bude aktivní až pÅ™i příštím spuÅ¡tÄ›ní programu Twinkle. Esc Esc Transfer consultation ZpÄ›tný dotaz Hide identity Skrýt identitu Click to show registrations. Kliknutím se zobrazí VOIP registrace. %1 new, 1 old message %1 nová, 1 stará zpráva %1 new, %2 old messages %1 nové, %2 staré zprávy 1 new message 1 nová zpráva %1 new messages %1 nových zpráv 1 old message 1 stará zpráva %1 old messages %1 starých zpráv Messages waiting PÅ™ijatých zpráv No messages Žádné zprávy <b>Voice mail status:</b> <b>Stav hlasové schránky:</b> Failure Chyba Unknown Neznámý Click to access voice mail. Kliknutím se vstoupí do hlasové schránky. Click to activate/deactivate Kliknutím aktivovat / deaktivovat Click to activate Kliknutím aktivovat not provisioned nezanesený You must provision your voice mail address in your user profile, before you can access it. PÅ™edtím než může být hlasová schránka používána, je nutné ji nastavit ve vaÅ¡em uživatelském profilu. The line is busy. Cannot access voice mail. Hlasovou schránku nelze otevřít - linka je obsazená. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Adresa hlasové schránky "%1" je neplatná. Zkontrolujte nastavení ve vaÅ¡em uživatelském profilu. Call toolbar text Volat &Call... call menu text Volat (&Call)... Answer toolbar text OdpovÄ›dÄ›t &Answer menu text &OdpovÄ›dÄ›t Bye toolbar text ZavÄ›sit &Bye menu text ZavÄ›sit (&Bye) Reject toolbar text Odmítnout &Reject menu text &Odmítnout Hold toolbar text Podržet &Hold menu text &Podržet Redirect toolbar text PÅ™esmÄ›rovat R&edirect... menu text &PÅ™esmÄ›rovat... Dtmf toolbar text DTMF &Dtmf... menu text &DTMF... &Terminal capabilities... menu text &Parametry protistrany... Redial toolbar text Opakovat &Redial menu text &Opakovat Conf toolbar text Konference &Conference menu text &Konference Mute toolbar text ZtiÅ¡it &Mute menu text &ZtiÅ¡it Xfer toolbar text ZprostÅ™edkovat Trans&fer... menu text &ZprostÅ™edkovat... Message waiting indication. Zobrazení Äekání na zprávu. Voice mail Hlasový záznamník &Voice mail &Hlasový záznamník Access voice mail Přístup na zvukový záznamník F11 Buddy list Buddy seznam &Message &Zpráva Msg Msg Instant &message... Instantní &zpráva... Instant message Instantní zpráva &Call... Volat (&Call)... &Edit... &Upravit... &Delete &Smazat O&ffline O&ffline &Online &Online &Change availability &ZmÄ›nit dostupnost &Add buddy... &PÅ™idat buddy... Failed to save buddy list: %1 Selhalo uložení seznamu s buddy: %1 You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. Je možné vytvoÅ™it oddÄ›lený buddy seznam pro každý uživatelský profil. Dostupnost vaších buddy a dostupnost vlastní lze zjistit a využívat jen pokud VoIP poskytovatel provozuje prezenÄní server. &Buddy list &Buddy seznam &Display &Stavové hlášky F10 F10 Diamondcard Manual &Manual Sign up &Sign up... Recharge... Balance history... Call history... Admin center... Recharge Balance history Admin center NumberConversionForm Twinkle - Number conversion Twinkle - konverze tel. Äísla &Match expression: &Hledaný výraz: &Replace: &Nahradit: Perl style format string for the replacement number. Perl formát Å™etÄ›zce pro nahrazované tel. Äíslo. Perl style regular expression matching the number format you want to modify. Regulární výraz (Perl regex) pro nahrazované tel. Äíslo. &OK Alt+O Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C Alt+C Match expression may not be empty. Hledaný výraz nesmí být prázdný. Replace value may not be empty. Nahrazovaná hodnota nesmí být prázdná. Invalid regular expression. Neplatný regulární výraz. RedirectForm Twinkle - Redirect Twinkle - PÅ™esmÄ›rování volání Redirect incoming call to Příchozí hovor pÅ™emÄ›rovat na You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Pro pÅ™esmÄ›rování volání lze zadat max. 3 Äísla. Pokud nebude hovor pÅ™ijat prvním cílem, dojde k pokusu o pÅ™esmÄ›rování na druhý cíl atd. &3rd choice destination: &3. Cíl: &2nd choice destination: &2. Cíl: &1st choice destination: &1. Cíl: Address book Adresář Select an address from the address book. Vybrat tel. Äíslo / SIP adresu z adresáře. &OK &Cancel ZruÅ¡it (Es&c) F10 F10 F12 F12 F11 F11 SelectNicForm Twinkle - Select NIC Twinkle - výbÄ›r síťového pÅ™ipojení Select the network interface/IP address that you want to use: Vyberte síťové rozhraní / IP adresu, kterou chcete použít: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. Na vaÅ¡em poÄítaÄi je k dispozici více IP adres. Vyberte tu, pod kterou je váš poÄítaÄ dostupný z internetu nebo pokud jste pÅ™ipojení na router vaÅ¡i IP adresu v lokální síti. Tuto adresu bude Twinkle používat uvnitÅ™ datových SIP paketů jako adresu odesilatele. Set as default &IP &Nastavit jako standardní IP adresu Alt+I Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Nastavit vybranou IP Adresu jako standardní. PÅ™i přístím startu Twinkle bude zvolena automaticky tato adresa. Set as default &NIC Nastavit jako &standardní pÅ™ipojení Alt+N Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. Nastavit vybrané síťové rozhraní jako standardní. PÅ™i příštím startu Twinkle bude toto rozhraní automaticky zvoleno. &OK Alt+O Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. Standardní nastavení je možné zmÄ›nit kdykoliv pozdÄ›ji v konfiguraci systému. SelectProfileForm Twinkle - Select user profile Twinkle - výbÄ›r uživatelského profilu Select user profile(s) to run: VýbÄ›r uživatelského profilu (popÅ™. profilů), které mají být aktivovány: User profile Uživatelský profil Tick the check boxes of the user profiles that you want to run and press run. OznaÄte uživatelský profil, se kterým by mÄ›l Twinkle pracovat a stisknÄ›te potom "Použít". &New &nový Create a new profile with the profile editor. Pomocí editoru profilu založit nový uživatelský profil. &Wizard &Wizard Alt+W Create a new profile with the wizard. Pomocí wizardu založit nový uživatelský profil. &Edit U&pravit Alt+E Edit the highlighted profile. Upravit vybraný uživatelský profil. &Delete &Smazat Alt+D Alt+L Delete the highlighted profile. Smazat vybraný uživatelský profil. Ren&ame &PÅ™ejmenovat Alt+A Alt+U Rename the highlighted profile. Das ausgewählte Benutzerprofil umbenennen. &Set as default Nastavit jako &výchozí Alt+S Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. Použít vybrané profily jako standardní. Twinkle je použije automaticky pÅ™i příštím startu. &Run &Spustit Alt+R Run Twinkle with the selected profiles. Spustit twinkle s oznaÄenými uživatelskými profily. S&ystem settings S&ystémová nastavení Alt+Y Edit the system settings. Upravit systémová nastavení. &Cancel ZruÅ¡it (Es&c) Alt+C <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> <html>PÅ™edtím než můžete Twinkle zaÄít používat, musíte založit aspoň jeden uživatelský profil.<br>KliknÄ›te OK pro založení nového profilu.</html> <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>Choose what method you wish to use.</html> <html>Pro vytvoÅ™ení uživatelského profilu můžete použít editor profilu. Tento vám umožní zmÄ›nit veÅ¡kerá nastavení týkající se SIP protokolu, RTP jakož i dalších parametrů programu.<br><br>PopřípadÄ› použijte Wizard pro rychlé a jednoduché nastavení základních paramtrů ke zvolenému uživatelskému profilu. Wizard se vás dotáže jen na nejzákladnÄ›jší údaje, které vám váš SIP poskytovatel dá pÅ™i zaregistrování. Pro nÄ›které poskytovatele vám budou dokonce nÄ›které z tÄ›chto údajů přímo wizardem nabídnuty. I pÅ™esto, že profil založíte pomocí wizardu ho budete moci pozdÄ›ji upravovat pomocí editoru.<br><br>NápovÄ›du získáte kdekoliv v Twinkle stiskem klávesové ombinace "Shift + F1", pÅ™es kontextovou nápovÄ›du pomocí stisku pravého tlaÄítka na myÅ¡i nebo stiskem na symbol "?" v pravém horním rohu okna.<br><br>Vyberte si jakým způsobem má být uživatelský profil založen.</html> <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> <html>V dalším kroku byste si mÄ›li pÅ™ekontrolovat a popřípadÄ› upravit systémová nastavení. ObzvláštÄ› potom, zda-li v oblasti Audio je v pořádku nastavení mikrofonu a reproduktorů.<br><br>KliknÄ›te na OK pro přístup k systémovým nastavením. Systémová nastavení můžete upravit i kdykoliv pozdÄ›ji.</html> You did not select any user profile to run. Please select a profile. Nevybrali jste k použití žádný uživatelský profil. Vyberte prosím aspoň jeden profil. Are you sure you want to delete profile '%1'? Opravdu smazat uživatelský profil %1 ? Delete profile Smazat uživatelský profil Failed to delete profile. Chyba pÅ™i mazání uživatelského profilu. Failed to rename profile. Chyba pÅ™i pÅ™ejmenování uživatelského profilu. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> <p>Standardní nastavení je možné kdykoliv smazat nebo zmÄ›nit v systémovém nastavení. </p> Cannot find .twinkle directory in your home directory. Nelze nalézt skrytý adresář ".twinkle" ve vaÅ¡em domovském adresáři ("/home/vasejmeno/") . &Profile editor &Editor profilu Create profile Ed&itor Alt+I Dia&mondcard Alt+M Modify profile Startup profile &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> SelectUserForm Twinkle - Select user Twinkle - VýbÄ›r uživatelského profilu &Cancel ZruÅ¡it (Es&c) Alt+C Alt+C &Select all Vybrat &vÅ¡e Alt+S Alt+S &OK Alt+O Alt+O C&lear all Vybrat &vÅ¡e Alt+L Alt+L purpose No need to translate User Uživatel Register PÅ™ihlásit se Select users that you want to register. Vybrat uživatelský profil k pÅ™ihlášení. Deregister Odhlásit Select users that you want to deregister. Vybrat uživatelský profil k odhlášení. Deregister all devices Odhlásit vÅ¡echny zařízení Select users for which you want to deregister all devices. Vybrat uživatelský profil od nÄ›hož mají být odhlášena vÅ¡echna zařízení. Do not disturb Prosím neruÅ¡it Select users for which you want to enable 'do not disturb'. Vybrat uživatelský profil, pro který má být aktivován režim "NeruÅ¡it". Auto answer Automaticky pÅ™ijmout volání Select users for which you want to enable 'auto answer'. Vybrat uživatelský profil, pro který má být aktivován režim "Automaticky vzít volání". SendFileForm Twinkle - Send File Twinkle - Odeslat soubor Select file to send. VýbÄ›r souboru k odeslání. &File: &Soubor: &Subject: &PÅ™edmÄ›t: &OK &OK Alt+O Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C Alt+C File does not exist. Soubor neexistuje. Send file... Odeslat soubor... SrvRedirectForm Twinkle - Call Redirection Twinkle - PÅ™esmÄ›rování hovoru User: Uživatel: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> Existují 3 způsoby pÅ™esmÄ›rování volání:<p> <b>Trvale:</b> pÅ™esmÄ›rovat vÅ¡echny hovory </p> <p> <b>Obsazeno:</b> PÅ™esmÄ›rovat hovor, pokud jsou obÄ› linky obsazené </p> <p> <b>Žádná odpovÄ›Ä:</b> PÅ™esmÄ›rovat volání po uplynutí Äekací prodlevy </p> &Unconditional &Trvale &Redirect all calls &PÅ™esmÄ›rovat vÅ¡echna volání Alt+R Alt-R Activate the unconditional redirection service. Aktivovat službu "pÅ™esmÄ›rovat vÅ¡echna volání". Redirect to PÅ™esmÄ›rovat na You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Mohou být zadány až 3 cíle pro pÅ™esmÄ›rování volání. Pokud nebude hovor pÅ™ebrán prvním cílem, bude použit druhý, popřípadÄ› tÅ™etí. &3rd choice destination: &3. Cíl: &2nd choice destination: &2. Cíl: &1st choice destination: &1. Cíl: Address book Adresář Select an address from the address book. Vybrat z adresáře volané Äíslo / SIP adresu. &Busy &Obsazeno &Redirect calls when I am busy &PÅ™esmÄ›rovat volání, pokud jsou vÅ¡echny linky obsazené Activate the redirection when busy service. Aktivovat pÅ™esmÄ›rovaní, pokud je linka nedostupná. &No answer &Žádná odpovÄ›Ä &Redirect calls when I do not answer &PÅ™esmÄ›rovat volání, pokud uživatel neodpovídá Activate the redirection on no answer service. Aktivovat službu "PÅ™esmÄ›rovat v nepřítomnosti". &OK Alt+O Accept and save all changes. Uložit zmÄ›ny. &Cancel ZruÅ¡it (Es&c) Alt+C Undo your changes and close the window. Neukládat provedené zmÄ›ny a zavřít okno. You have entered an invalid destination. Neplatná cílová adresa. F10 F10 F11 F11 F12 F12 SysSettingsForm Twinkle - System Settings Twinkle - Systémová nastavení General Obecné Audio Audio Ring tones VyzvánÄ›cí tóny Address book Adresář Network Síť Log Log Select a category for which you want to see or modify the settings. Vybrat skupinu vlastností u které chcete zmÄ›nit nastavení. Sound Card Zvuková karta Select the sound card for playing the ring tone for incoming calls. Vybrat audio pÅ™ipojení pro pÅ™ehrávání vyzvánÄ›cího tónu příchozího volání. Select the sound card to which your microphone is connected. Vybrat audio pÅ™ipojení pro mikrofon. Select the sound card for the speaker function during a call. Vybrat audio pÅ™ipojení pro sluchátka/reproduktoru. Může být shodné s audio pÅ™ipojením pro vyzvánÄ›cí tón. &Speaker: &Sluchátka/Reproduktor: &Ring tone: &VyzvánÄ›cí tón: Other device: Jiné pÅ™ipojení: &Microphone: &Mikrofon: When using ALSA, it is not recommended to use the default device for the microphone as it gives poor sound quality. PÅ™i použítí ALSA rozhraní není doporuÄeno mít nastaveno pro mikrofon "standardní zařízení". Může to být příÄinou Å¡patné kvality zvuku. Reduce &noise from the microphone Speciální potlaÄení &ruÅ¡ení z mikrofonu Recordings from the microphone can contain noise. This could be annoying to the person on the other side of your call. This option removes soft noise coming from the microphone. The noise reduction algorithm is very simplistic. Sound is captured as 16 bits signed linear PCM samples. All samples between -50 and 50 are truncated to 0. Zvuk z mikrofonu může obsahovat ruÅ¡ení. Tato volba se ho snaží odstranit. Zavedena byla po zkuÅ¡enosti s vadnými A/D pÅ™evodníky u nÄ›kterých Provider Gateways. Algoritmus je velmi jednoduchý. Zvuk je navzorkován jako 16 bitový PCM vzorek a poté jsou vÅ¡echny vzorky s hodnotou mezi -50 až 50 nastaveny na 0. Advanced PokroÄilé nastavení OSS &fragment size: Velikost OSS &fragmentů: 16 32 64 128 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. ALSA play perioda ovlivňuje zjednoduÅ¡enÄ› Å™eÄeno velikost paketů, pomocí kterých jsou posílána data na zvukovou kartu. HodnÄ› malých paketů zatěžuje více procesor, ale ztráta nÄ›jakého paketu není tolik vážná. PÅ™i problémech s vypadáváním nebo pÅ™eskakováním zvuku je možné zaexperimentovat s jinými hodnotami. ALSA &play period size: Velikost ALSA &play (LS) periody: &ALSA capture period size: Velikost &ALSA capture (MIC) periody: The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. OSS fragment size ovlivňuje zjednoduÅ¡enÄ› Å™eÄeno velikost paketů, pomocí kterých jsou posílána data na zvukovou kartu. HodnÄ› malých paketů zatěžuje více procesor, ale ztráta nÄ›jakého paketu není tolik vážná. PÅ™i problémech s vypadáváním nebo pÅ™eskakováním zvuku je možnÄ› zaexperimentovat s jinými hodnotami. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. Velikost capture periody ovlivňuje zjednoduÅ¡enÄ› Å™eÄeno velikost paketů, pomocí kterých jsou posílána data na zvukovou kartu. HodnÄ› malých paketů zatěžuje více procesor, ale ztráta nÄ›jakého paketu není tolik vážná. PÅ™i problémech s vypadáváním nebo pÅ™eskakováním zvuku je možnÄ› zaexperimentovat s jinými hodnotami. &Max log size: &Maximální velikost systémového logu: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. Systémový log je používán experty pro hledání problémů. Zde je možné nastavit jeho maximální velikost. PÅ™i dosažení logu této velikosti je twinkle.log pÅ™ejmenováno na twinkle.old Pokud již soubor twinkle.old existuje, je pÅ™epsán. MB Log &debug reports Zapsat i '&debug' hlášky Alt+D Indicates if reports marked as "debug" will be logged. Aktivuje zápis "debug" výstupů. Log &SIP reports Zapsat &SIP hlášky Alt+S Indicates if SIP messages will be logged. Aktivuje zápis SIP stavů. Log S&TUN reports Zapsat S&TUN hlášky Alt+T Indicates if STUN messages will be logged. Aktivuje zápis STUN stavů. Log m&emory reports Zapsat hlášky ohl&ednÄ› pamÄ›ti Alt+E Indicates if reports concerning memory management will be logged. Aktivuje zápis protokolů o pÅ™idÄ›lení/uvolnÄ›ní RAM pamÄ›ti. System tray Systémová liÅ¡ta Create &system tray icon on startup PÅ™i spuÅ¡tÄ›ní vytvoÅ™it &ikonku v systémové liÅ¡tÄ› Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. S touto volbou vytvoří Twinkle pÅ™i startu v systémové liÅ¡tÄ› symbol hvÄ›zdiÄky. PÅ™es tento lze kdykoliv program vyvolat do popÅ™edí. Rovněž je pÅ™es jeho vzhled signalizován aktuální stav telefonní linky. &Hide in system tray when closing main window PÅ™esunout do systémové liÅ¡ty pÅ™i zavÅ™ení &hlavního okna programu Alt+H Enable this option if you want Twinkle to hide in the system tray when you close the main window. Pokud je aktivováno, je twinkle pÅ™i zavÅ™ení hlavního okna pÅ™esunuto do systémové liÅ¡ty. K úplnému ukonÄení programu je nutné vybrat volbu "ukonÄit" v menu "Soubor" nebo v kontextovém menu symbolu Twinkle v systémové liÅ¡tÄ›. Startup Start programu Next time you start Twinkle, this IP address will be automatically selected. This is only useful when your computer has multiple and static IP addresses. Zde uvedená IP adresa bude automaticky vybrána pÅ™i příštím startu programu. To má smysl jen pokud má tento poÄítaÄ vícero síťových pÅ™ipojení a jen jedno je s přístupem do internetu. Default &IP address: Standardní &IP adresa: Next time you start Twinkle, the IP address of this network interface be automatically selected. This is only useful when your computer has multiple network devices. Pokud má tento poÄítaÄ vícero síťových pÅ™ipojení, je zde možné uvést, které má být zvoleno. PÅ™i příštím startu programu již na toto nebude dotazováno. Default &network interface: Standardní síťové &rozhraní: S&tartup hidden in system tray Spustit zminimalizované do &systémové liÅ¡ty Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. PÅ™i startu Twinkle neotevírat hlavní okno, nýbrž spustit zminimalizované do systémové liÅ¡ty. MÄ›l by být rovněž pÅ™ednastaven standarní profil, jinak dojde k vyvolání okna s výbÄ›rem profilu. Default user profiles Standardní uživatelský profil If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. Zde nastavené uživatelské profily budou pÅ™i startu programu automaticky aktivovány. Kdykoliv je můžete pÅ™es "Soubor" -> "ZmÄ›nit uživatelské profily" aktivovat nebo deaktivovat. Services Služby Call &waiting Detekce &příchozího hovoru Alt+W With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. Pokud je aktivována funkce "Detekce příchozího hovoru", může být v případÄ› obsazené linky volání pÅ™esmÄ›rováno na druhou linku. Pokud je funkce deaktivována, je volajícímu signalizováno "obsazeno". Hang up &both lines when ending a 3-way conference call. PÅ™i ukonÄení konferenÄního hovoru budou &obÄ› linky "zavěšeny". Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. Pokud je aktivováno budou pÅ™i "zavěšení" odpojeny obÄ› linky. Jinak dojde jen k ukonÄení volání na aktivní lince a je možné pokraÄovat v hovoru na druhé lince. &Maximum calls in call history: &Maximální poÄet záznamů v seznamu volání: The maximum number of calls that will be kept in the call history. Délka seznamu volání bude omezena na zde zadaný poÄet záznamů. Starší záznamy budou automaticky odstranÄ›ny. &Auto show main window on incoming call after PÅ™i hovoru &otevřít automaticky hlavní okno Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Pokud je hlavní okno programu skryto, bude pÅ™i příchozím hovoru po zadaném poÄtu sekund zobrazeno do popÅ™edí. Number of seconds after which the main window should be shown. ÄŒas v sekundách po kterém bude hlavní okno programu obnoveno do popÅ™edí. secs Sekund The UDP port used for sending and receiving SIP messages. UDP Port pro SIP Protokoll. StandardnÄ› je to 5060. NicménÄ› váš VoIP provider může vyžadovat jiný port. &RTP port: &RTP port: The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. První port pÅ™es který běží datový pÅ™enos hovoru. SouÄasnÄ› vedený hovor na druhé lince používá port o 2 Äísla vyšší. ZprostÅ™edkování hovoru potom další 2 porty. NapÅ™. 1. linka: 8000(+8001), 2. linka: 8002(+8003), ZprostÅ™edkování: 8004(+8005). StandardnÄ› je to vÄ›tÅ¡inou 8000 nebo 5004. Je to vÅ¡ak závislé od konkrétního poskytovatele VoIP pÅ™ipojení. PÅ™i vÄ›tším množství SIP telefonů pÅ™ipojených na jedno internetové pÅ™ipojení, potÅ™ebuje každý vyhrazenou vlastní skupinu portů! Tedy druhý telefon napÅ™. 8006 a výše. &SIP UDP port: &SIP UDP port: Ring tone VyzvánÄ›cí tón &Play ring tone on incoming call PÅ™i příchozím volání &spustit vyzvánÄ›cí tón Alt+P Indicates if a ring tone should be played when a call comes in. Pokud je aktivováno, spustí Twinkle pÅ™i příchozím volání vyzvánÄ›cí tón pÅ™es pÅ™ednastavené audio pÅ™ipojení. &Default ring tone &Standardní vyzvánÄ›cí tón Play the default ring tone when a call comes in. Spustí standardní vyzvánÄ›cí tón pÅ™i příchozím volání. C&ustom ring tone individuální vyzvánÄ›cí &tón Alt+U Play a custom ring tone when a call comes in. PÅ™i příchozím volání pÅ™ehrávat vlastní vyzvánÄ›cí tón. Specify the file name of a .wav file that you want to be played as ring tone. Zadejte jméno .wav souboru pro vlastní vyzvánÄ›cí tón. Ring back tone Tón pro signalizaci vyzvánÄ›ní u volaného P&lay ring back tone when network does not play ring back tone PÅ™ehrát tón pro &vyzvánÄ›ní u volaného, pokud telefonní síť žádný tón neposkytuje Alt+L <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> <p>PÅ™ehrát tón pro vyzvánÄ›ní u volaného, pokud telefonní síť žádný takový tón neposkytuje.</p> <p>Tento tón je závislý od vaÅ¡eho SIP poskytovatele.</p> D&efault ring back tone &Standardní tón pro vyzvánÄ›ní u volaného Play the default ring back tone. PÅ™ehrávat standardní tón vyzvánÄ›ní u volaného. Cu&stom ring back tone &Individuální tón vyzvánÄ›ní u volaného Play a custom ring back tone. Použít individuální vyzvánÄ›cí tón u volaného. Specify the file name of a .wav file that you want to be played as ring back tone. Zadat jméno .wav souboru pro váš indiviuální tón vyzvánÄ›ní u volaného. &Lookup name for incoming call Podle Äísla &zjistit volajícího Ove&rride received display name &PÅ™episovat jméno volajícího Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. Volající protistrana může posílat vlastní jméno. PÅ™i aktivaci této volby bude zobrazované jméno vzato z vaÅ¡eho lokálního adresáře. Lookup &photo for incoming call Hledat &fotografii volajícího Lookup the photo of a caller in your address book and display it on an incoming call. Hledat fotografii ve vaÅ¡em lokálním adresáři a zobrazit pÅ™i příchozím volání. &OK Alt+O Accept and save your changes. PÅ™evzít zmÄ›ny a uložit. &Cancel ZruÅ¡it (Es&c) Alt+C Undo all your changes and close the window. Vrátit zpÄ›t vÅ¡echny zmÄ›ny a uzavřít. none This is the 'none' in default IP address combo auto none This is the 'none' in default network interface combo auto Either choose a default IP address or a default network interface. Vybrat buÄ standardní IP adresu nebo standardní síťové rozhraní. Ring tones Description of .wav files in file dialog VyzvánÄ›cí tóny Choose ring tone Vybrat vyzvánÄ›cí tón Ring back tones Description of .wav files in file dialog Tón vyzvánÄ›ní u volaného Choose ring back tone Vybrat tón pro signalizaci volné linky &Validate devices before usage Ověřit audio nasta&vení pÅ™ed prvním použití Alt+V Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. <p>Pokud je aktivováno, Twinkle pÅ™i startu zkontroluje zdali je zadané audio zařízení přístupné.</p> <p>Pokud se zdá, že mikrofon nebo reproduktory/sluchátko nejsou v pořádku, bude zobrazeno varovné hlášení a žádné volání nebude dovoleno.</p> <p>Rovněž v případÄ›, že je detekováno příchozí volání a audio zařízení není v pořádku, zobrazí se varování a hovor nebude možné pÅ™ijmout. On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. PÅ™i příchozím volání se Twinkle bude pokouÅ¡et najít k volajícímu v lokálním adresáři odpovídající záznam. Pokud se to podaří, bude jeho jméno zobrazeno. Select ring tone file. VýbÄ›r souboru s vyzvánÄ›cím tónem. Select ring back tone file. VýbÄ›r souboru pro vyzvánÄ›cí tón u protistrany. Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. MaximálnÄ› povolená velikost příchozí SIP zprávy pÅ™es UDP, v Bajtech (0-65535). &SIP port: &SIP port: Max. SIP message size (&TCP): Max. velikost SIP zprávy (&TCP): The UDP/TCP port used for sending and receiving SIP messages. UDP/TCP port použitý pro odesílání a pÅ™ijímání SIP zpráv. Max. SIP message size (&UDP): Max. velikost SIP zprávy (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. MaximálnÄ› povolená velikost příchozí SIP zprávy pÅ™es TCP, v Bajtech (0-4294967295). W&eb browser command: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. SysTrayPopup Answer PÅ™ijmout Reject Odmítnout Incoming Call TermCapForm Twinkle - Terminal Capabilities Twinkle - parametry protistrany &From: &Od: Get terminal capabilities of Dotázat se na parametry následující protistrany &To: &Adresa: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adresa nebo Äíslo protistrany jejíž parametry se mají zjistit (OPTION request). Může to být kompletní SIP adresa ve formátu <b>sip:example@example.com</b> nebo jen telefonní Äíslo celé adresy. Pokud není adresa kompletní, Twinkle doplní jméno domény podle standardního uživatelského profilu. Address book Adresář Select an address from the address book. Vybrat z adresáře volané Äíslo nebo SIP adresu. &OK &Cancel ZruÅ¡it (Es&c) F10 F10 TransferForm Twinkle - Transfer Twinkle - pÅ™evedení Transfer call to PÅ™evést hovor na &To: &Na: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adresa nebo Äíslo protistrany, na které má být hovor pÅ™esmÄ›rován. Může to být kompletní SIP adresa jako napÅ™. <b>sip:example@example.com</b> nebo jen telefonní Äíslo. Pokud není zadána plná SIP adresa, Twinkle doplní adresu jménem domény aktivního uživatelského profilu. Address book Adresář Select an address from the address book. Vybrat z adresáře volané Äíslo nebo SIP adresu. &OK Alt+O &Cancel ZruÅ¡it (Es&c) Type of transfer Typ pÅ™esmÄ›rování &Blind transfer &Bez zpÄ›tného pÅ™esmÄ›rování Alt+B Transfer the call to a third party without contacting that third party yourself. Hovor přímo pÅ™esmÄ›rovat na nového úÄastníka, aniž by bylo nutné ho nejdříve kontaktovat. T&ransfer with consultation PÅ™esmÄ›rovat se &zpÄ›tným dotazem Alt+R Before transferring the call to a third party, first consult the party yourself. PÅ™ed pÅ™esmÄ›rováním hovoru nejprve kontaktovat nového úÄastníka a volajícího ohlásit. Transfer to other &line PÅ™esmÄ›rovat na jinou &linku Alt+L Connect the remote party on the active line with the remote party on the other line. Propojit obÄ› protistrany na lince 1 a 2. Protistrana, která je právÄ› na aktivní lince bude ta, která bude hovor pÅ™esmÄ›rovat. F10 F10 TwinkleCore Failed to create log file %1 . Chyba pÅ™i vytvoÅ™ení logového souboru "%1". Cannot open file for reading: %1 Nelze otevřít ke Ätení soubor "%1" File system error while reading file %1 . Systémová chyba pÅ™i Ätení souboru "%1". Cannot open file for writing: %1 Nelze otevřít k zápisu soubor "%1" File system error while writing file %1 . Systémová chyba pÅ™i zápisu do "%1". Excessive number of socket errors. PříliÅ¡ velký poÄet socketových chyb. Built with support for: VytvoÅ™eno s podporou pro: Contributions: Pomocní vývojáři: This software contains the following software from 3rd parties: Tento program obsahuje softwarové Äásti tÄ›chto tÅ™etích stran: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * GSM kodek od Jutta Degener a Carsten Bormann, University of Berlin * G.711/G.726 codecs from Sun Microsystems (public domain) * G.711/G.726 kodeky od Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * iLBC implementace RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * Části ze STUN projektu na http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ * Části z libsrv na http://libsrv.sourceforge.net/ For RTP the following dynamic libraries are linked: Pro RTP jsou linkovány následující dynamické knihovny: Translated to english by <your name> ÄŒeský pÅ™eklad vypracoval Marek Straka, ©20090701, (http://marek.straka.info) Directory %1 does not exist. Složka "%1" nenalezena. Cannot open file %1 . Soubor "%1" nelze otevřít. %1 is not set to your home directory. "%1" neukazuje na vaÅ¡i domovskou složku. Directory %1 (%2) does not exist. Složka "%1" (%2) neexistuje. Cannot create directory %1 . Složku "%1" nelze vytvoÅ™it. Lock file %1 already exist, but cannot be opened. Zamykací soubor "%1" již existuje, ale nemůže být otevÅ™en. %1 is already running. Lock file %2 already exists. "%1" již běží. Zamykací soubor "%2" již existuje. Cannot create %1 . Nelze vytvoÅ™it "%1" . Cannot write to %1 . Nelze zapisovat do "%1". Syntax error in file %1 . Syntaktická chyba v souboru "%1" . Failed to backup %1 to %2 Chyba pÅ™i záloze z "%1" do "%2" unknown name (device is busy) Neznámé zařízení nebo je již obsazené Default device Standardní zařízení Anonymous Anonymní Warning: UpozornÄ›ní: Call transfer - %1 PÅ™esmÄ›rování - %1 Sound card cannot be set to full duplex. Audio zařízení nelze nastavit na "voll duplex". Cannot set buffer size on sound card. Nelze nastavit velikost bufferu na zvukové kartÄ›. Sound card cannot be set to %1 channels. Zvukové zařízení neze nastavit na %1 kanálů. Cannot set sound card to 16 bits recording. Audio zařízení nelze nastavit na 16 bitový záznam. Cannot set sound card to 16 bits playing. Audio zařízení nelze nastavit na 16 bitové pÅ™ehrávání. Cannot set sound card sample rate to %1 Nelze nastavit vzorkovací frekvenci audio zařízení na %1 Opening ALSA driver failed Chyba pÅ™i otevírání ALSA ovladaÄů Cannot open ALSA driver for PCM playback Nelze otevřít ALSA ovladaÄ pro PCM pÅ™ehrávání Cannot resolve STUN server: %1 Nelze identifikovat URL STUN serveru: %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. Nacházíte se za "symetric NAT". STUN nebude fungovat. Je nutné nastavit v uživatelském profilu veÅ™ejnÄ› dostupnou IP adresu a na vaÅ¡em routeru/firewallu/NATu vytvoÅ™it veÅ™ejnÄ› přístupné porty nasmÄ›rované na lokální porty na vaÅ¡em poÄítaÄi. public IP: %1 --> private IP: %2 (SIP signaling) veÅ™ejná IP: %1 --> privátní IP: %2 (SIP Protokol) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) VeÅ™ejná IP: %1 - %2 --> privátní IP: %3 - %4 (RTP/RTCP) Cannot reach the STUN server: %1 Nelze pÅ™ipojit na STUN server: "%1" Port %1 (SIP signaling) Port %1 (SIP Protokol) NAT type discovery via STUN failed. Analýza NAT pomocí STUN selhala. If you are behind a firewall then you need to open the following UDP ports. Pokud se nacházíte za firewallem, je nutné otevřít následující UDP porty. Ports %1-%2 (RTP/RTCP) Porty %1-%2 (RTP/RTCP) Cannot access the ring tone device (%1). Audio zařízení "%1" pro vyzvánÄ›cí tón není přístupné. Cannot access the speaker (%1). Audio zařízení "%1" pro reproduktory/sluchátka není přístupné. Cannot access the microphone (%1). Audio zařízení "%1" pro mikrofon není přístupné. Cannot open ALSA driver for PCM capture Nelze otevřít ALSA ovladaÄ pro PCM nahrávání Cannot receive incoming TCP connections. Nelze pÅ™ijmout příchozí TCP spojení. Failed to create file %1 selhalo vytvoÅ™ení souboru %1 Failed to write data to file %1 Selhal zápis dat do souboru %1 Failed to send message. Selhalo odeslání zprávy. Cannot lock %1 . UserProfileForm Twinkle - User Profile Twinkle - uživatelský profil User profile: Uživatelský profil: Select which profile you want to edit. Vybrat profil k úpravÄ›. User Uživatel SIP server SIP Server RTP audio RTP Audio SIP protocol SIP protokol NAT NAT (pÅ™eklad adres) Address format Formát adresy Timers ÄŒasovaÄ Ring tones VyzvánÄ›cí tóny Scripts Skripty Security ZabezpeÄení Select a category for which you want to see or modify the settings. Vybrat oblast, ve které mají být provedeny zmÄ›ny nastavení. &OK Alt+O Accept and save your changes. Akceptovat a uložit zmÄ›ny v nastavení. &Cancel ZruÅ¡it (Es&c) Alt+C Undo all your changes and close the window. Vrátit zpÄ›t vÅ¡echny zmÄ›ny a zavřít okno. SIP account Údaje SIP úÄtu &User name*: Uživatelské &jméno *: &Domain*: Or&ganization: Or&ganizace: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. Uživatelské jméno, které vám bylo pÅ™idÄ›leno vaším VoIP poskytovatelem. Je první Äástí vaší kompletní SIP adresy <b>uzivatel</b>@domain.com Mnozí VoIP poskytovatelé toto oznaÄují jako telefonní Äíslo. <br><br> *ÚDAJE V TOMTO ŘÃDKU JSOU POVINNÉ. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Doména nebo IP adresa, pod kterou jste vedeni u vaÅ¡eho VoIP poskytovatele, popÅ™. dosažitelný v internetu. Je to druhá Äást vaší kompletní SIP adresy uzivatel@<b>domain.com</b>, popÅ™. doména vaší SIP proxy. U mnohých VoIP poskytovatelů je totožná s doménou poskytovatele. Pro přímé propojení IP-to-IP se zde uvede jméno nebo IP, pod kterým je váš poÄítaÄ dosažitelný v internetu. <br><br> *ÚDAJE V TOMTO ŘÃDKU JSOU POVINNÉ. You may fill in the name of your organization. When you make a call, this might be shown to the called party. Zde je možné uvést jméno vaší organizace. Pokud nÄ›komu voláte, může být tento údaj zobrazen protistranÄ›. Není bezpodmíneÄnÄ› nutné. VyhnÄ›te se písmenům s diakritikou. NÄ›které VoIP přístroje s tím mohou mít problémy. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. VaÅ¡e jméno nebo pÅ™ezdívka. Tato položka je volané protistranÄ› zobrazována jako jméno volajícího. Údaj není nutný. VyhnÄ›te se používání písmen s diakritrikou. NÄ›které VoIP přístroje s tím mohou mít problémy. &Your name: &Jméno: SIP authentication SIP pÅ™ihlaÅ¡ovací údaje &Realm: Authentication &name: PÅ™ihlaÅ¡ovací &jméno: &Password: &Heslo: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. "Realm" hodnota pro pÅ™ihlášení. Možné pÅ™eložit jako "oblast". Tento údaj vám poskytne váš SIP poskytovatel. Pokud zůstane pole prázdné, pokusí se Twinkle pÅ™i každém Realm dotazu o pÅ™ihlášení s vaším uživatelským jménem a heslem. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. VaÅ¡e pÅ™ihlaÅ¡ovací SIP jméno. Je Äasto identické s vaším uživatelským SIP jménem. Potom jej lze vynechat. Pokud tomu tak není, poskytne vám ho váš SIP poskytovatel. Your password for authentication. VaÅ¡e pÅ™ihlaÅ¡ovací SIP heslo. Pokud toto políÄko zůstane nevyplnÄ›né, je nutné heslo zadat vždy pÅ™i spuÅ¡tÄ›ní programu pÅ™i navázání kontaktu. Registrar Registrar (pÅ™ihlaÅ¡ovací server) &Registrar: &Registrar: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. Doména, IP adresa nebo jméno vaÅ¡eho SIP pÅ™ihlaÅ¡ovacího serveru. Pokud použijete outbond proxy, která je totožná s vaším SIP poskytovatelem, lze toto políÄko nechat prázdné a vyplnit pouze adresu outbond proxy. &Expiry: &Platnost: The registration expiry time that Twinkle will request. Doba platnosti pÅ™ihlášení v sekundách, kterou si Twinkle pÅ™i pÅ™ihlášení vyžádá. Po uplynutí této doby se Twinkle pÅ™ihlásí automaticky znovu. Pokud tak neuÄiní, váš poskytovatel to vyhodnotí jako stav, že je váš telefon offline a tedy nedostupný pro volání. Také zmÄ›ny vaší IP adresy, napÅ™. po odpojení a opÄ›tovném pÅ™ipojení do sítÄ› s pÅ™idÄ›lením nové IP adresy jsou brány do úvahy až po uplynutí této doby. Hodnoty pod 120 nejsou doporuÄeny. StandardnÄ›: 3600 (=1h). seconds sekund Re&gister at startup PÅ™ihlásit pÅ™i spuÅ¡tÄ›ní &profilu Alt+G Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Pokud je aktivováno, Twinkle se pÅ™i otevÅ™ení tohoto uživatelského profilu automaticky pokouší pÅ™ihlásit k vaÅ¡emu poskytovateli. PÅ™esnÄ›ji Å™eÄeno k pÅ™ihlaÅ¡ovacímu SIP serveru. Pro přímé propojení telefonů IP-to-IP neexistuje žádný poskytovatel a tato volba by mÄ›la být vypnutá. Outbound Proxy &Use outbound proxy &Použít Outbound-Proxy Alt+U Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Pokud je aktivováno, použije Twinkle outbound proxy pro odcházející volání na kterou budou zasílány SIP dotazy. Outbond proxy je možno pÅ™eložit jako "zprostÅ™edkovatele". Toto může být napÅ™. SIP gateway vaší firemní sítÄ›. Bez uvedení outbound proxy se Twinkle sám pokusí zjistit IP adresu k volané telefonnímu Äíslu/adrese. Outbound &proxy: Outbound &proxy: &Send in-dialog requests to proxy Poslat In-&Dialog dotaz na proxy Alt+S SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. Pokud je aktivováno, jsou SIP dotazy posílány <b>vždy</b> na Outbound-Proxy. NormálnÄ› totiž Twinkle posílá SIP dotazy bÄ›hem SIP dialogu (t.j bÄ›hem probíhajícího hovoru) na adresu obdrženou na poÄátku volání v kontaktní hlaviÄce. Tedy přímo protistranÄ›. &Don't send a request to proxy if its destination can be resolved locally. &Neposílat SIP dotazy na proxy, pokud tato není dosažitelná. Dotazy poslat přímo. Alt+D When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) Pokud je aktivováno, pokusí se nejprve Twinkle najít k cílové adrese odpovídající IP adresu a poslat SIP dotaz přímo tam. Pokud se nepodaří IP adresu zjistit, je dotaz poslán na proxy. (UpozornÄ›ní: In-Dialog dotaz bude v tomto případÄ› poslán na proxy, jen pokud je aktivována pÅ™edchozí volba) The hostname, domain name or IP address of your outbound proxy. Doménové jméno, IP adresa nebo jméno vaší outbound proxy. Co&decs Ko&deky Codecs kodeky Available codecs: Dostupné kodeky: G.711 A-law G.711 u-law GSM speex-nb (8 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) List of available codecs. Seznam dostupných, neaktivovaných kodeků. V závislosti od nastavení pÅ™i kompilaci mohou být nÄ›které kodeky nepřístupné. Move a codec from the list of available codecs to the list of active codecs. PÅ™esunout kodek ze seznamu dostupných kodeků do seznamu aktivních kodeků. Move a codec from the list of active codecs to the list of available codecs. Deaktivovat kodek. Active codecs: Aktivní kodeky: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. Seznam aktivních kodeků. Tyto budou použity pÅ™i navázání spojení s protistranou. PoÅ™adí zde uvedených kodeků je zároveň poÅ™adím v jakém budou kodeky upÅ™ednostňovány v použití. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. PÅ™esunout tento kodek smÄ›rem nahoru v seznamu kodeků. Tzn. zvýšit jeho prioritu pro použií pÅ™i navázání spojení. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. PÅ™esunout tento kodek smÄ›rem dolů v seznamu kodeků. Tzn. znížit jeho prioritu pro použií pÅ™i navázání spojení. &G.711/G.726 payload size: &G.711/G.726 payload hodnota: The preferred payload size for the G.711 and G.726 codecs. UpÅ™ednostňovaná payload hodnota pro kodeky G.711 a G.726. ms &iLBC iLBC i&LBC payload type: i&LBC payload type: iLBC &payload size (ms): iLBC &payload &hodnota (ms): The dynamic type value (96 or higher) to be used for iLBC. Typ dynamické hodnoty pro použití v iLBC (96 nebo více). 20 30 The preferred payload size for iLBC. UpÅ™ednostňovaná velikost payload hodnot RTP paketu pro iLBC. &Speex Speex Perceptual &enhancement VylepÅ¡ení &kvality zvuku Alt+E Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). "VylepÅ¡ení kvality zvuku" (anglicky: perceptual enhancement) jsou urÄité funkce daného kodeku, které mají zajistit potlaÄení Å¡umu pÅ™i pÅ™ihlédnutí k vlastnostem lidského sluchu. AÄkoliv dojde pÅ™i použití tÄ›chto funkcí z hlediska technických parametrů pÅ™enosu k jeho zhorÅ¡ení (S/N odstup Å¡umu) a odchýlení se od originálu, je nakonec pociÅ¥ováno zlepÅ¡ení kvality zvuku. &Ultra wide band payload type: &Ultra wide band payload type: Alt+V When enabled, voice activity detection detects whether the audio being encoded is speech or silence/background noise. VAD is always implicitly activated when encoding in VBR, so the option is only useful in non-VBR operation. In this case, Speex detects non-speech periods and encode them with just enough bits to reproduce the background noise. This is called "comfort noise generation" (CNG). Pokud je aktivováno, testuje systém VAD (Voice Activity Detection), jestli je právÄ› mluveno nebo je v hovoru pauza. Zvuky které nejsou rozpoznány jako hovor jsou nahrazeny jen nÄ›kolika málo bity napodobující Å¡um pozadí. To vede k redukci pÅ™enášených dat. Systém VAD je vždy aktivován, pokud je nastaveno kódováni s VBR. &Wide band payload type: &Wide band payload type: Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. PromÄ›nná vzorkovací frekvence (VBR) umožní danému kodeku pÅ™izpůsobit množství dat potÅ™ebných k pÅ™enosu hovoru charakteru audio signálu. Zatímco napÅ™. nÄ›které ostré samohlásky nebo velmi promÄ›nné pasáže potÅ™ebují velkou vzorkovací frekvenci a tím velký datový tok, tak mÄ›kké souhlásky a zvláštÄ› pÅ™estávky v hovoru (viz VAD) vystaÄí s malým datovým tokem. Díky VBR tak lze pÅ™i dané datové rychlosti docílit lepší kvality zvuku. Anebo pÅ™i dané kvalitÄ› hovoru vystaÄit s nižším datovým tokem. Nevýhodou je, že pÅ™i zadané kvalitÄ› nelze pÅ™edpovÄ›dÄ›t jaký velký datový tok bude ve skuteÄnosti. A také, že v aplikacích pracujících v reálném Äase (jako je právÄ› VoIP) je rozhodující maximální vzorkovací frekvence a ne průmÄ›rná. The dynamic type value (96 or higher) to be used for speex wide band. Dynamická typová hodnota pro speex wide band (ne ménÄ› než 96). Co&mplexity: Ko&mplexita: Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. Discontinuous transmission, pÅ™eloženo jako nesouvislý datový pÅ™enos, je rozšíření VAD/VBR pÅ™enosu. PÅ™i nemÄ›nícím se audio signálu (pÅ™edevším v odmlkách mezi slovy) nejsou odesílána stále stejná data nýbrž dojde k úplnému pÅ™eruÅ¡ení posílání dat. Vede to k ÄásteÄnému snížení průmÄ›rného datového toku. PÅ™i nekvalitním pÅ™enosu vÅ¡ak tato volba může vést k poruchám zvuku, jako napÅ™. k zaseknutí urÄitého tónu nebo různým zkreslením. The dynamic type value (96 or higher) to be used for speex narrow band. Dynamická hodnota pro speex narrow band (ne ménÄ› než 96). With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. S použitím funkce Speex může být urÄena komplexita (pÅ™esnost) pro daný kodek. Slouží to k zadání hloubky hledání v rozsahu od 1 do 10. Podobný princip je zaveden v kompresních programech gzip a bzip2 s volbou -1 až -9 . Za normálních podmínek je odstup Å¡umu pÅ™i komplexitÄ› 1 o 1 až 2dB vyšší než pÅ™i komplexitÄ› 10. NicménÄ› CPU vytížení je asi 5x vyšší než pÅ™i komplexitÄ› 1. V praxi se osvÄ›dÄilo nastavení mezi 2 až 4. Vyšší nastavení jsou vhodné pÅ™enos DTMF signálů nebo hudebního signálu. &Narrow band payload type: &Narrow band payload type: G.726 G.726 &40 kbps payload type: payload type hodnota pro G.726 &40 kb/s : The dynamic type value (96 or higher) to be used for G.726 40 kbps. Dynamická typová hodnota pro G.726 40 kb/s (ne ménÄ› než 96). The dynamic type value (96 or higher) to be used for G.726 32 kbps. Dynamická typová hodnota pro G.726 32 kb/s (ne ménÄ› než 96). G.726 &24 kbps payload type: Payload hodnota pro G.726 &24 kb/s : The dynamic type value (96 or higher) to be used for G.726 24 kbps. Dynamická typová hodnota pro G.726 24 kb/s (ne ménÄ› než 96). G.726 &32 kbps payload type: Payload type hodnota pro G.726 &32 kb/s : The dynamic type value (96 or higher) to be used for G.726 16 kbps. Dynamická typová hodnota pro G.726 16 kb/s (ne ménÄ› než 96). G.726 &16 kbps payload type: Payload type hodnota pro G.726 &16 kb/s : DT&MF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). Dynamická typová hodnota pro (RFC2833) (ne ménÄ› než 96). DTMF vo&lume: DTMF &hlasitost: The power level of the DTMF tone in dB. Hlasitost vysílaných DTMF tónů v dB. Jak pro reálné tóny tak i pro rozpoznávání hladiny úrovní dle RFC2833. MÄ›la by být mezi -10 až -6. The pause after a DTMF tone. Doba prodlevy mezi dvÄ›mi DTMF tóny. PříliÅ¡ malé hodnoty mohou vést k tomu, že dva po sobÄ› následující stejné tóny mohou splynout a nebudou rozpoznány jako dvÄ› stejná Äísla. Vyšší hodnoty nejsou na závadu, pokud ovÅ¡em není žádáno co nejrychlejší pÅ™enos DTMF signálů. DTMF &duration: DTMF &trvání: DTMF payload &type: DTMF payload &type: DTMF &pause: DTMF &pauza: dB Duration of a DTMF tone. Doba trvání jednoho DTMF tónu v milisekundách. PÅ™i příliÅ¡ malé hodnotÄ› nemusí pÅ™ijímací stanice odpovídající "hodnoty" správnÄ› rozpoznat. Hodnota 200 by mÄ›la vyhovovat u vÄ›tÅ¡iny i starších přístrojů. DTMF t&ransport: DTMF &režim: Auto RFC 2833 Inband Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> <p><h3>RFC 2833</h3> Vysílá DTMF tóny jako RFC 2833 telefonní signály (symboly v RTP datovém audio toku).</p> <p><h3>Inband</h3> Vysílá DTMF inband (skuteÄné tóny, které Twinkle pÅ™imíchá do audio signálu).</p> <p><h3>Auto</h3> Pokud protistrana podporuje RFC 2833 jsou použity DTMF tóny dle RFC 2833 standardu, jinak jako Inband.</p> <p><h3>Out-of-band (SIP INFO)</h3> Vysílá DTMF out-of-band pouze pÅ™es SIP INFO požadavek.</p> General Obecné Redirection PÅ™esmÄ›rování pro odchozí volání &Allow redirection Povolit &pÅ™esmÄ›rování Alt+A Indicates if Twinkle should redirect a request if a 3XX response is received. Pokud je aktivováno, Twinkle sleduje zda volaná protistrana vyÅ¡le požadavek (3XX). Pokud ano, dojde k pÅ™esmÄ›rování. Ask user &permission to redirect Dotázat se uživatele pÅ™ed &pÅ™esmÄ›rováním Alt+P Alt+W Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Pokud je aktivováno, dotáže se Twinkle pÅ™i pÅ™ijmutí požadavku 3XX uživatele, zdali má být odchozí volání pÅ™esmÄ›rováno na nový cíl. Max re&directions: Max. poÄet &pÅ™esmÄ›rování: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. PoÄet pÅ™esmÄ›rování odchozího volání (z A do B do C atd.), po kterém Twinkle ukonÄí pokusy navázat spojení. Zabraňuje zacyklení pÅ™i pÅ™esmÄ›rování (A -> B -> A...). Protocol options Nastavení SIP protokolu Call &Hold variant: Standard volání a &podržení volání: RFC 2543 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. VýbÄ›r zdali bude k podržení hovoru použito RFC 2543 (set media IP address in SDP to 0.0.0.0) nebo RFC 3264 (use direction attributes in SDP). Allow m&issing Contact header in 200 OK on REGISTER Povolit chybÄ›jící kontaktní hlaviÄku v 200 OK pÅ™i REG&ISTER Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. OdpovÄ›Ä "200 OK" na požadavek "REGISTER" musí obsahovat kontaktní hlaviÄku. NÄ›kteří poskytovatelé buÄ neposílají kontaktní hlaviÄku anebo posílají chybnou kontaktní hlaviÄku. Pokud je aktivováno, pokusí se Twinkle tuto chybu opravit. &Max-Forwards header is mandatory &Max-Forwards-Header je vyžadován Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Podle RFC3261 je Max-Forwards header povinný. ÄŒasto vÅ¡ak není posílán. Pokud je aktivováno, odmítne Twinkle SIP požadavky, které neobsahují Max-Forwards header. Put &registration expiry time in contact header Vložit do kontaktní hlaviÄky dobu platnosti pÅ™i&hlášení Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. Doba vyprÅ¡ení platnosti pÅ™ihlášení v REGISTER požadavku může být pÅ™enášena jak v Contact-Header tak i v Expires-Header. Pokud je aktivováno, posílá ji Twinkle v Contact-header. Jinak v Expires-header. &Use compact header names Použít &kompaktní jména hlaviÄek Indicates if compact header names should be used for headers that have a compact form. Pokud je aktivováno, bude pro jména hlaviÄek použita krátká forma (pokud existuje). Allow SDP change during call setup Povolit SDP zmÄ›ny pÅ™i navázání volání <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> <p>SIP UAS může odesílat SDP v 1XX odpovÄ›di na "early media", napÅ™. "vyzvánÄ›cí tón". Pokud bude volání pÅ™ijmuto, mÄ›l by poslat SIP UAS to samé SDP v odpovÄ›dí "200 OK". Po pÅ™ijmutí SDP by mÄ›ly být vÅ¡echny následující SDP odpovÄ›di ignorovány. Takto je to definováno v RFC 3261.</p> <p>Pokud je povoleno, že se SDP bÄ›hem navázání hovoru může zmÄ›nit, Twinkle neignoruje v následujících odpovÄ›dích SDP, nýbrž zmÄ›ní požadovaným způsobem vlastnosti RTP média streamu (napÅ™. kodek). ZmÄ›nÄ›né SDP musí mít v "o=" řádku nové Äíslo verze.</p> <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> <p>Pokud je aktivováno, vytvoří Twinkle jednoznaÄnou hodnotu kontaktní hlaviÄky pomocí kombinace uživatelského SIP jména a doménového jména: <br> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> Je tím umožnÄ›no vytvoÅ™ení vícera uživatelských profilů se stejným uživatelským SIP jménem ale s rozdílnými kontaktními adresami v doménÄ›. Tyto profily lze potom použít souÄasnÄ›. </p> <p> Mnohé proxy nemusí s takovýmito kontaktními hlaviÄkami umÄ›t zacházet. Pokud je tato volba deaktivována, posílá Twinkle kontaktní hlaviÄku v následujícím formátu: <br> <tt>&nbsp;user@local_ip</tt> </p> <p> Tento formát je používán téměř vÅ¡emi SIP telefony. </p> <p> <b>Používejte tuto volbu jen pokud ji skuteÄnÄ› potÅ™ebujete! Tedy pokud máte vícero profilů se stejným uživatelským jménem.</b></p> &Encode Via, Route, Record-Route as list Via, Route a Record-Route poslat jako &seznam The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. Via-, Route- und Record-Route-Header mohou posílány zakódované jako seznam Äárkou oddÄ›lených hodnot nebo jako jednotlivé hodnoty. Každá ve zvláštní hlaviÄce. SIP extensions SIP rozšíření &100 rel (PRACK): disabled deaktivováno supported podporováno required vyžadováno preferred upÅ™ednostňováno Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. Definuje způsob podpory 100rel extension (PRACK):<br><br> <b>deaktivováno</b>: 100rel rozšíření není podporováno <br><br> <b>povoleno</b>: 100rel je podporováno (je pÅ™idáno do odchozího INVITE jako podporovaná hlaviÄka). Protistrana si potom může vyžádat PRACK na 1xx odpovÄ›Ä. <br><br> <b>vyžadováno</b>: 100rel je vyžádán. Požadavek je vložen do hlaviÄky "require header" v odchozím INVITE. Pokud protistrana poÅ¡le INVITE (=zavolá) a následnÄ› signalizuje, že je 100rel podporován, Twinkle si vyžádá PRACK pÅ™i zasílání odpovÄ›di 1xx. Pokud protistrana 100rel nepodporuje, nedojde k navázání spojení. <br><br> <b>UpÅ™ednostňováno</b>: PodobnÄ› jako "vyžadováno", kromÄ› toho, že dojde k navázání hovoru i když protistrana 100rel nepodporuje. Toto nastavení ovlivňuje chování pÅ™i "early media" (napÅ™. pÅ™i znaku "volné linky"). REFER Call transfer (REFER) PÅ™esmÄ›rování volání (REFER) Allow call &transfer (incoming REFER) Povolit protistranÄ› pÅ™esmÄ›rování &volání (příchozí REFER) Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. Pokud je aktivováno, Twinkle následuje požadavek protistrany (REFER) pÅ™esmÄ›rovat volání na jinou adresu. PÅ™i tomto vám mohou vzniknout dodateÄné finanÄní výdaje. As&k user permission to transfer Dotázat se uživatele na &povolení Alt+K Alt+V Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Pokud je aktivováno, dotazuje se Twinkle pÅ™i příchozím (REFER) požadavku na povolení pÅ™esmÄ›rování. Oproti pevné nebo GSM síti nepÅ™ebírá náklady hovoru ten, kdo volání pÅ™esmÄ›rovává, nýbrž ten kdo volání iniciuje. Hold call &with referrer while setting up call to transfer target T&winkle mezitím co zprostÅ™edkuje pÅ™esmÄ›rování, podrží hovor Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Pokud je aktivováno, Twinkle pÅ™i příchozím požadavku REFER na pÅ™esmÄ›rování podrží stávající hovor. NormálnÄ› by to mÄ›la provést zprostÅ™edkovávající protistrana. Viz následující volbu. StandardnÄ› je to vypnuto. Ho&ld call with referee before sending REFER Twink&le pÅ™edtím než poÅ¡le signál REFER, podrží hovor jako zprostÅ™edkovatel Alt+L Indicates if Twinkle should put the current call on hold when you transfer a call. Pokud je aktivováno, Twinkle jako zprostÅ™edkovatel, pÅ™edtím než poÅ¡le protistranÄ› požadavek REFER o pÅ™esmÄ›rování, pÅ™epne stávající hovor do stavu podržení. Viz pÅ™edchozí volba. StandardnÄ›: aktivováno. Auto re&fresh subscription to refer event while call transfer is not finished Automaticky obnovovat registraci &pro REFER signál, dokud není pÅ™esmÄ›rování dokonÄeno Alt+F While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. BÄ›hem pÅ™esmÄ›rování hovoru posílá zprostÅ™edkovatel pÅ™esmÄ›rování zprávy NOTIFY o postupu pÅ™esmÄ›rování na toho, jehož volání je pÅ™esmÄ›rováváno. OvÅ¡em jen po krátkou dobu. Tu urÄí ten, kdo je pÅ™esmÄ›rováván. Pokud je tato volba aktivována, posílá zprostÅ™edkovatel (Twinkle) automaticky SUBCRIBEs tak, aby doÅ¡lo k prodloužení tohoto Äasu, dokud není proces pÅ™esmÄ›rování ukonÄen. NAT traversal NAT traversal &NAT traversal not needed &NAT traversal není nutný Alt+N Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. Vybrat tuto volbu, pokud se mezi Twinkle a vaší SIP proxy nenachází žádný NAT (router). Anebo pokud sice NAT existuje, ale je konfigurovaný tak, že potÅ™ebné porty jsou již na vás pÅ™esmÄ›rované. PopřípadÄ› pokud váš SIP poskytovatel podporuje "hosted NAT traversal" (způsob jak VoIP poskytovatelé dokáží obejít problémy s NAT). &Use statically configured public IP address inside SIP messages V SIP telegramech použít &pevnÄ› nastavenou IP adresu Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Pokud je aktivováno, Twinkle použije uvnitÅ™ SIP zpráv (v SIP hlaviÄce a SDP obsahu) veÅ™ejnou IP adresu, namísto IP adresy vaÅ¡eho síťového rozhraní. Pokud si tuto volbu vyberete, musíte rovněž na vaÅ¡em NAT zařízení nasmÄ›rovat odpovídající RTP porty na váš poÄítaÄ. Use &STUN Použít &STUN Choose this option when your SIP provider offers a STUN server for NAT traversal. Vybrat tuto volbu, pokud váš SIP poskytovatel nabízí STUN server k pÅ™emostÄ›ní vaší NAT. S&TUN server: Adresa S&TUN serveru: The hostname, domain name or IP address of the STUN server. Doménové jméno, IP adresa nebo jméno STUN serveru (podle potÅ™eby též vÄetnÄ› ":<portnr>", napÅ™. "stunsrv.cz:10000"). &Public IP address: VeÅ™ejná &adresa: The public IP address of your NAT. VeÅ™ejná adresa (IP, DynDNS-doména), pod kterou je váš NAT (realizovaný napÅ™. na vám nejbližším routeru) dosažitelný v internetu. Tato volba má smysl jen pÅ™i nemÄ›nné adrese. Telephone numbers Telefonní Äísla Only &display user part of URI for telephone number U telefonních Äísel zobrazit jen uživatelskou Äást &URI If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. Pokud URI zjistí telefonní Äíslo, zobrazí se jen uživatelská Äást adresy. NapÅ™. pokud pÅ™ijde volání od sip:12345@voipprovider.com, ukáže Twinkle jako adresu jen "12345". URI je považováno jako "Telefonní Äíslo", pokud obsahuje parametr "user=phone" nebo pokud je aktivní následující volba a uživatelská Äást adresy je numerická. &URI with numerical user part is a telephone number &URI s numerickou uživatelskou Äástí je telefonní Äíslo If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. Pokud je aktivováno, považuje Twinkle každou SIP adresu jako "Telefonní Äíslo", které může mít v uživatelské Äásti pouze Äíslice, *, #, + a zvláštní znaky (viz výše). V odchozím SIP zprávách oznaÄí Twinkle takové adresy parametrem "user=phone". Pozor: NapÅ™. poskytovatel Sipgate mÄ›nil/mÄ›ní výraznÄ› své chování v mnohých funkcích, jakmile je tento parametr detekován. &Remove special symbols from numerical dial strings &Odstranit z vytáÄecího Å™etÄ›zce zvláštní znaky Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. Aby byla telefonní Äísla snázeji Äitelná, bývají Äasto zadána s použitím zvláštních znaků jako napÅ™. "(", ")", " "(prázdný znak), "-". PÅ™i vytáÄení, obzvláštÄ› nÄ›jaké SIP adresy, nesmí být tyto znaky vysílány. Aby bylo možné zjednoduÅ¡it vytáÄení pomocí copy/paste nebo přímým nakliknutím v adresáři, lze Twinkle zadat seznam nepřípustných znaků. Ty budou pÅ™ed samotným vytáÄením automaticky z adresy odstranÄ›ny. &Special symbols: nepřípustné &zvláštní znaky: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. Seznam vÅ¡ech zvláštních znaků, které má Twinkle z vytáÄených Äísel odstranit. Number conversion PÅ™evod Äísel Match expression Vyhledávaný výraz Replace Nahradit <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> <p> ÄŒasto není formát telefonních Äísel, které jsou oÄekávány od VoIP poskytovatele, shodný s formátem Äísel uložených v adresáři. NapÅ™. u Äísel zaÄínajících na "+" a národním kódem zemÄ› oÄekává váš poskytovatel namísto "00" znak "+". Nebo jste-li napojeni na místní SIP síť a je nutné pÅ™edtoÄit nejdříve Äíslo k přístupu ven. Zde je možné za použití vyhledávacích a zaměňovacích vzorů (podle způsobu regulárních výrazů a la Perl) nastavit obecnÄ› platné pravidla pro konverzi telefonních Äísel. </p> <p> PÅ™i každém vytáÄení se Twinkle pokusí najít pro Äísla z uživatelské Äásti SIP adresy odpovídají výraz v seznamu hledaných vzorů. S prvním nalezeným vyhovujícím výrazem je provedena úprava originálního Äísla, pÅ™iÄemž pozice v "(" ")" v hledaném výrazu (napÅ™. "([0-9]*)" pro "jakkoliv mnoho Äísel") je nahrazena znaky v odpovídajících promÄ›nných. NapÅ™. "$1" pro první pozici. Viz též `man 7 regex` nebo konqueror:"#regex". Pokud není nalezen žádný odpovídající hledaný vzor, zůstane Äíslo nezmÄ›nÄ›no. </p> <p> Pravidla budou rovněž použita na Äísla v příchozích voláních. Podle nastavených pravidel budou tato pÅ™etransformována do žádaného formátu. </p> <h3>1. příklad</h3> <p> NapÅ™. váš národní kód je "420" pro Äeskou republiku a ve vaÅ¡em adresáři máte také mnoho vnitrostátních Äísel uložených v mezinárodním formátu. NapÅ™.. +420 577 2345678. AvÅ¡ak VoIP poskytovatel oÄekává pro vnitrostátní hovor 0577 2345678. Chcete tedy nahradit '+420' za '0' a zároveň pro zahraniÄní hovory nahradit '+' za '00'. </p> <p> K tomu jsou potÅ™ebné následující pravidla uvedená v tomto poÅ™adí: </p> <blockquote> <tt> Hledaný výraz = \+49([0-9]*) , Náhrada = 0$1<br> Hledaný výraz = \+([0-9]*) , Náhrada = 00$1</br> </tt> </blockquote> <h3>2. příklad</h3> <p> Nacházíte se na telefonní ústÅ™ednÄ› a vÅ¡em Äíslům s 0 jako první Äíslicí, má být pÅ™edÅ™azeno Äíslo 9. </p> <blockquote> <tt> Hledaný výraz = 0[0-9]* , Náhrada = 9$&<br> </tt> </blockquote> ( $& je speciální promÄ›nná, do které je uloženo celé originální Äíslo)<br> Poznámka: Toto pravidlo nelze nastavit jednoduÅ¡e jako tÅ™etí pravidlo ke dvou pravidlů z pÅ™edcházejícího příkladu. Bude totiž použito vždy jen to první, které vyhledávání vyhoví. Namísto toho by muselo být zmÄ›nÄ›no nahrazování v pravidlech 1 a 2 - "57$1" a "577$1" Move the selected number conversion rule upwards in the list. Posunout vybrané pravidlo konverze na vyšší pozici. Move the selected number conversion rule downwards in the list. Posunout vybrané pravidlo konverze na nižší pozici. &Add &Nové Add a number conversion rule. VytvoÅ™it nové konverzní pravidlo. Re&move &Odstranit Remove the selected number conversion rule. Smazat vybrané konverzní pravidlo. &Edit U&pravit Edit the selected number conversion rule. Upravit vybrané konverzní pravidlo. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. Pro ověření funkÄnosti vytvoÅ™eného konverzního pravidla, napiÅ¡te zde zkuÅ¡ební telefonní Äíslo a stisknÄ›te "Test". &Test &Otestovat Test how a number is converted by the number conversion rules. Otestovat jak bude Äíslo pÅ™evedeno konverzními pravidly. for STUN pro STUN Keep alive timer for the STUN protocol. If you have enabled STUN, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. ÄŒasový signál pro STUN protokol. Pokud je STUN aktivován, bude Twinkle posílat pravidelnÄ› v zadaném Äasovém odstupu datové STUN-keep-alive pakety. Cílem je, aby nedoÅ¡lo na routeru ke smazání přísluÅ¡nosti mezi externí a interní IP adresou z adresní NAT tabulky a docházelo k pravidelnému prodlužování platnosti záznamu. Tato hodnota je proto závislá od konkrétního NATu a nemÄ›la by být příliÅ¡ velká. When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". Pokud je detekováno příchozí volání, spustí se tento ÄasovaÄ. Pokud nebude volání do konce vyprÅ¡ení Äasové prodlevy pÅ™ijato, vyÅ¡le Twinkle signál "480 User Not Responding" a hovor odmítne. NAT &keep alive: &STUN NAT-keep-alive: &No answer: "&Nedostupný" po: Ring &back tone: Tón &volné linky: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p>Zadejte zde jméno .wav souboru pro signál volné linky v tomto uživatelském profilu.</p> <p>Tento tón nahrazuje tón volné linky ze systémového nastavení.</p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> <p>Zadejte zde jméno .wav souboru pro vyzvánÄ›cí tón v tomto uživatelském profilu.</p> <p>Toto nastavení nahrazuje vyzvánÄ›cí tón ze systémového nastavení.</p> &Ring tone: &VyzvánÄ›cí tón: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude spuÅ¡tÄ›n, pokud je nÄ›jaký hovor ukonÄen z vaší strany. </p> <h3>Systémové promÄ›nné</h3> <p> Obsahy vÅ¡ech SIP hlaviÄek odesílaných SIP BYE požadavků budou pÅ™edány tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> obsahuje request-URI metody BYE. <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude spuÅ¡tÄ›n, pokud nebude příchozí hovor pÅ™ijat. Tzn. ukonÄí se vyzvánÄ›ní aniž by byl "zvednuto". </p> <h3>Systémové promÄ›nné</h3> <p> Obsahy vÅ¡ech SIP hlaviÄek odesílaných SIP failure odpovÄ›dí budou pÅ™edány tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> obsahuje stavový kód odesílané SIP failure odpovÄ›di. <b>SIPSTATUS_REASON</b> obsahuje "reason phrase", tedy chybovou příÄinu pomocí obyÄejného textu. <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript je spuÅ¡tÄ›n, pokud je hovor ukonÄen protistranou. </p> <h3>Systémové promÄ›nné</h3> <p> Obsahy vÅ¡ech SIP hlaviÄek příchozích SIP BYE požadavků budou pÅ™edány tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> obsahuje request-URI signálu BYE. <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude spuÅ¡tÄ›n, pokud bude protistranou volání pÅ™ijato. </p> <h3>Systémové promÄ›nné</h3> <p> Obsahy vÅ¡ech SIP hlaviÄek příchozích "200 OK" hlášek budou pÅ™edány tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> obsahuje "reason phrase" <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude spuÅ¡tÄ›n, pokud bude příchozí hovor pÅ™ijmut. </p> <h3>Systémové promÄ›nné</h3> <p> Obsahy vÅ¡ech SIP hlaviÄek odchozích "200 OK" odpovÄ›dí budou pÅ™edány tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> obsahuje "reason phrase" <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. Call released locall&y: Lokální &ukonÄení hovoru: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude spuÅ¡tÄ›n, pokud odchozí volání nebude moci býti realizováno. NapÅ™ kvůli timeout, DND atd. </p> <h3>Systémové promÄ›nné</h3> <p> Obsah vÅ¡ech SIP hlaviÄek pÅ™ijatých SIP failure odpovÄ›dí bude pÅ™edán tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> obsahuje stavový kód odeslané SIP failure odpovÄ›di. <b>SIPSTATUS_REASON</b> obsahuje "reason phrase", tedy chybovou hlášku ve formÄ› jednoduchého textu. <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude spuÅ¡tÄ›n, pokud bude zahájeno nÄ›jaké volání. </p> <h3>Systémové promÄ›nné</h3> <p> Obsahy vÅ¡ech SIP hlaviÄek odeslaných SIP INVITE požadavků budou pÅ™edány tomuto skriptu pomocí následujících systémových promÄ›nných: </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> obsahuje request-URI signálu INVITE. <b>TWINKLE_USER_PROFILE</b> obsahuje jméno aktivního uživatelského profilu. Outgoing call a&nswered: Volání &pÅ™ijato protistranou: Incoming call &failed: Příchozí volání bylo &neúspěšné: &Incoming call: &Příchozí volání: Call released &remotely: UkonÄení &hovoru protistranou: Incoming call &answered: Příchozí volání &pÅ™ijato: O&utgoing call: Odchozí &volání: Out&going call failed: Od&chozí volání bylo neúspěšné: &Enable ZRTP/SRTP encryption Aktivovat ZRTP/SRTP &Å¡ifrování When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. Pokud je aktivováno, pokusí se Twinkle pÅ™i vÅ¡ech odchozích a příchozích hovorech zaÅ¡ifrovat zvuková data. Aby byl hovor opravdu zaÅ¡ifrován musí i protistrana podporovat Å¡ifrování ZRTP/SRTP. Jinak zůstane hovor nezakódován. ZRTP settings ZRTP nastavení O&nly encrypt audio if remote party indicated ZRTP support in SDP &ZaÅ¡ifrovat jen pokud protistrana potvrdí podporu ZRTP A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. Protistrana schopná ZRTP může toto oznámit již na zaÄátku navázání rozhovoru. Pokud je aktivována tato volba, pokusí se Twinkle v takových případech použít zaÅ¡ifrovaného pÅ™enosu hovoru. &Indicate ZRTP support in SDP ZRTP podporu ohlaÅ¡ovat &v SDP Twinkle will indicate ZRTP support during call setup in its signalling. Pokud je aktivováno, hlásí Twinkle protistranÄ› pÅ™i navázání hovoru pomocí SDP, že podporuje ZRTP. &Popup warning when remote party disables encryption during call &Upozornit, pokud protistrana pÅ™epne na neÅ¡ifrovaný pÅ™enos hovoru A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. Protistrana může bÄ›hem zaÅ¡ifrovaného hovoru vyslat příkaz ZRTP-go-clear a tím Å¡ifrování zruÅ¡it. Pokud je tato volba aktivována, Twinkle na tento bezpeÄnostní problém okamžitÄ› upozorní. Dynamic payload type %1 is used more than once. Dynamický payload typ %1 je použit vícekrát. You must fill in a user name for your SIP account. Je nutné zadat uživatelské jméno pro váš SIP úÄet. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. K vaÅ¡emu SIP úÄtu musíte vyplnit doménové jméno. (Äást vpravo od znaku @) ÄŒasto je shodné s doménovým jménem vaÅ¡eho SIP poskytovatele. Pro přímé IP-to-IP spojení, tedy bez SIP poskytovatele, je to doménové jméno nebo veÅ™ejná IP adresa vaÅ¡eho poÄítaÄe. Invalid user name. Chybné uživatelské jméno. Invalid domain. Chybné jméno domény. Invalid value for registrar. Chybné jméno registrátora. Invalid value for outbound proxy. Chybné jméno outbound proxy. Value for public IP address missing. Chybí veÅ™ejná IP adresa. Invalid value for STUN server. Chybný údaj STUN serveru. Ring tones Description of .wav files in file dialog VyzvánÄ›cí tóny Choose ring tone VýbÄ›r vyzvánÄ›cího tónu Ring back tones Description of .wav files in file dialog Tón pro signalizaci vyzvánÄ›ní u protistrany All files VÅ¡echny soubory Choose incoming call script VýbÄ›r skriptu ke spuÅ¡tÄ›ní pÅ™i "příchozím volání" Choose incoming call answered script VýbÄ›r skriptu ke spuÅ¡tÄ›ní po "pÅ™ijetí příchozího volání" Choose incoming call failed script VýbÄ›r skriptu ke spuÅ¡tÄ›ní po selhání příchozího volání Choose outgoing call script VýbÄ›r skriptu ke spuÅ¡tÄ›ní pÅ™i odchozím volání Choose outgoing call answered script VýbÄ›r skriptu ke spuÅ¡tÄ›ní pÅ™i pÅ™ijetí volání protistranou Choose outgoing call failed script VýbÄ›r skriptu ke spuÅ¡tÄ›ní pÅ™i selhání odchozího volání Choose local release script VýbÄ›r skriptu ke spuÅ¡tÄ›ní pÅ™i vlastním ukonÄení hovoru Choose remote release script VýbÄ›r skriptu ke spuÅ¡tÄ›ní pÅ™i ukonÄení hovoru protistranou Voice mail Záznamník hovorů &Follow codec preference from far end on incoming calls Kodeky pro pÅ™enos hlasu pÅ™i příchozím volání &vybere protistrana <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. Pokud je aktivováno, Twinkle upÅ™ednostní pÅ™i příchozím volání povolené kodeky protistrany (SDP offer). KonkrétnÄ› bude použit první kodek, který je protistranou nabízen a rovněž se nachází v seznamu lokálních Twinkle kodeků. Pokud je deaktivováno, použije Twinkle první kodek ve vlastním seznamu, který je rovněž podporován protistranou. Follow codec &preference from far end on outgoing calls Následovat &upÅ™ednostnÄ›né kodeky protistranou pÅ™i odchozím volání <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. Pokud je aktivováno bude Twinkle pÅ™i odchozím volání řídit seznamem upÅ™ednostňovaných kodeků u protistrany (SDP answer). KonkrétnÄ› bude použit první kodek na seznamu upÅ™ednostňovaných kodeků protistrany, který je rovněž podporován v aktuálním lokálním nastavení Twinkle. Pokud je deaktivováno, použije Twinkle první kodek z vlastního seznamu, který je rovněž podporován protistranou. Tzn. je uveden v SDP-Answer seznamu. Codeword &packing order: Datové poÅ™adí (codeword &packing order): RFC 3551 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. Existují dvÄ› metody zaÅ™azení datových paketů G.726 do RTP paketu. StandardnÄ› je to RFC 3551. NÄ›kteří SIP poskytovatelé používají ovÅ¡em ATM AAL2. Pokud je pÅ™enos zvuku pÅ™i použití kodeku G.726 zaruÅ¡en, je možné zde zkusit jiné nastavení. Replaces Nahrazení Indicates if the Replaces-extenstion is supported. Pokud je aktivováno, podporuje Twinkle Replaces-Extension u metody PRACK. Attended refer to AoR (Address of Record) PÅ™esmÄ›rování se zpÄ›tným dotazem použije "Address of Record" An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. PÅ™esmÄ›rování se zpÄ›tným dotazem by mÄ›lo používat Contact-URI jako cílovou adresu pro sdÄ›lení nového spojení pÅ™esmÄ›rovávané protistranÄ›. Tato adresa nemusí být ovÅ¡em globálnÄ› platná. Může být tzv. "neroutovatelná". PÅ™esmÄ›rované volání se pak nemusí dostat k cíli. AlternativnÄ› může Twinkle použít AoR (Address of Record). Nevýhodou je, že pÅ™i více uživatelských SIP úÄtech nejsou pÅ™ihlášená koncová zařízení jednoznaÄnÄ› urÄená. Tzn. že pÅ™emÄ›rovávací protistranou (vlastnÄ› SIP poskytovatelem) budou oslovena vÅ¡echna koncová zařízení a budou signalizovat příchozí volání. Privacy Ochrana soukromých data Privacy options Nastavení ochrany soukromých dat &Send P-Preferred-Identity header when hiding user identity &Posílat "P-Preferred-Identity Header" pÅ™i skrytí identity uživatele Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. Pokud je vybráno a je aktivována volba "skrýt odesilatele", bude spolu s údajem odesilatele odeslán pÅ™i požadavku INVITE "P-Preferred-Identity Header". <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Tento skript bude vyvolán, pokud bude detekován požadavek INVITE (volání). <br> Prostudujte si prosím příruÄku v "/usr/share/doc/packages/twinkle/..." nebo podrobnou dokumentaci na "http://twinklephone.com" ! </p> <h3>Vrácené hodnoty</h3> - print po STDOUT (napÅ™. `echo "action=dnd"`), jedna hodnota na řádek: <br> <tt>action=[ continue | reject | dnd | redirect | autoanswer ]<br></tt> <blockquote> <i>continue</i> - pokraÄovat v normálním zpracování volání (default)<br> <i>reject</i> - odmítnout volání<br> <i>dnd</i> - odmítnout volání s poznámkou "do not disturb"<br> <i>redirect</i> - pÅ™esmÄ›rovat volání na <tt>contact</tt> (viz tam)<br> <i>autoanswer</i> - volání "automaticky" pÅ™ijmout<br> </blockquote> <br> <tt>reason=&lt;string&gt; </tt>pro dnd a reject (zobrazení u protistrany)<br> <tt>contact=&lt;pÅ™esmÄ›rovací adresa&gt; </tt>pro pÅ™esmÄ›rování<br> <tt>caller_name=&lt;nové zobrazované jméno volajícího&gt; </tt>nahrazuje pro zobrazení eventuálnÄ› již existující jméno z INVITE<br> <tt>ringtone=&lt;jméno .wav souboru&gt; </tt>vyzvánÄ›cí tón speciálnÄ› pro toto volání (jen pÅ™i <i>continue</i> ;-)<br> <tt>display_msg=&lt;libovolná poznámka pro podrobné zobrazení v hlavním oknÄ›&gt;</tt><br> <tt>end </tt>Twinkle vyhodnotí vÅ¡echny vrácené hodnoty, uzavÅ™e STDOUT skriptu(!) a pokraÄuje dále<br> </tt> </p> <p> <h3>Systémové promÄ›nné</h3> <p> Hodnoty vÅ¡ech SIP hlaviÄek příchozího INVITE budou pÅ™edány tomuto skriptu. Struktura promÄ›nných: <b>SIP_&lt;HEADER_NAME&gt;</b> - napÅ™. SIP_FROM obsahuje hodnotu "from header". </p> <p> TWINKLE_TRIGGER=in_call. <br> SIPREQUEST_METHOD=INVITE. <br> SIPREQUEST_URI obsahuje request-URI signálu INVITE.<br> TWINKLE_USER_PROFILE obsahuje jméno uživatelského profilu, pro který je příchozí volání urÄeno. &Voice mail address: &Adresa záznamníku hovorů: The SIP address or telephone number to access your voice mail. SIP adresa nebo telefonní Äíslo, pod kterým je dosažitelný záznamník hovorů vaÅ¡eho SIP poskytovatele. NÄ›kdy jsou dána dvÄ› Äísla. Jedno pro přístup z libovolného telefonu, napÅ™. "00420 211 58000111") a jedno SIP Äíslo, napÅ™. "50000". Potom by zde mÄ›lo být uvedeno SIP Äíslo. Unsollicited Asterisk režim Sollicited RFC 3842 <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> <H2>Message waiting indication Typ</H2> <p> Pokud váš SIP poskytovatel nabízí "message waiting indication" = upozornÄ›ní na uložené zprávy v záznamníku, může vás Twinkle informovat o nových i již vyslechnutých zprávách na vaÅ¡em SIP záznamníku. V závisloti od vaÅ¡eho poskytovatele, popÅ™. jím používaným typem záznamníkové služby, je nutné zde nastavit jednu z náledujících metod přístupu: </p> <H3>Asterisk</H3> <p> Asterisk podporuje "unsollicited message waiting indication". </p> <H3>RFC 3842</H3> <p> "Sollicited message waiting indication" dle specifikace RFC 3842. </p> &MWI type: &MWI Typ: Sollicited MWI RFC 3842 Subscription &duration: Doba &platnosti pÅ™ihlášení: Mailbox &user name: Uživatelské jméno &mailboxu: The hostname, domain name or IP address of your voice mailbox server. Síťové jméno stanice, doménové jméno nebo IP adresa hlasového Voice-Mailbox serveru. Pokud vám váš poskytovatel k záznamníku neposkytl žádné údaje, zkuste jméno domény vaÅ¡eho uživatelského úÄtu. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Ve specifikaci RFC 3842 MWI se koncové zařízení (Twinkle) hlásí na serveru k příjmu zpráv (SUBSCRIBE) na urÄitou dobu a pÅ™ed vyprÅ¡ením této doby by se pÅ™ihlášení mÄ›lo znovu obnovit. PodobnÄ› jako "expiry time" / "doba platnosti" pro REGISTER. Viz SIP server. Your user name for accessing your voice mailbox. Uživatelské jméno k přístupu na váš Voice-Mailbox (záznamník hovorů). Pokud vám váš poskytovatel toto nesdÄ›lí, zkuste to s vaším SIP jménem. Mailbox &server: Mailbox &server: Via outbound &proxy PÅ™es Outbound &proxy Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. Pokud je aktivováno, zasílá Twinkle SIP požadavky na Mailbox pÅ™es outbound proxy. You must fill in a mailbox user name. Musíte zadat uživatelské jméno pro Mailbox. You must fill in a mailbox server Musíte zadat Mailbox-Server Invalid mailbox server. Neplatné jméno pro Mailbox-Server. Invalid mailbox user name. Nepřípustné jméno Mailboxu. Use domain &name to create a unique contact header value Použít doménové &jméno pro vytvoÅ™ení jednoznaÄné kontaktní hlaviÄky Select ring back tone file. VýbÄ›r souboru pro vyzvánÄ›cí tón u protistrany. Select ring tone file. VýbÄ›r souboru pro vyzvánÄ›cí tón. Select script file. VýbÄ›r souboru se skriptem. %1 converts to %2 %1 pÅ™evést na %2 Instant message Instantní zpráva Presence Přítomnost &Maximum number of sessions: &Maximální poÄet seancí: When you have this number of instant message sessions open, new incoming message sessions will be rejected. Pokud je již otevÅ™en tento poÄet seancí s instantními zprávami, novÄ› příchozí seance budou odmítnuty. Your presence VaÅ¡e přítomnost &Publish availability at startup &Publikovat dostupnost pÅ™i startu Publish your availability at startup. Publikovat vaÅ¡i dostupnost pÅ™i startu. Buddy presence Přítomnost buddyho Publication &refresh interval (sec): Interval &obnovení publikování (sec): Refresh rate of presence publications. Obnovovací frekvence publikování. &Subscription refresh interval (sec): &Interval obnovení pÅ™ihlášení (sec): Refresh rate of presence subscriptions. Obnovovací frekvence pÅ™ihlášení o přítomnosti. Transport/NAT Transport/NAT Add q-value to registration PÅ™idat q-hodnotu k registraci The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. Hodnota 'q' urÄuje prioritu vaÅ¡eho zaregistrovaného zařízení. Pokud je mimo Twinkle k VoIP úÄtu zaregistrováno jiné SIP zařízení, může síť využít tÄ›chto hodnot k urÄení zařízení, které bude pÅ™ednostnÄ› osloveno pro obsloužení hovoru. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. Hodnota 'q' je mezi 0.000 and 1.000 Vyšší hodnota znamená vyšší prioritu. SIP transport SIP transport UDP UDP TCP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. Transportní mód pro SIP. V auto módu je velikost zpráv urÄena tím, jaký transportní protokol je použit. Zprávy vÄ›tší než UDP threshold jsou posílány pÅ™es TCP. Menší zprávy jsou posílány pÅ™es UDP. T&ransport protocol: T&ransportní protokol: UDP t&hreshold: UDP t&hreshold: Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. Zprávy vÄ›tší než threshold jsou odeslány pÅ™es TCP. Menší zprávy pÅ™es UDP. Use &STUN (does not work for incoming TCP) Použít &STUN (nefunguje pro příchozí TCP) P&ersistent TCP connection Tr&valé TCP spojení Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. Podržet otevÅ™ené TCP spojení vytvoÅ™ené bÄ›hem registrace tak, aby SIP Proxy mohla využít tohoto spojení k vysílání příchozích požadavků. Aplikací jsou vysílány ping pakety aby se testovalo, zda-li je spojení stále aktivní. &Send composing indications when typing a message. PÅ™i psaní zprávy vždy &vysílat příznaky editace. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. Twinkle vysílá pÅ™i psaní zprávy příznak editace. Díky tomu je příjemce informován o tom, že je pÅ™ipravována nÄ›jaká zpráva. AKA AM&F: A&KA OP: Authentication management field for AKAv1-MD5 authentication. Parametry autentizaÄního managementu pro AKAv1-MD5 autentizaci. Operator variant key for AKAv1-MD5 authentication. Operátorová varianta klíÄe pro AKAv1-MD5 autentizaci. Prepr&ocessing PÅ™ed&zpracování Preprocessing (improves quality at remote end) PÅ™edzpracování (vylepÅ¡uje kvalitu u příjemce) &Automatic gain control &Automatické řízení hlasitosti Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Z důvodu velkého rozdílu hlasitosti nahrávání v různých nastavení byla zavedena funkce &Automatického řízení hlasitosti (AGC - Automatic gain control). AGC umožňuje nastavit úroveň signálu na pÅ™ednastavenou hodnotu. Díky tomu není nutné pokaždé manuálnÄ› nastavovat hlasitost mikrofonu. Další výhodou je, že nastavení hlasitosti mikrofonu je vÄ›tÅ¡inou na nižší (konzervativní) úrovni, Äímž se pÅ™edchází zpÄ›tnovazebnímu efektům. Automatic gain control &level: &Úroveň automatického řízení hlasitosti: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. Úroveň automatického řízení hlasitosti pÅ™edstavuje procentuální hodnotu maximální hlasitosti mikrofonu. DoporuÄená hodnota je kolem 25%. &Voice activity detection Detekce &hlasové aktivity When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. Pokud je aktivováno testuje funkce detekce hlasové aktivity zdali je vstupní signál hovor (hlas) nebo ruÅ¡ivé okolní zvuky. &Noise reduction &PotlaÄení Å¡umu The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. PotlaÄení Å¡umu může být použito k snížení okolních ruÅ¡ivých zvuků ve vstupním signálu. Vede to k lepší kvalitÄ› mluveného slova. Acoustic &Echo Cancellation PotlaÄení &akustické ozvÄ›ny In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Pokud je pÅ™i VoIP komunikaci příchozí zvuk pÅ™ehráván v reproduktorech může se šířit v místnosti a dostávat se zpÄ›t do mikrofonu. Pokud je tento signál poslán zpÄ›t volajícímu stává se, že slyší dozvuk vlastního hlasu. Funkce potlaÄení &akustické ozvÄ›ny je navržena k potlaÄení tÄ›chto zvuků pÅ™ed tím než jsou odeslány volajícímu. Je důležité si uvÄ›domit, že tato funkce je urÄena pro zlepÅ¡ení kvality pÅ™enosu hlasu na stranÄ› volajícího. Nikoliv na vlastní stranÄ›. Variable &bit-rate PromÄ›nná &vzorkovaci frekvence Discontinuous &Transmission Diskontinuitní &pÅ™enos &Quality: &Kvalita: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. Speex je ztrátový kodek. To znamená, že na úkor kvality je možné docílit redukce datového toku. Na rozdíl od jiných hlasových kodeků je možné nastavit kompromis mezi kvalitou a vzorkovací frekvencí. Kódovací proces u tohoto kodeku je po vÄ›tÅ¡inu doby řízen nastavením parametru kvality v rozsahu od 0 do 10. bytes bajtů Use tel-URI for telephone &number Použít tel-URI pro &telefonní Äíslo Expand a dialed telephone number to a tel-URI instead of a sip-URI. Rozšířit vytáÄené telefonní Äíslo o tel-URI namísto sip-URI. Accept call &transfer request (incoming REFER) Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. Enable NAT &keep alive Send UDP NAT keep alive packets. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. WizardForm Twinkle - Wizard The hostname, domain name or IP address of the STUN server. Doménové jméno, IP adresa nebo jméno STUN serveru. Twinkle se pokouší pod touto doménou zjistit u DNS serveru potÅ™ebné údaje (RFC 2782). StaÄí proto u poskytovatelů internetové pÅ™ipojení, kteří toto podporují, uvést doménové jméno pÅ™ihlaÅ¡ovacího serveru. S&TUN server: S&TUN server: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. Uživatelské jméno, které vám bylo pÅ™idÄ›leno vaším VoIP poskytovatelem. Je také první Äástí vaší kompletní SIP adresy <b>uzivatel</b>@domain.com U mnohých VoIp poskytovatelů to bývá oznaÄeno jako telefonní Äíslo. <br><br> *TYTO ÚDAJE JSOU POVINNÉ. &Domain*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. Vyberte vaÅ¡eho SIP poskytovatele a uveÄte zde vaÅ¡e plné jméno, vaÅ¡e uživatelské SIP jméno, popřípadÄ› pÅ™ihlaÅ¡ovací jméno a heslo.<br> Pokud váš SIP poskytovatel není v seznamu, vyberte <b>Jiný</b> a uveÄte požadované údaje. <p> Prakticky kdekoliv v Twinkle lze pomocí klávesové kombinace <b>Shift-F1</b> nebo <b>pravým tlaÄítkem myÅ¡i</b> vyvolat nápovÄ›du k jednotlivým políÄkům nebo tlaÄítkům. &Authentication name: &PÅ™ihlaÅ¡ovací jméno: &Your name: VaÅ¡e &jméno: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. VaÅ¡e pÅ™ihlaÅ¡ovací SIP jméno. ÄŒasto shodné s vaším uživatelským SIP jménem. NicménÄ› může být i jiné. Dostanete ho od vaÅ¡eho VoIP poskytovatele. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Doména nebo IP adresa, pod kterou je v internetu dostupný váš VoIP poskytovatel. Je to druhá Äást vaší úplné SIP adresy uzivatel@<b>domain.com</b>. U mnohých poskytovatelů je shodná s vlastní doménou poskytovatele. Pro přímé spojení IP-to-IP (viz uživ. příruÄka) se zde uvede adresa (DynDNS nebo IP), pod kterou je <b>váš poÄítaÄ</b> dostupný. <br><br> *TYTO ÚDAJE JSOU POVINNÉ. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. VaÅ¡e plné jméno nebo pÅ™ezdívka. Tento údaj je jednou z Äástí, které jsou pÅ™enášeny pÅ™i volání protistranÄ› a eventuálnÄ› tam zobrazeny. Může být uvedeno cokoliv a není nutnÄ› vyžadováno. SIP pro&xy: SIP pro&xy: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. Doménové jméno, IP adresa nebo jméno vaší proxy. Pokud je shodné s adresou vaÅ¡eho poÄítaÄe je možné tento údaj vynechat. &SIP service provider: &SIP VoIP poskytovatel (Shift-F1 pro nápovÄ›du): &Password: &Heslo: &User name*: &Uživatelské jméno *: Your password for authentication. VaÅ¡e pÅ™ihlaÅ¡ovací heslo. Pokud necháte toto políÄko prázdné, musíte heslo pÅ™i každém pÅ™ihlášení vyplnit do objevivšího se dialogového okna. &OK Alt+O &Cancel ZruÅ¡it (Es&c) Alt+C None (direct IP to IP calls) Žádné (přímé IP to IP volání) Other Jiný User profile wizard: Průvodce uživatelským profilem: You must fill in a user name for your SIP account. Musíte zadat uživatelské jméno vaÅ¡eho SIP úÄtu. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Je nutné zadat doménové jméno vaÅ¡eho SIP úÄtu (Äást vpravo od symbolu "@"). ÄŒasto je shodné s doménovým jménem vaÅ¡eho SIP poskytovatele. Pro přímé spojení IP-to-IP, tedy bez SIP poskytovatele, je to doménové jméno nebo veÅ™ejná IP vaÅ¡eho poÄítaÄe. Invalid value for SIP proxy. Nepřípustná hodnota pro SIP proxy. Invalid value for STUN server. Nepřípustná hodnota pro STUN server. YesNoDialog &Yes &Ano &No &Ne twinkle-1.4.2/src/gui/lang/twinkle_fr.ts0000644000175000001440000101614711151060224015122 00000000000000 AddressCardForm Twinkle - Address Card Twinkle - Fiche de contact &Remark: &Remarque: Infix name of contact. Titre du contact. First name of contact. Prénom du contact. &First name: &Prénom: You may place any remark about the contact here. Vous pouvez saisir une remarque sur le contact ici. &Phone: &Téléphone: &Infix name: T&itre: Phone number or SIP address of contact. Numéro de téléphone ou une adresse SIP du contact. Last name of contact. Nom du contact. &Last name: &Nom: &OK Alt+O &Cancel Annuler (Es&c) Alt+C You must fill in a name. Vous devez saisir un nom. You must fill in a phone number or SIP address. Vous devez saisir un numéro de téléphone ou une adresse SIP. AuthenticationForm Twinkle - Authentication Twinkle - Authentification user No need to translate The user for which authentication is requested. L'utilisateur dont l'identification est requise. profile No need to translate The user profile of the user for which authentication is requested. Le profil d'utilisateur dont l'identification est requise. User profile: Profil d'utilisateur: User: Utilisateur: &Password: Mot de &passe: Your password for authentication. Votre mot de passe pour authentification. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Votre nom d'authentification SIP. Souvent il est le même que votre nom d'utilisateur SIP. Cependant, il peut être différent. &User name: &Utilisateur: &OK &OK &Cancel Annuler (Es&c) Login required for realm: Login nécessaire pour Realm: realm No need to translate The realm for which you need to authenticate. Le Realm pour lequel vous devez vous identifier. BuddyForm Twinkle - Buddy Twinkle - Avatar Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. &Phone: &Téléphone: Name of your buddy. Nom de votre avatar. &Show availability &Montrer la disponibilité Alt+S Alt+M Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. Cochez cette case si vous voulez voir la disponibilité de votre avatar. Ceci fonctionnera uniquement si votre fournisseur d'accès offre un service de présence. &Name: &Nom: SIP address your buddy. Adresse SIP de votre avatar. &OK &OK Alt+O &Cancel Annuler (Es&c) Alt+C You must fill in a name. Vous devez saisir un nom. Invalid phone. Téléphone invalide. Failed to save buddy list: %1 Echec de la sauvegarde de la liste d'avatars: %1 BuddyList Availability Disponobilité unknown inconnu offline déconnecté online connecté request rejected demande rejetée not published non publié failed to publish impossible de publier request failed demande échouée Click right to add a buddy. Cliquez à droite pour ajouter un avatar. CoreAudio Failed to open sound card Echec de l'accès à la carte son Failed to create a UDP socket (RTP) on port %1 Echec de la création de la socket UDP (RTP) sur le port %1 Failed to create audio receiver thread. Echec de la création de "audio receiver thread". Failed to create audio transmitter thread. Echec de la création de "audio transmitter thread". CoreCallHistory local user utilisateur local remote user utilisateur distant failure échec unknown inconnu in entrant out sortant DeregisterForm Twinkle - Deregister Twinkle - Déconnexion deregister all devices déconnecter toutes les interfaces &OK &Cancel Annuler (Es&c) DiamondcardProfileForm Twinkle - Diamondcard User Profile Your Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. C'est simplement votre nom complet, ex: Pierre Dupond. Il est utilisé pour l'affichage. Quand vous ferez un appel, ceci sera montré à votre correspondant. &Account ID: &PIN code: &Your name: &Votre nom: <p align="center"><u>Sign up for a Diamondcard account</u></p> &OK Alt+O &Cancel Annuler (Es&c) Alt+C Fill in your account ID. Fill in your PIN code. A user profile with name %1 already exists. Your Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> DtmfForm Twinkle - DTMF Keypad Clavier 2 3 Over decadic A. Normally not needed. Touche de fonction A. Normalement pas nécessaire. 4 5 6 Over decadic B. Normally not needed. Touche de fonction B. Normalement pas nécessaire. 7 8 9 Over decadic C. Normally not needed. Touche de fonction C. Normalement pas nécessaire. Star (*) Etoile (*) 0 Pound (#) Point (#) Over decadic D. Normally not needed. Touche de fonction D. Normalement pas nécessaire. 1 &Close &Fermer Alt+C FreeDeskSysTray Show/Hide Montrer/Cacher Quit Quitter GUI Failed to create a UDP socket (SIP) on port %1 Impossible de créer un socket UDP (SIP) sur le port %1 The following profiles are both for user %1 Les profils suivant sont pour l'utilisateur %1 You can only run multiple profiles for different users. Des utilisateurs différents doivent avoir des profils différents. Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Impossible de trouver une interface réseau. Twinkle utilisera 127.0.0.1 comme adresse IP locale. Quand vous vous connecterez au réseeau vous devrez redémarrer Twinkle pour utiliser la bonne adresse IP. Line %1: incoming call for %2 Ligne %1: appel entrant pour %2 Call transferred by %1 Appel tranféré par %1 Line %1: far end cancelled call. Ligne %1: appel annulé par le correspondant. Line %1: far end released call. Ligne %1: Le correspondant a raccroché. Line %1: SDP answer from far end not supported. Ligne %1: réponse SDP du correspondant non supportée. Line %1: SDP answer from far end missing. Ligne %1: réponse SDP du correspondant manquante. Line %1: Unsupported content type in answer from far end. Ligne %1: Contenu entrant non supporté. Line %1: no ACK received, call will be terminated. Ligne %1: ACK non reçu, l'appel sera annulé. Line %1: no PRACK received, call will be terminated. Ligne %1: PRACK non reçu, l'appel sera annulé. Line %1: PRACK failed. Ligne %1: PRACK échoué. Line %1: failed to cancel call. Ligne %1: impossible d'annuler l'appel. Line %1: far end answered call. Ligne %1: Le correspondant a répondu. Line %1: call failed. Ligne %1: appel échoué. The call can be redirected to: L'appel peut être redirigé vers: Line %1: call released. Ligne %1: fin d'appel. Line %1: call established. Leitung %1: appel établi. Response on terminal capability request: %1 %2 Réponse à la demande des capacités du correspondant: %1 %2 Terminal capabilities of %1 Capacités du correspondant %1 Accepted body types: Types de corps acceptés: unknown inconnu Accepted encodings: Encodage accepté: Accepted languages: Langages accepté: Allowed requests: Demandes authorisées: Supported extensions: Extensions supportées: none aucun End point type: Type de correspondant: Line %1: call retrieve failed. Ligne %1: récupération de l'appel échoué. %1, registration failed: %2 %3 %1, connexion échouée: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, connexion réussie (expire %2 sec.) %1, registration failed: STUN failure %1, enregistrement échoué: echec STUN %1, de-registration succeeded: %2 %3 %1, déconnexion réussie: %2 %3 %1, fetching registrations failed: %2 %3 %1, recherche des connexions échouée: %2 %3 : you are not registered : vous n'êtes pas connecté : you have the following registrations : voici la liste des connexions : fetching registrations... : recherche des connexions... Line %1: redirecting request to Ligne %1: rediriger la demande à Redirecting request to: %1 Redirection de la demande à : %1 Line %1: DTMF detected: Ligne %1: DTMF détecté: invalid DTMF telephone event (%1) Evénnement DTMF invalid (%1) Line %1: send DTMF %2 Ligne %1: envoi DTMF %2 Line %1: far end does not support DTMF telephone events. Ligne %1: le correspondant ne supporte pas les événnements DTMF. Line %1: received notification. Ligne %1: notification reçue. Event: %1 Evénnement: %1 State: %1 Statut: %1 Reason: %1 Raison: %1 Progress: %1 %2 Progression: %1 %2 Line %1: call transfer failed. Ligne %1: transfert d'appel échoué. Line %1: call succesfully transferred. Ligne %1: transfert d'appel réussi. Line %1: call transfer still in progress. Ligne %1: transfert d'appel en cours. No further notifications will be received. Aucune nouvelle notification ne sera reçue. Line %1: transferring call to %2 Ligne %1: transfert d'appel vers %2 Transfer requested by %1 Demande de transfert de %1 Line %1: Call transfer failed. Retrieving original call. Ligne %1: Transfert d'appel échoué. Recherche de l'appel original. Redirecting call Redirection d'appel User profile: Profil utilisateur: User: Utilisateur: Do you allow the call to be redirected to the following destination? Authorisez vous la redirection de l'appel vers la destination suivante? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. Si vous ne voulez plus qu'on vous pose cette question, vous devez modifier les paramètres dans la section "protocole SIP" du profil d'utilisateur. Redirecting request Demande de redirection Do you allow the %1 request to be redirected to the following destination? Authorisez-vous la redirection de la demande %1 vers la destination suivante? Transferring call Transfert d'appel Request to transfer call received from: Demande de transfert d'appel reçue depuis: Do you allow the call to be transferred to the following destination? Authorisez-vous le transfert de l'appel vers la destination suivante? Info: Info: Warning: Attention: Critical: Critique: Firewall / NAT discovery... Firewall / NAT Analyse... Abort Annuler Line %1 Ligne %1 Click the padlock to confirm a correct SAS. Cliquez sur "Verr Num" pour confirmer un SAS correcte. The remote user on line %1 disabled the encryption. L'utilisateur distant sur la ligne %1 a invalidé la cryptographie. Line %1: SAS confirmed. Ligne %1: SAS confirmé. Line %1: SAS confirmation reset. Ligne %1: SAS confiirmation de la remise à zéro. Line %1: call rejected. Ligne %1: appel rejeté. Line %1: call redirected. Ligne %1: appel redirigé. Failed to start conference. Lancement de la conférence échoué. Override lock file and start anyway? Outre-passer le fichier de vérouillage et démarrer quand-même? %1, STUN request failed: %2 %3 %1, STUN demande rejetée: %2 %3 %1, STUN request failed. %1, STUN demande échouée. %1, voice mail status failure. %1, echec du statut du message vocal. %1, voice mail status rejected. %1, rejet du statut du message vocal. %1, voice mailbox does not exist. %1, la boîte vocale n'existe pas. %1, voice mail status terminated. %1, statut du message vocal terminé. %1, de-registration failed: %2 %3 %1, déconnexion échouée: %2 %3 Request to transfer call received. Demande de transfert d'appel reçue. If these are users for different domains, then enable the following option in your user profile (SIP protocol) S'il y a des utilisateurs de différents domaines, activez cette option dans votre profil d'utilisateur (protcole SIP) Use domain name to create a unique contact header Utilisez le nom de domaine pour créer une entête de contact unique Failed to create a %1 socket (SIP) on port %2 Impossible de créer un socket %1 (SIP) sur le port %2 Accepted by network Accepté par le réseau Failed to save message attachment: %1 Echec de l'enregistrement de la pièce jointe: %1 Transferred by: %1 Cannot open web browser: %1 Configure your web browser in the system settings. GetAddressForm Twinkle - Select address Twinkle - Selection d'adresse Name Nom Type Type Phone Téléphone &Show only SIP addresses Montrer uniquement les adresses &SIP Alt+S Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". Cochez cette case quand vous voulez uniquement voir les contacts avec une adresse SIP, i.e. commençant par: "<b>sip:</b>". &Reload &Recharger Alt+R Reload the list of addresses from KAddressbook. Recharge la liste d'adresse de KAddressbook. &OK Alt+O &Cancel Annuler (Es&c) Alt+C &KAddressBook This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. La liste d'adresse est tiré de <b>KAddressBook</b>. Les contacts pour lesquels vous n'avez pas renseignés de numéro de téléphone ne sont pas montrés ici. Pour ajouter, supprimer, ou modifier une information de contact, vous devez utiliser KaddressBook. &Local address book Carnet d'adresse &local Remark Remarque Contacts in the local address book of Twinkle. Contacts dans le carnet d'adresses local de Twinkle. &Add &Ajouter Alt+A Add a new contact to the local address book. Ajouter un nouveau contact au carnet d'adresse local. &Delete &Supprimer Alt+D Alt+S Delete a contact from the local address book. Supprimer un contact du carnet d'adresse local. &Edit &Editer Alt+E Edit a contact from the local address book. Editer un contact du carnet d'adresse local. <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> <p>Il semble qu'il n'y ait aucun contact avec un numéro de téléphone dans <b>KAddressBook</b>, le carnet d'adresse de KDE. Twinkle récupère tous les contacts avec un numéro de téléphone de KAddressBook. Pour gérer vos contacts utilisez KadressBook.</p> <p>Comme alternative, vous pouvez utiliser le carnet d'adresse local de Twinkle.</p> GetProfileNameForm Twinkle - Profile name Twinkle - Nom du profil &OK &Cancel Annuler (Es&c) Enter a name for your profile: Saisissez un nom de profil: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> <b>Le nom de votre profil</b> <br><br> Un profil contient vos parmêtres utilisateur, ex: votre nom d'utilisateur et mot de passe. Vous devez donner un nom à chaque profil. <br><br> Si vous avez plusieurs comptes SIP, vous pouvez créer différents profils. Quand vous lancez Twinkle, il vous proposera la liste des profils pour sélectionner celuique vous voulez utiliser. <br><br> Pour vous rappeler facilement de vos profils, vous pouvez utiliser votre nom d'utilisateur SIP comme nom de profil. ex: <b>exemple@exemple.com</b> Cannot find .twinkle directory in your home directory. Impossible de trouver le dossier .twinkle dans votre dossier home. Profile already exists. Ce profil existe déjà. Rename profile '%1' to: Renomer le profil %1 en: HistoryForm Twinkle - Call History Twinkle - Historique des appels Time Heure In/Out Ent/Sort From/To de/à Subject Sujet Status Statut Call details Détails Details of the selected call record. Détails de l'appel sélectionné. View Voir &Incoming calls Appels &entrants Alt+I Alt+E Check this option to show incoming calls. Sélectionnez cette option pour voir les appels entrants. &Outgoing calls Appels &sortants Alt+O Alt+S Check this option to show outgoing calls. Sélectionnez cette option pour voir les appels sortants. &Answered calls Appels &répondus Alt+A Alt+R Check this option to show answered calls. Sélectionnez cette option pour voir les appels répondus. &Missed calls Appels en &absence Alt+M Alt+A Check this option to show missed calls. Sélectionnez cette option pour voir les appels en absence. Current &user profiles only Seulement l'&utilisateur actif Alt+U Check this option to show only calls associated with this user profile. Sélectionnez cette option pour voir seulement les appels de cet utilisateur. C&lear &Vider Alt+L Alt+V <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> <p>Vider la totalité de l'historique.</p> <p><b>Nota:</b> ceci supprimera <b>tous</b> les enregistrements, y compris les enregistrements non affichés en fonction des options sélectionnées.</p> Alt+C Close this window. Fermer cette fenêtre. Call start: Début de l'appel: Call answer: Appel abouti: Call end: Fin de l'appel: Call duration: Durée de l'appel: Direction: Direction: From: de: To: à: Reply to: Répondre à: Referred by: Demandé par: Subject: Sujet: Released by: Terminé par: Status: Statut: Far end device: Interface de l'utilisateur distant: User profile: Profil d'utilisateur: conversation conversation Call... Appel... Delete Suppression Re: Re: Call selected address. Adresse des appels sélectionnés. Clo&se &Fermer (Esc) Alt+S Alt+F &Call Appel (&Enter) Number of calls: ### Total call duration: InviteForm Twinkle - Call Twinkle - Appel &To: &à: Optionally you can provide a subject here. This might be shown to the callee. Vous pouvez renseigner un sujet ici (optionnel). Il peut être montré à l'appelant. Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. L'adresse de la personne vers que vous voulez appeler. Ceci peut être une adresse SIP comme <b>sip:exemple@exemple.com</b> ou uniquement la partie utilisateur ou le numéro de téléphone d'une adresse complète. Quand vous ne spécifiez pas une adresse complète, Twinkle complètera cette adresse en utilisant le domaine défini dans votre profil utilisateur. The user that will make the call. L'utilisateur qui fera l'appel. &Subject: &Sujet: &From: &De: &OK &Cancel Annuler (Es&c) &Hide identity Cacher l'&identité Alt+H Alt+I <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> <p>Par cette option, vous demandez à votre fournisseur de services SIP de cacher votre identité vis à vis de votre correspondant. Ceci ne cachera que votre identité c'est à dire votre adresse SIP et numéro de téléphone. Ceci </b>ne<b> cache <b>pas</b> votre <b>adresse IP</p>. <p><b>Attention: </b>Tous les fournisseurs de services SIP ne supportent pas cette fonctionnalité !</p> Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. Tous les fournisseurs de services SIP ne supportent pas la fonctionnalité "cacher l'identité". Assurez vous que votre fournisseur de services SIP l'authorise si vous en avez vraîment besoin. F10 LogViewForm Twinkle - Log Contents of the current log file (~/.twinkle/twinkle.log) Contenu du fichier de log (~/.twinkle/twinkle.log) &Close &Fermer Alt+C Alt+F C&lear &Supprimer Alt+L Clear the log window. This does <b>not</b> clear the log file itself. Fermer la fenêtre de log. Ceci <b>ne</b> supprime <b>pas</b> le fichier de log lui-même. MessageForm Twinkle - Instant message Twinkle - Messagerie instantanée &To: &à: The user that will send the message. L'utilisateur qui enverra le message. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. L'adresse de la personne à qui vous voulez envoyer un message. Ceci peut être une adresse SIP comme <b>sip:exemple@exemple.com</b> ou uniquement la partie utilisateur ou le numéro de téléphone d'une adresse complète. Quand vous ne spécifiez pas une adresse complète, Twinkle complètera cette adresse en utilisant le domaine défini dans votre profil utilisateur. Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. &User profile: Profil &utilisateur: Conversation Conversation The exchanged messages. Les messages échangés. Type your message here and then press "send" to send it. Saisissez votre message ici, puis appuyer sure "Envoyer" pour l'envoyer. &Send &Envoyer Alt+S Alt+E Send the message. Envoyer le message. Delivery failure Echec de l'envoi Delivery notification Notification de la réception Instant message toolbar Barre d'outil de la messagerie instantanée Send file... Envoi de fichier... Send file Envoyer un fichier image size is scaled down in preview La taille de l'image est réduite en prévisualisation Open with %1... Ouvrir avec %1... Open with... Ouvrir avec... Save attachment as... Enregistrer la pièce jointe sous... File already exists. Do you want to overwrite this file? Le fichier existe déjà. Voulez-vous le remplacer ? Failed to save attachment. Impossible d'enregistrer la pièce jointe. %1 is typing a message. %1 est un message texte. F10 Size MessageFormView sending message Envoi du message MphoneForm Twinkle &Call: Label in front of combobox to enter address &Numéro: The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. L'adresse de la personne vers que vous voulez appeler. Ceci peut être une adresse SIP comme <b>sip:exemple@exemple.com</b> ou uniquement la partie utilisateur ou le numéro de téléphone d'une adresse complète. Quand vous ne spécifiez pas une adresse complète, Twinkle complètera cette adresse en utilisant le domaine défini dans votre profil utilisateur. The user that will make the call. L'utilisateur qui émettera l'appel. &User: &Utilisateur: Dial Appeler Dial the address. Appeler l'appel. Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. Auto answer indication. Indication de réponse automatique. Message waiting indication. Indication de message en attente. Call redirect indication. Indication de redirection d'appel. Do not disturb indication. Indication "ne pas déranger". Missed call indication. Indication d'appel en absence. Registration status. Statut de la connexion. Display Affichage Line status Statut de la ligne Line &1: Ligne &1: Alt+1 Click to switch to line 1. Cliquez pour basculer sur la ligne 1. From: De: To: à: Subject: Sujet: Visual indication of line state. Indication visuelle de l'état de la ligne. idle No need to translate Call is on hold Appel en attente Voice is muted Voix coupée Conference call Conférence Transferring call Transfert d'appel <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> <p> Le clavier indique que votre voix est encrypté sur le réseau. </p> <h3>SAS - Short Authentication String (chaine d'authentification courte)</h3> <p> Les deux correspondants d'une ligne encrypté reçoivent le même SAS lors du premier appel. Si le SAS est différent, votre ligne est compromise. </p> <p> Si le SAS est égal, vous devez le confirmer en cliquant sur le clavier pour une meilleure sécurité des futurs appels vers cette même destination. Vous n'aurez plus à confirmer le SAS pour cette même destination. Le clavier affichera un symbol de confirmation quand le SAS est confirmé. </p> sas No need to translate Short authentication string SAS - Short authentication string g711a/g711a No need to translate Audio codec 0:00:00 Call duration Durée de l'appel sip:from No need to translate sip:to No need to translate subject No need to translate photo No need to translate Line &2: Ligne &2: Alt+2 Click to switch to line 2. Cliquez pour basculer sur la ligne 2. &File &Fichier &Edit &Edition C&all &Appel Activate line Activer la ligne &Registration &Connexion &Services &Services &View &Vue &Help Ai&de Call Toolbar Barre d'outil d'appel Quit Quitter &Quit &Quitter Ctrl+Q About Twinkle A propos de Twinkle &About Twinkle A propos de &Twinkle Call someone Appeler F5 Answer incoming call Répondre à l'apppel entrant F6 Release call Raccrocher Reject incoming call Rejeter l'appel entrant F8 Put a call on hold, or retrieve a held call Mettre un appel en attente, ou reprendre un appel en attente Redirect incoming call without answering Redirection d'appel entrant sans répondre Open keypad to enter digits for voice menu's Ouvrir le clavier pour siasir des digits du menu vocal Register Se connecter &Register Se &connecter Deregister Se déconnecter &Deregister Se &déconnecté Deregister this device Déconnecter cette interface Show registrations Montrer les connexions &Show registrations &Montrer les connexions Terminal capabilities Possibilités du terminal Request terminal capabilities from someone Demande les capacités du terminal d'un correspondant Do not disturb Ne pas déranger &Do not disturb Ne pas &déranger Call redirection Redirection d'appel Call &redirection... &Redirection d'appel... Repeat last call Wahlwiederholung, wählt letzten Ruf erneut F12 About Qt A propos de Qt About &Qt &A propos de Qt User profile Profil utilisateur &User profile... Profil &utilisateur... Join two calls in a 3-way conference Joindre une conférence 3 parties Mute a call Rendre muet Transfer call Transfert d'appel System settings Paramètres système &System settings... Paramètres &système... Deregister all Tout déconnecter Deregister &all &Tout déconnecter Deregister all your registered devices Déconnecter toutes les interfaces connectées Auto answer Réponse automatique &Auto answer Réponse &automatique Log &Log... Call history Historique d'appel Call &history... &Historique d'appel... F9 Change user ... Changer d'utilisateur ... &Change user ... &Changer d'utilisateur ... Activate or de-activate users Activer ou désactiver des utilisateurs What's This? Qu'est-ce que c'est? What's &This? &Qu'est-ce que c'est? Shift+F1 Shift+F1 Line 1 Ligne 1 Line 2 Ligne 2 idle libre dialing numérotation attempting call, please wait appel en cours, merci de patienter incoming call appel entrant establishing call, please wait établissement de l'appel, merci de patienter established établi established (waiting for media) établi (attente de données) releasing call, please wait Raccrochage en cours, merci de patienter unknown state Etat inconnu Voice is encrypted Voix encryptée Click to confirm SAS. Cliquez pour confirmer SAS. Click to clear SAS verification. Cliquez pour annuler la vérification SAS. User: Utilisateur: Call: Appel: Registration status: Statut de la connexion: Registered Connecté Failed Echoué Not registered Non connecté No users are registered. Aucun utilisteur n'est connecté. Do not disturb active for: "Ne pas dérangé" activé pour: Redirection active for: Redirection activée pour: Auto answer active for: "Réponse automatique" activée pour: Do not disturb is not active. "Ne pas dérangé" n'est pas actif. Redirection is not active. La redirection n'est pas active. Auto answer is not active. la réponse automatique n'est pas active. You have no missed calls. Vous n'avez pas d'appel en absence. You missed 1 call. 1 appel en absence. You missed %1 calls. %1 appels en absence. Click to see call history for details. Cliquez pour plus de détails . Starting user profiles... Démarrage des profiles d'utilisateurs... The following profiles are both for user %1 Les profils suivant sont pour l'utilisateur %1 You can only run multiple profiles for different users. Voius pouvez seulement executer plusieurs profils pour différents utilisateurs. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. Vous avez chazngé le port UDP de SIP. Pour prendre en compte les modifications, il est nécessaire de redémarrer Twinkle. Esc Esc Transfer consultation Consultation du transfert Hide identity Cacher l'identité Click to show registrations. Cliquez pour montrer les connexions. %1 new, 1 old message %1 nouveau, 1 ancien message %1 new, %2 old messages %1 nouveau, %2 ancien messages 1 new message 1 nouveau message %1 new messages %1 nouveau messages 1 old message 1 ancien message %1 old messages %1 anciens messages Messages waiting Messages reçus No messages Pas de messages <b>Voice mail status:</b> <b>Statut de la boîte vocale:</b> Failure Echec Unknown Inconnu Click to access voice mail. Cliquez pour accéder à la boîte vocale. Click to activate/deactivate Cliquez pour activer/désactiver Click to activate Cliquez pour activer not provisioned non enregistré You must provision your voice mail address in your user profile, before you can access it. Vous devez enregistrer votre numéro de boîte vocale dans votre profil d'utilisateur avant de pouvoir y accéder. The line is busy. Cannot access voice mail. La ligne est occupée. Impossible d'accéder à la boîte vocale. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Le numéro %1 de boîte vocale est invalide. Merci d'enregistrer un numéro valide dans votre profil d'utilisateur. Call toolbar text Appel &Call... call menu text &Appel... Answer toolbar text Répondre &Answer menu text &Répondre Bye toolbar text Fin &Bye menu text &Fin Reject toolbar text Refuser &Reject menu text R&efuser Hold toolbar text Attente &Hold menu text Atte&nte Redirect toolbar text Redirect R&edirect... menu text Re&direction... Dtmf toolbar text Dtmf &Dtmf... menu text Dt&mf... &Terminal capabilities... menu text Possibilités du &terminal... Redial toolbar text Rappeler &Redial menu text &Rappeler Conf toolbar text Conf &Conference menu text &Conférence Mute toolbar text Muet &Mute menu text M&uet Xfer toolbar text Transfert Trans&fer... menu text &Transfert... Voice mail Boîte vocale &Voice mail &Boîte vocale Access voice mail Accès boîte vocale F11 Buddy list Liste d'avatars &Message &Message Msg Msg Instant &message... &Message instantané... Instant message Message instantané &Call... &Appel... &Edit... &Editer... &Delete &Supprimer O&ffline Déc&onnecté &Online &Connecté &Change availability Mod&ifier la disponibilité &Add buddy... &Ajouter un avatar... Failed to save buddy list: %1 Echec de la sauvegarde de la liste d'avatars: %1 You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. Vous pouvez créer une liste d'avatar pour chaque profil. Vous ne pouvez voir la disponibilité de vos avatars et publier la votre que si votre fournisseur de service dispose d'un serveur de présence. &Buddy list &Liste d'avatars &Display &Affichage F10 Diamondcard Manual &Manual Sign up &Sign up... Recharge... Balance history... Call history... Admin center... Recharge Balance history Admin center NumberConversionForm Twinkle - Number conversion Twinkle - Conversion de numéro &Match expression: &Expression de recherche: &Replace: &Remplacer: Perl style format string for the replacement number. Chaine au format Perl pour le remplacement du numéro. Perl style regular expression matching the number format you want to modify. Expression réguliuère au format Perl pour la vérification du format du numéro que vous voulez modifier. &OK Alt+O &Cancel Annuler (Es&c) Alt+C Match expression may not be empty. L'expression de vérification ne doit pas être vide. Replace value may not be empty. La valeur de remplacement ne doit pas être vide. Invalid regular expression. Expression régulière invalide. RedirectForm Twinkle - Redirect Twinkle - Redirection Redirect incoming call to Rediriger les appels entrants vers You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Vous pouvez sélectionner jusqu'a 3 destinations vers lesquelles rediriger l'appel. Si la première destionationne répond pas, la deuxième sera essayée et ainsi de suite. &3rd choice destination: &3ème destination: &2nd choice destination: &2ème destination: &1st choice destination: &1ère destination: Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. &OK &Cancel Annuler (Es&c) F10 F12 F11 SelectNicForm Twinkle - Select NIC Twinkle - Selection de l'interface réseau Select the network interface/IP address that you want to use: Selectionnez l'interface réseau/adresse IP que vous voulez utiliser: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. Vous avez plusieurs adresses IP. Vous devez sélectionner ici l'adresse IP qui doit être utilisée. Cette adresse IP sera incluse dans les messages SIP. Set as default &IP Activer comme &IP par défaut Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Utiliser l'adresse IP sélectionnée comme adresse IP par défaut. La prochaine fois que vous démarrerez Twinkle, cette adresse IP sera automatiquement utilisée. Set as default &NIC Activer comme interface &réseau par défaut Alt+N Alt+R Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. Utiliser l'interface réseau sélectionné comme interface réseau par défaut. La prochaine fois que vous démarrerez Twinkle, cette interface sera automatiquement utilisée. &OK Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. Si vous voulez supprimer ou modifier les paramètres par défaut, vous pourrez le faire par les paramètres système. SelectProfileForm Twinkle - Select user profile Twinkle -Sélectionner un profil utilisateur Select user profile(s) to run: Sélectionner le(s) profil(s) à démarrer: User profile Profil utilisateur Tick the check boxes of the user profiles that you want to run and press run. Cochez les cases des profils utilisateurs que vous voulez utilisez et appuyer sur "Démarrer". &New &Nouveau Alt+N Alt+N Create a new profile with the profile editor. Créer un nouveau profil avec l'éditeur de profil. &Wizard &Assistant Alt+W Alt+A Create a new profile with the wizard. Créer un nouveau profil avec l'assistant de création de profil. &Edit &Editer Alt+E Alt+E Edit the highlighted profile. Editer le profil sélectionné. &Delete &Supprimer Alt+D Alt+S Delete the highlighted profile. Supprimer le profil sélectionné. Ren&ame Ren&ommer Alt+A Alt+O Rename the highlighted profile. Renommer le profil sélectionné. &Set as default &Utiliser par défaut Alt+S Alt+U Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. Utiliser le profil sélectionné comme profil par défaut. La prochaine fois que vous démarrerez Twinkle, ces profils seront automatiquement démarrés. &Run &Démarrer Alt+R Alt+D Run Twinkle with the selected profiles. Démarrer Twinkle avec le profil sélectionné. S&ystem settings Paramètres s&ystème Alt+Y Alt+Y Edit the system settings. Editer les paramètres système. &Cancel Annuler (Es&c) Alt+C Alt+C <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> <html>Avant d'utiliser Twinkle, vous devez créer un profil utilisateur.<br>Cliquez sur OK pour créer un profil.</html> <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>Choose what method you wish to use.</html> <html>Vous pouvez utiliser l'éditeur de profil pour créer un profil. Avec l'éditeur de profil vous pouvez modifier beaucoup de paramètres SIP, RTP et autres.<br><br>Vous pouvez également utiliser l'assistant pour créer un profil plus rapidement. Il vous proposera seulement quelques paramètres essentiels. Vous pourrez éditer ce profil plus tard en utilisant l'éditeur de profil.<br><br>Sélectionnez la méthode que vous préférez (débutants: l'assistant est conseillé).</html> <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> <html>Vous devrez ajuster les paramètres systèmes. Vous pouvez changer ces parmètres à tout moment.<br><br>Cliquez sur OK pour voir et modifier les paramètres systèmes</html> You did not select any user profile to run. Please select a profile. Vous n'avez sélectionné aucun profil à démarrer. Merci de sélectionner un profil. Are you sure you want to delete profile '%1'? Etes-vous sûr de vouloir supprimer le profil '%1' ? Delete profile Supprimer un profil Failed to delete profile. Echec de la suppression de profil. Failed to rename profile. Echec du changement de nom de profil. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> <p>Si vous voulez supprimer ou modifier le profil par défaut, vous pourrez le faire par les paramètres système. </p> Cannot find .twinkle directory in your home directory. Impossible de trouver le dossier .twinkle dans le dossier home. &Profile editor Editeur de &profil Create profile Ed&itor Alt+I Dia&mondcard Alt+M Modify profile Startup profile &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> SelectUserForm Twinkle - Select user Twinkle - Selection d'utilisateur &Cancel Annuler (Es&c) Alt+C &Select all Tout &sélectionner Alt+S Alt+A &OK Alt+O C&lear all Tout &désélectionner Alt+L purpose No need to translate User Utilisateur Register Se connecter Select users that you want to register. Sélectionnez le profil que vous voulez connecter. Deregister Se déconnecter Select users that you want to deregister. Sélectionnez le profil que vous voulez déconnecter. Deregister all devices Déconnecter toutes les interfaces Select users for which you want to deregister all devices. Sélectionnez le profil dont vous voulez déconnecter toutes les interfaces. Do not disturb Ne pas déranger Select users for which you want to enable 'do not disturb'. Sélectionnez le profil dont vous voulez activer "ne pas déranger". Auto answer Réponse automatique Select users for which you want to enable 'auto answer'. Sélectionnez le profil dont vous voulez activer la réponse automatique. SendFileForm Twinkle - Send File Twinkle - Envoi de fichier Select file to send. Choisir le fichier à envoyer. &File: &Fichier: &Subject: &Sujet: &OK &OK Alt+O &Cancel Annuler (Es&c) Alt+C File does not exist. Le fichier n'existe pas. Send file... Envoi de fichier... SrvRedirectForm Twinkle - Call Redirection Twinkle - Redirection d'appel User: Utilisateur: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> Il y a 3 srvices de redirection:<p> <b>Inconditionnel:</b> tous les appels sont redirigés<p> <p> <b>Occupé:</b> Rediriger l'appel si les 2 lignes sont occupées </p> <p> <b>Pas de réponse:</b> redirige un appel quand le décompte "pas de réponse" expire. </p> &Unconditional &Inconditionnel &Redirect all calls &Rediriger tous les appels Alt+R Alt-A Activate the unconditional redirection service. Active le service de redirection inconditionelle. Redirect to Rediriger vers You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Vous pouvez sélectionner jusqu'a 3 destinations vers lesquelles rediriger l'appel. Si la première destionationne répond pas, la deuxième sera essayée et ainsi de suite. &3rd choice destination: &3ème destination: &2nd choice destination: &2ème destination: &1st choice destination: &1ère destination: Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. &Busy &Occupé &Redirect calls when I am busy &Rediriger les appels quand je suis occupé Activate the redirection when busy service. Active le service de redirection "occupé". &No answer &Pas de réponse &Redirect calls when I do not answer &Rediriger les appels quand je ne réponds pas Activate the redirection on no answer service. Active le service de redirection sans réponse. &OK Alt+O Accept and save all changes. Accepter et enregistrer les modifications. &Cancel Annuler (Es&c) Alt+C Undo your changes and close the window. Annuler tous les changements et fermer la fenêtre. You have entered an invalid destination. Vous avez saisi une destination invalide. F10 F11 F12 SysSettingsForm Twinkle - System Settings Twinkle - Paramètres du système General Général Audio Audio Ring tones Sonneries Address book Carnet d'adresse Network Réseau Log Log Select a category for which you want to see or modify the settings. Sélectionnez la catégorie dont vous voulez voir ou modifier les paramètres. Sound Card Carte son Select the sound card for playing the ring tone for incoming calls. Sélectionnez la carte son qui jouera la sonnerie des appels entrants. Select the sound card to which your microphone is connected. Sélectionnez la carte son à laquelle est connecté le microphone. Select the sound card for the speaker function during a call. Sélectionnez la carte son à laquelle est connecté le haut parleur. &Speaker: &Haut-parleur: &Ring tone: &Sonnerie: Other device: Autre interface: &Microphone: &Microphone: When using ALSA, it is not recommended to use the default device for the microphone as it gives poor sound quality. Avec ALSA, il n'est pas recommandé d'utiliser l'interface par défaut pour le microphone car ceci dégrade la qualité du son. Reduce &noise from the microphone Réduire le &bruit du microphone Alt+N Alt+B Recordings from the microphone can contain noise. This could be annoying to the person on the other side of your call. This option removes soft noise coming from the microphone. The noise reduction algorithm is very simplistic. Sound is captured as 16 bits signed linear PCM samples. All samples between -50 and 50 are truncated to 0. L'enregistrement par l'intermédiaire d'un microphone peut contenir du bruit. Ceci peut être génant pour le correspondant. Cette option supprime ce bruit. L'algoritme de réduction de bruit est très simple. Le son est enregistré en échantillons PCM 16 bits linéaires signés. Tous les échantillons entre -50 et 50 sont ramenés à zéro. Advanced Avancé OSS &fragment size: OSS taille du &fragment: 16 32 64 128 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. La période de lecture ALSA influence le comportement en temps réel de votre carte son. Si votre son disparait fréquemment en utilisant ALSA, vous devriez essayer différentes valeurs. ALSA &play period size: ALSA période de &lecture (LS): &ALSA capture period size: ALSA période de &capture (MIC): The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. La taille du fragment OSS influence le comportement en temps réel de votre carte son. Si votre son disparait fréquemment en utilisant OSS, vous devriez essayer différentes valeurs. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. La période de capture ALSA influence le comportement en temps réel de votre carte son. Si votre son disparait fréquemment en utilisant ALSA, vous devriez essayer différentes valeurs. &Max log size: Taille &max. du fichier de log: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. La taille maximum du fichier de log en Mo. Quand le fichier de log excède cette taille, une sauvegarde de ce fichier est effectué et le fichier est supprimé. Seulement un fichier de sauvegarde est conservé. MB Log &debug reports Sauvegarder les rapports de &debug Alt+D Indicates if reports marked as "debug" will be logged. Indique si les rapports marqués "débug" seront archivés. Log &SIP reports Sauvegarder les rapports &SIP Alt+S Indicates if SIP messages will be logged. Indique si les messages SIP douvent être sauvegardés. Log S&TUN reports Sauvegarder les rapports S&TUN Alt+T Indicates if STUN messages will be logged. Indique si les messages STUN douvent être sauvegardés. Log m&emory reports Sauvegarder les rapports &mémoire Alt+E Alt+M Indicates if reports concerning memory management will be logged. Indique si les rapports concernant la gestion mémoire seront archivés. System tray Tableau de bord Create &system tray icon on startup Créer une icone dans le &tableau de bord au démarrage Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. Cochez cette case si vous voulez une icone dans le tableau de bord pour Twinkle. Cette icone est créée au démarrage de Twinkle. &Hide in system tray when closing main window &Rabattre dans le &tableau de bord à la fermeture de la fenêtre principale Alt+H Alt+R Enable this option if you want Twinkle to hide in the system tray when you close the main window. Cochez cette case si vous voulez rabattre Twinkle dans le tableau de bord quand vous fermez la fenêtre principale. Startup Démarrage Next time you start Twinkle, this IP address will be automatically selected. This is only useful when your computer has multiple and static IP addresses. La prochaine fois que vous lancerez Twinkle, cette adresse IP sera automatiquement sélectionnée. Ceci est utile uniquement si votre ordinateur à plusieurs IP statiques. Default &IP address: Adresse &IP par défaut: Next time you start Twinkle, the IP address of this network interface be automatically selected. This is only useful when your computer has multiple network devices. La prochaine fois que vous lancerez Twinkle, l'adresse IP de cette interface réseau sera automatiquement sélectionnée. Ceci est utile uniquement si votre ordinateur à plusieurs interfaces réseau. Default &network interface: &Réseau par défaut: S&tartup hidden in system tray &Démarrer rabattu dans le tableau de bord Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. La prochaine fois que vous lancerez Twinkle, il sera immédiatement rabattu dans le tableau de bord. Ceci fonctionne mieux si vous sélectionnez également un utilisateur par défaut. Default user profiles Profil utilisateur par défaut If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. Si vous utilisez toujours le(s) même(s) profile(s), vous pouvez le(s) définir comme "défaut". La prochaine fois que vous lancerai Twinkle, vous n'aurez pas à sélectionner de profil. Les profils par défaut seront lancés automatiquement. Services Services Call &waiting Mise en &attente Alt+W Alt+A With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. Avec cette option, un appel entrant sera accepté si une ligne est occupée. Si vous désactivez la mise en attente d'appel, un appel entrant sera refusé quand une ligne est occupée. Hang up &both lines when ending a 3-way conference call. Raccrocher les deux lignes à la fin d'une &conférence. Alt+B Alt+C Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. Raccroche les deux lignes quand vous clickez sur le bouton "Fin" lors d'une conférence. Quand cette option est désactivée, seule la ligne active est raccrochée et vous pourvez continuer à parler avec le correspondante de l'autre ligne. &Maximum calls in call history: Nombre d'appels &maximum dans l'historique des appels: The maximum number of calls that will be kept in the call history. Le nombre d'appels maximum qui seront enregistrés dans l'historique des appels. &Auto show main window on incoming call after Affichage &automatiquement de la fenêtre principale lors d'un appel Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Quand la fenêtre principale est cachée, elle sera automatiqument affichée lors d'un appel entrant après le nombre de secondes spécifié. Number of seconds after which the main window should be shown. Délai d'affichage automatique sur appel entrant. secs secs The UDP port used for sending and receiving SIP messages. Le port UDP utilisé pour envoyer et recevoir des messages SIP. &RTP port: Port &RTP: The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. Le port UDP utilisé pour envoyer et recevoir des RTP pour la première ligne. Celui de la seconde est plus grand de 2. Ex: Si le port 8000 est utilisé pour la première ligne, celui de la seconde sera 8002. Quand vous utilisez le transfert d'appel, le port suivant (ex:8004) est alors également utilisé. &SIP UDP port: Port &SIP UDP : Ring tone Sonneries &Play ring tone on incoming call &Sonner lors d'un appel entrant Alt+P Alt+S Indicates if a ring tone should be played when a call comes in. Indique si une sonnerie doit être jouée lors d'un appel entrant. &Default ring tone Sonneries par &défaut Play the default ring tone when a call comes in. Joue la sonnerie par défaut lors d'un appel entrant. C&ustom ring tone Sonnerie &personnalisée Alt+U Alt+P Play a custom ring tone when a call comes in. Joue une sonnerie personnalisée lors d'un appel entrant. Specify the file name of a .wav file that you want to be played as ring tone. Saisissez le nom de fichier .wav que vous voulez utiliser comme sonnerie. Ring back tone Sonneries de tonalité P&lay ring back tone when network does not play ring back tone Jouer une& tonalité quand le réseau ne le fait pas Alt+L Alt+T <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> <p>Joue une tonalité pendant que vous attendez que votre correspondant décroche. </p> <p>Suivant votre fournisseur de service, le réseau peut émettre une tonalité ou une annonce.</p> D&efault ring back tone &Tonalité par défaut Play the default ring back tone. Joue la tonalité par défaut. Cu&stom ring back tone Tonalité p&ersonnalisée Play a custom ring back tone. Joue la tonalité personnalisée. Specify the file name of a .wav file that you want to be played as ring back tone. Saisissez le nom de fichier .wav que vous voulez utiliser comme tonalité. &Lookup name for incoming call &Voir le nom de l'appel entrant Ove&rride received display name Ne pas &tenir compte du nom d'affichage reçu Alt+R Alt+T The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. L'appelant peut avoir défini un nom d'affichage. Cochez cette case si vous voulez le remplacer par celui défini dans votre carnet d'adresse. Lookup &photo for incoming call Visionner la &photo pour l'appel entrant Lookup the photo of a caller in your address book and display it on an incoming call. Visionner la photo de l'appelant dans votre carnet d'adresse et l'afficher pour les appels entrants. &OK Alt+O Accept and save your changes. Accepter et enregistrer les modifications. &Cancel Annuler (Es&c) Alt+C Undo all your changes and close the window. Annuler tous les changements et fermer la fenêtre. none This is the 'none' in default IP address combo aucune none This is the 'none' in default network interface combo aucune Either choose a default IP address or a default network interface. Choisissez soit une adresse IP par défaut soit une interface de réseau. Ring tones Description of .wav files in file dialog Sonneries Choose ring tone Choisir une sonnerie Ring back tones Description of .wav files in file dialog Sonneries de tonalité Choose ring back tone Choisir une sonnerie de tonalité &Validate devices before usage &Valider les interfaces avant d'utiliser Alt+V Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. <p>Twinkle valide l'interface audio avant utilisation pour éviter d'établir un appel sans canal audio.</p> <p>Au démarrage de Twinkle, un avertissement vous prévient si l'interface audio est inaccessible.</p> <p>Si avant de faire un appel, le microphone ou le haut-parleur est invalide, un avertissement s'affiche et l'appel est bloqué.</p> <p>Si avant de répondre à un appel, le microphone ou le haut-parleur est invalide, un avertissement s'affiche et il est impossible de répondre à un appel. On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. Lors d'un appel entrant, Twinkle essaiera de trouve le nom correspondant à l'adresse SIP dans votre carnet d'adresse. Ce nom sera affiché. Select ring tone file. Sélectionner un fichier de sonnerie. Select ring back tone file. Sélectionnez votre sonnerie de tonalité. Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. Taille maximum allouée pour un message SIP entrant en UDP en octets (0-65535). &SIP port: Port &SIP: Max. SIP message size (&TCP): Taille max. du message SIP (&TCP): The UDP/TCP port used for sending and receiving SIP messages. Le port UDP/TCP utilisé pour envoyer et recevoir des messages SIP. Max. SIP message size (&UDP): Taille max. du message SIP (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. Taille maximum allouée pour un message SIP entrant en TCP en octets (0-4294967295). W&eb browser command: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. SysTrayPopup Answer Répondre Reject Refuser Incoming Call TermCapForm Twinkle - Terminal Capabilities Twinkle - Capacités du terminal &From: &De: Get terminal capabilities of Récuperer les possibilités du terminal de &To: &à: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. L'adresse dont vous voulez demandes les possiblités (demande d'OPTIONS). Ceci peut être une adresse SIP comme <b>sip:exemple@exemple.com</b> ou uniquement la partie utilisateur ou le numéro de téléphone d'une adresse complète. Quand vous ne spécifiez pas une adresse complète, Twinkle complètera cette adresse en utilisant le domaine défini dans votre profil utilisateur. Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. &OK &Cancel Annuler (Es&c) F10 TransferForm Twinkle - Transfer Twinkle - Transfert Transfer call to Transférer l'appel vers &To: &à: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. L'adresse de la personne vers que vous voulez transférer l'appel. Ceci peut être une adresse SIP comme <b>sip:exemple@exemple.com</b> ou uniquement la partie utilisateur ou le numéro de téléphone d'une adresse complète. Quand vous ne spécifiez pas une adresse complète, Twinkle complètera cette adresse en utilisant le domaine défini dans votre profil utilisateur. Address book Carnet d'adresse Select an address from the address book. Sélectionner une adresse du carnet d'adresse. &OK Alt+O &Cancel Annuler (Es&c) Type of transfer Type de transfert &Blind transfer Transfert &direct Alt+B Alt+D Transfer the call to a third party without contacting that third party yourself. Transfert l'appel vers un tier sans consultation. T&ransfer with consultation &Transfert avec consultation Alt+R Alt+T Before transferring the call to a third party, first consult the party yourself. Avant de transférer l'appel vous pourrez consulter le tier vous-même. Transfer to other &line Transfert vers l'autre &ligne Alt+L Connect the remote party on the active line with the remote party on the other line. Connecte le correspondant de la ligne active avec le correspondant de l'autre ligne. F10 TwinkleCore Failed to create log file %1 . Impossible de créer le fichier de log %1. Cannot open file for reading: %1 Impossible d'ouvrir le fichier %1 en lecture File system error while reading file %1 . Erreur système pendant la lecture du fichier %1. Cannot open file for writing: %1 Impossible d'ouvrir le fichier %1 en écriture File system error while writing file %1 . Erreur système pendant l'écriture du fichier %1. Excessive number of socket errors. Nombre trop important d'erreurs de socket. Built with support for: Compilé à l'aide de: Contributions: Contributions: This software contains the following software from 3rd parties: Ce logiciel contient les logiciels tiers suivants: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * G.711/G.726 codecs from Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ For RTP the following dynamic libraries are linked: Pour RTP, les librairies dynamiques suivantes sont rattachées: Translated to english by <your name> Traduit en français par:<br> ©20070614 Olivier Aufrère Directory %1 does not exist. Le dossier %1 n'existe pas. Cannot open file %1 . Impossible d'ouvrir le fichier %1. %1 is not set to your home directory. %1 n'est pas paramêtré pour votre dossier home. Directory %1 (%2) does not exist. Le dossier %1 (%2) n'existe pas. Cannot create directory %1 . Impossible de créer le dossier %1. Lock file %1 already exist, but cannot be opened. Le fichier de vérouillage %1 existe déjà mais ne peut être ouvert. %1 is already running. Lock file %2 already exists. %1 en cours d'execution Le fichier de vérouillage %2 existe déjà. Cannot create %1 . Impossible de créer %1. Cannot write to %1 . Impossible d'écrire su %1. Syntax error in file %1 . Erreur de syntaxe dans le fichier %1. Failed to backup %1 to %2 Impossible de sauvegarder %1 sur %2 unknown name (device is busy) nom inconnu (interface utilisée) Default device Interface par défaut Anonymous Anonyme Warning: Attention: Call transfer - %1 Transfert d'appel - %1 Sound card cannot be set to full duplex. La carte son ne peut pas être passée en full duplex. Cannot set buffer size on sound card. Impossible de paramètrer la taille du beffer de la carte son. Sound card cannot be set to %1 channels. Impossible de paramètrer la carte son pour les canaux %1. Cannot set sound card to 16 bits recording. Impossible de paramètrer la carte son en enregistrement 16 bits. Cannot set sound card to 16 bits playing. Impossible de paramètrer la carte son en lecture 16 bits. Cannot set sound card sample rate to %1 Impossible de paramètrer la carte son à un taux de sample %1 Opening ALSA driver failed Echec de l'ouverture d'ALSE Cannot open ALSA driver for PCM playback Impossible d'ouvrir ALSA pour la lecture PCM Cannot resolve STUN server: %1 Impossible de trouver le serveur STUN %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. Vous êtes derrière un NAT symétrique. STUN ne fonctionnera pas. Configurez une adresse IP publique pour votre profil utilisateur et créez les attaches statiques suivantes (UDP) dans votre NAT. public IP: %1 --> private IP: %2 (SIP signaling) IP publique: %1 -> IP privée: %2 (SIP) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) IP publique: %1-%2 -> IP privée: %3-%4 (RTP/RTCP) Cannot reach the STUN server: %1 Impossible d'atteindre le serveur STUN: %1 Port %1 (SIP signaling) Port %1 (SIP) NAT type discovery via STUN failed. Echec de l'identification du type NAT par STUN. If you are behind a firewall then you need to open the following UDP ports. Si vous êtes derrière un firemwall, vous devez ouvrir les ports UDP suivants. Ports %1-%2 (RTP/RTCP) Ports %1-%2 (RTP/RTCP) Cannot access the ring tone device (%1). Impossible d'accéder à l'interface %1 de la sonnerie. Cannot access the speaker (%1). Impossible d'accéder à l'interface %1 du haut-parleur. Cannot access the microphone (%1). Impossible d'accéder à l'interface %1 du microphone. Cannot open ALSA driver for PCM capture Impossible d'ouvrir ALSA pour la capture PCM Cannot receive incoming TCP connections. Impossible de recevoir des connexions TCP entrantes. Failed to create file %1 Echec de la création du fichier %1 Failed to write data to file %1 Echec de l'écriture de données dans %1 Failed to send message. Echec de l'envoi du message. Cannot lock %1 . UserProfileForm Twinkle - User Profile Twinkle - Profil utilisateur User profile: Profil utilisateur: Select which profile you want to edit. Sélectionnez le profil que vous voulez éditer. User Utilisateur SIP server Serveur SIP RTP audio RTP Audio SIP protocol Protocole SIP Address format Format d'adresse Timers Décomptes Ring tones Sonneries Scripts Security Sécurité Select a category for which you want to see or modify the settings. Sélectionnez la catégorie dont vous voulez voir ou modifier les paramètres. &OK Alt+O Accept and save your changes. Accepter et enregistrer les modifications. &Cancel Annuler (Es&c) Alt+C Undo all your changes and close the window. Annuler tous les changements et fermer la fenêtre. SIP account Compte SIP &User name*: Nom d'&utilisateur*: &Domain*: &Domaine*: Or&ganization: Or&ganisation: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. Le nom d'utilisateur SIP donné par votre fournisseur de service. C'est la partie "utilisateur" de votre adresse SIP, <b>utilisateur</b>@domain.com. Ceci peut être un numéro de téléphone. <br><br> Ce champ est obligatoire. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Le domaine de votre adresse SIP, username@<b>domain.com</b>. A la place d'un vrai nom de domaine, il est également possible de saisir le nom de l'hôte ou l'adresse IP de votre <b>proxy SIP</b>. Si vous voulez uniquement des communications de PC à PC, saisissez le nom de l'hôte ou l'adresse IP de votre ordinateur. <br><br> Ce champ est obligatoire. You may fill in the name of your organization. When you make a call, this might be shown to the called party. Vous pouvez remplir le nom de votre organisation. Quand vous ferez un appel, ceci sera montré à votre correspondant. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. C'est simplement votre nom complet, ex: Pierre Dupond. Il est utilisé pour l'affichage. Quand vous ferez un appel, ceci sera montré à votre correspondant. &Your name: &Votre nom: SIP authentication Authentification SIP &Realm: Authentication &name: &Nom d'authentification: &Password: Mot de &passe: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. Le realm pour l'authentification. Cette valeur vous est fournie par votre fournisseur de service SIP. Si vous laissez ce champ vide, Twinkle utilisera le nom d'utilisateur et le mot de passe en cas de demande de realm. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Votre nom d'authentification SIP. Souvent, c'est le même que votre nom d'utilisateur SIP. Cependant, il peut être différent. Your password for authentication. Votre mot de passe d'authentification. Registrar Registrar (Serveur proxy) &Registrar: &Registrar: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. Le nom d'hôte, le nom de domaine ou l'adresse IP de votre fournisseur de service. Si vous utilisez un proxy sortant qui est identique à votre fournisseur de service, vous pouvez laisser ce champ vide et seulement remplir l'adresse du proxy sortant. &Expiry: &Expiration: The registration expiry time that Twinkle will request. Le délai d'expiration de l'établissement de la connexion par Twinkle. Standard: 3600 (=1h). seconds secondes Re&gister at startup Se &connecter au démarrage Alt+G Alt-C Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Indique si Twinkle doit automatiquement se connecter quand cous utilisez ce profil. Vous devrez désactivé ceci en cas de communication directe de téléphone IP à téléphone IP sans passer par proxy SIP. Outbound Proxy Proxy sortant &Use outbound proxy &Utiliser le proxy sortant Alt+U Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Indique si Twinkle doit utiliser un proxy sortant. Si un proxy sortant est utiliser, toutes les demandes SIP sont envoyées par ce proxy. Sans proxy sortant, Twinkle essaiera de résoudre l'adresse SIP que vous avez saisie pour une invitation d'appel, par exemple à une adresse IP et envoie la demande SIP à cette adresse. Outbound &proxy: &Proxy sortant: &Send in-dialog requests to proxy &Envoyer des demandes "in-dialog" au proxy Alt+S Alt+E SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. Les demandes SIP incluses dans un dialogue SIP sont normalement envoyées dans les entêtes de contact échangées pendant l'établissement de l'appel. Si vous cochez cette case, cette adresse est ignorée et les demandes incluses dans le dialog sont également envoyées par le proxy de sortie. &Don't send a request to proxy if its destination can be resolved locally. &Ne pas envoyer une demande au proxy si la destination peut être trouvée locallement. Alt+D Alt+N When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) Quand vous cochez cette case, Twinkle essaiera d'abord de trouver une adresse SIP par une adresse IP. S'il y arrive, la demande SIP sera envoyée par ce mode. Dans le cas contraire, il enverra la demande SIP au proxy (nota: une demande incluse dans un dialogue serra uniquement envoyée au proxy si vous avez également cochez la case précédente) The hostname, domain name or IP address of your outbound proxy. Le nom d l'hôte, le nom de domaine ou l'adresse IP de votre proxy de sortie. Co&decs Codecs Available codecs: Codecs disponibles: G.711 A-law G.711 u-law GSM speex-nb (8 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) List of available codecs. Liste des codecs disponibles. Move a codec from the list of available codecs to the list of active codecs. Active un codec. Move a codec from the list of active codecs to the list of available codecs. Désactive un codec. Active codecs: Codecs actifs: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. Liste des codecs actifs. Ceux sont les codecs qui seront utilisés pour la négociation lors de l'établissement de l'appel. L'ordre des codecs est l'ordre de préférence d'utilisation. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. Monte un codec dans la liste des codecs actifs, i.e. augmente sa priorité d'utilisation. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. Descend un codec dans la liste des codecs actifs, i.e. diminue sa priorité d'utilisation. &G.711/G.726 payload size: &G.711/G.726 taille des données: The preferred payload size for the G.711 and G.726 codecs. La taille des données préférée pour les codecs G.711 et G.726. ms &iLBC iLBC i&LBC payload type: i&LBC Type des données: iLBC &payload size (ms): iLBC &taille des données (ms): The dynamic type value (96 or higher) to be used for iLBC. Le type de valeur dynamique (96 ou plus) devant être utilisé. 20 30 The preferred payload size for iLBC. Taille préférée des données du paquet RTP pour iLBC. &Speex Speex Perceptual &enhancement &Amélioration de la perception Alt+E Alt+A Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). l' "amélioration de la perception" (anglais: perceptual enhancement) est une partie du décodeur qui, quand elle est activée, essaie de réduire la perception du bruit produit par le décodage/encodage. Dans la plupart des cas, ceci rend le son assez différent de l'original, mais le rend plus agréable. &Ultra wide band payload type: Type des données pour la bande &Ultra-Large: Alt+V When enabled, voice activity detection detects whether the audio being encoded is speech or silence/background noise. VAD is always implicitly activated when encoding in VBR, so the option is only useful in non-VBR operation. In this case, Speex detects non-speech periods and encode them with just enough bits to reproduce the background noise. This is called "comfort noise generation" (CNG). En la sélectionnant, la détection de la parole (ie: voice activity detection ou VAD) détecte si le son encodé est de la voix ou du silence (bruit de fond). VAD est toujours implicitement activé en encodage VBR, cette option est donc uniquement utilisable pour les opérations non-VBR. Dans ce cas, Speex detecte les passages sans paroles et les encode avec juste le nombre de bits nécessaire pour reproduire le bruit de fond. Ceci est appelé la "génération de bruit pour le confort" (comfort noise generation CNG). &Wide band payload type: Type des données pour la bande &Large: Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. Variable Bit-Rate (VBR) permet au codec d'ajuster sa bande passante dynamiquement à la difficulté d'encodage du son. Ceci permet à qualité constante, de réduire la bande passante nécessaire. Il y a cependant des désavantages: en ne spécifiant que la qualité, il n'y à aucune garantie sur la bande passante moyenne finallement utilisée; pour certaines applications comme la VOIP, ce qui compte c'est la bande passante maximum, qui doit être la plus basse possible. The dynamic type value (96 or higher) to be used for speex wide band. La valeur dynamique (96 ou plus) à utiliser pour le speex à large bande (RFC 2833). Co&mplexity: Co&mplexité: Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. La transmission discontinue est un ajout à VAD/VBR, qui permet d'arrêter totalement la transmission quand le bruit de fond est stationnaire. The dynamic type value (96 or higher) to be used for speex narrow band. La valeur dynamique (96 ou plus) à utiliser pour le speex à petite bande (RFC 2833). With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. Avec Spexx, il est possible de faire varier le taux de compression de l'encodeur. Ceci est possible en contrôlant comment la recherche est assurée avec un entier entre 1 et 10 d'une manière similaire aux option -1 à -9 de gzip et bzip2. En utilisation normale, le niveau de bruit au taux 1 est entre 1 et 2 dB plus élevé que au taux 10, mais l'utilisation du CPU au taux 10 est 5 fois plus grande que au taux 1. En pratique, Le meilleur compromis est entre 2 et 4, alors que des taux plus élevés sont souvent utilent pour encoder des sons autre que la voix comme les sonneries DTMF. &Narrow band payload type: Type des données pour la bande &Courte: G.726 G.726 &40 kbps payload type: G.726 &40 kb/s Type des données: The dynamic type value (96 or higher) to be used for G.726 40 kbps. La valeur dynamique (96 ou plus) a utiliser pour G.726 40 kb/s. The dynamic type value (96 or higher) to be used for G.726 32 kbps. La valeur dynamique (96 ou plus) a utiliser pour G.726 32 kb/s. G.726 &24 kbps payload type: G.726 &24 kb/s Type des données: The dynamic type value (96 or higher) to be used for G.726 24 kbps. La valeur dynamique (96 ou plus) a utiliser pour G.726 24 kb/s. G.726 &32 kbps payload type: G.726 &32 kb/s Type des données: The dynamic type value (96 or higher) to be used for G.726 16 kbps. La valeur dynamique (96 ou plus) a utiliser pour G.726 16 kb/s. G.726 &16 kbps payload type: G.726 &16 kb/s Type des données: DT&MF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). La valeur dynamique (96 ou plus) à utiliser pour les évenements DTMF (RFC 2833). DTMF vo&lume: &Volume DTMF: The power level of the DTMF tone in dB. Le volume de la sonnerie DTMF en dB. The pause after a DTMF tone. La durée de la pose après la sonnerie DTMF. DTMF &duration: &Durée DTMF: DTMF payload &type: D&TMF Type des données: DTMF &pause: &Pause DTMF: dB Duration of a DTMF tone. Durée d'une sonnerie DTMF. DTMF t&ransport: &Méthode DTMF: Auto RFC 2833 Inband Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> <p><h3>RFC 2833</h3> Envoi une sonnerie DTMF comme un événement de téléphone (RFC 2833).</p> <p><h3>Inband</h3> Sende DTMF inband (tatsächliche Töne, die Twinkle ins Tonsignal einmischt).</p> <p><h3>Auto</h3> Wenn die Gegenstelle RFC 2833 unterstützt, dann DTMF-Töne als RFC 2833 telephone events senden, ansonsten inband.</p> <p><h3>Out-of-band (SIP INFO)</h3> Sende DTMF nur out-of-band via SIP INFO request.</p> General Général Redirection Redirection &Allow redirection &Authoriser la redirection Alt+A Indicates if Twinkle should redirect a request if a 3XX response is received. Indique si Twinkle doit rediriger une demande en cas de réception d'une réponse 3XX. Ask user &permission to redirect Demander la &permission de l'utilisateur avant de rediriger Alt+P Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Indique si Twinkle doit demander à l'utilisateur avant de rediriger une demande en cas de réception d'une réponse 3XX. Max re&directions: Max. re&directions: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. Le nombre maximum de tentatives de redirection d'adresse avant l'abandon. Ceci évite qu'une demande ne soit redirigé indéfiniement. Protocol options Options du protocole Call &Hold variant: Variante d'&attente d'appel: RFC 2543 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. Indique si RFC 2543 (passer l'adresse IP de l'interface dans SDP à 0.0.0.0) ou RFC 3264 (utiliser les attributs de direction dans SDP) est utilisé pour mettre un appel en attente. Allow m&issing Contact header in 200 OK on REGISTER Authorise l'absence de l'&entête de contact dans 200 OK lors de la connexion Alt+I Alt+E A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. Une réponse "200 OK" lors d'une connexion, doit comporter une entête de contact.Cependant, quelques fournisseurs de service, n'incorporent pas d''entête de contact ou en incorpore une erronée. Cette option authorise cette transgression. &Max-Forwards header is mandatory &Max-Forwards-Header onbligatoire Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Selon le RFC3261, l'entête Max-Forwards est obligatoire, mais plusieurs implémentations n'envoient pas cet entête. Si vous cochez cette case, Twinkle rejettera une demande SIP si Max-Forwards est manquant. Put &registration expiry time in contact header Mettre le délai d'expi&ration de la connexion dans l'entête de contact Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. Dans un message REGISTER, le temps d'expiration de la connexion peut être inséré dans l'entête de contact ou dans celle d'expiration. Si vous cochez cette case, il sera inséreé dans celle de contact, dans le cas contraire, dans celle d'expiration. &Use compact header names &Utiliser les nom d'entêtes courts Indicates if compact header names should be used for headers that have a compact form. Indique si un nom d'entête court doit être utilisé pour les entêtes courtes. Allow SDP change during call setup Authoriser les modification SDP pendant l'établissement d'un appel <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> <p>Une UAS SIP doit envoyer un SDP dans une réponse 1XX. Quand l'appel est répondu, l'UAS SIP doit envoyer le même SDP dans une réponse 200 OK selon le RFC 3261. Après réception du SDP, les SDP dans les réponses suivantes seront annulés.</p> <p>En authorisant les modifications de SDP pendant l'appel, Twinkle n'annulera pas les SDP dans les réponses suivantes et modifiera le medium si le SDP a changé.</p> <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> <p>Twinkle crée une entête de contact unique en combinant le nom d'utilisateur et de domaine SIP: <br> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> De cette façon, 2 profils utilisateur ayant le même nom d'utilisateur mais des domaines différents, ont une adresse unique de contact et peuvent ainsi être activé simultanément. </p> <p> Des proxy ne construisent pas l'entête de contact de cette façon. Vous pouvez désactiver cette option pour avoir une entête comme ceci: <br> <tt>&nbsp;user@local_ip</tt> </p> <p> Ce format est utiliser par la plupart des téléphones SIP. </p> &Encode Via, Route, Record-Route as list &Encode Via, Route, Record-Route comme une liste The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. Les entêtes Via-, Route- et Record-Route peuvent être encodé comme une liste séparée par des virgules ou comme des occurrences mulitples de la même entête. SIP extensions extensions SIP &100 rel (PRACK): disabled désactivé supported supporté required requis preferred préféré Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. Indique si l'extension 100rel (PRACK) est supportée:<br><br> <b>désactivée</b>: extension 100rel désactivée <br><br> <b>supportée</b>: 100rel supportée (elle est insérée dans "supported header" d'une INVITE sortante). Le correspondant peut alors exiger un PRACK dans une réponse 1xx. <br><br> <b>requise</b>: 100rel requise (elle est insérée dans "equire header" d'une INVITE sortante). Si une INVITE entrante indique qu'elle supporte 100rel, alors Twinkle exigera un PRACK lors de l'envoi d'une reponse 1xx. Si le correspondant ne supporte pas 100rel, l'appel ne se réalise pas. <br><br> <b>préférée</b>: proche de requise, mais si l'appel échoue suite à l'absence de support de 100rel par le correspondant (420 réponses), une nouvelle tentativce d'appel sans 100rel sera lancée. REFER Call transfer (REFER) Transfert d'appel (REFER) Allow call &transfer (incoming REFER) Authoriser le &transfert d'appel (REFER entrant) Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. Indique si Twinkle doit transferer l'appel en cas de réception d'une demande REFER. As&k user permission to transfer Demander l'aut&horisation d'utilisateur avant de transférer Alt+K Alt+H Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Indique si Twinkle doit demander à l'utilisateur avant de transférer un appel en cas de réception d'une demande REFER. Hold call &with referrer while setting up call to transfer target Mettre l'appel avec un &mandataire en attente pendant l'établissement de l'appel vers le destinataire du transfert Alt+W Alt+M Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Indique si Twinkle doit demander à l'utilisateur avant de mettre l'appel en attente en cas de réception d'une réponse REFER pour un transfert. Ho&ld call with referee before sending REFER Mettre l'appel avec un ma&ndant en attente avant d'envoyer un REFER Alt+L Alt+N Indicates if Twinkle should put the current call on hold when you transfer a call. Indique si twinkle doit mettre l'appel courant en attente pendant un transfert. Auto re&fresh subscription to refer event while call transfer is not finished Ra&fraichir la subsciption au refer automatiquement avant que le transfert d'appel ne soit fini Alt+F While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. Quand l'appel est transféré, le mandant envoie des messages NOTIFY au mandataire à propos de la progression du transfert. Ces messages sont seulement envoyés pendante une courte période dans la durée est déterminée par le mandant. Si vous cochez cette case, le mandataire enverra automatiquement un SUBSCRIBE pour allonger cette durée si elle est trop courte (transfert non terminé). NAT traversal NAT Tranvsersal &NAT traversal not needed &NAT traversal non nécessaire Alt+N Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. Cochez cette case quand il n'y a pas d'interface NAT entre vous et votre proxy SIP, ou quand votre fournisseur de service SIP gère lui même le NAT transversal. &Use statically configured public IP address inside SIP messages &Utiliser une adresse IP publique fixe dans les messages SIP Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Indique si Twinkle doit utiliser l'adresse IP public spécifiée dans le champ suivant dans les messages SIP, i.e. dans les entêtes SIP et dans le corps SDP à la place de l'adresse IP de votre interface réseau (privée).<br><br> En cochant cette case, vous devez créer un mappage NAT. Vous devez mapper les ports RTP sur l'adresse IP public et sur l'adresse IP privée de votre PC. Use &STUN Utiliser &STUN Choose this option when your SIP provider offers a STUN server for NAT traversal. Sélectionez cette option si votre fournisseur de service SIP propose un serveur STUN pour le NAT transversal. S&TUN server: Serveur S&TUN: The hostname, domain name or IP address of the STUN server. Le nom d l'hôte, le nom de domaine ou l'adresse IP du serveur STUN. &Public IP address: Adresse IP &publique: The public IP address of your NAT. L'adresse IP publique de votre NAT. Telephone numbers Numéros de téléphone Only &display user part of URI for telephone number &Afficher seulement la partie utilisateur de l'URI pour un numéro de téléphone If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. Si une URI indique un numéro de téléphone, alors seulement la partie utilisateur sera affichée. Ex: Si un appel arrive depuis sip:123456@twinklephone.com alors seulement "123456" sera affiché. Une URI indique un numérode téléphone si elle contient le paramêtre "user=phone" ou si elle a une partie utilisateur numérique et que vous avez coché la case suivante. &URI with numerical user part is a telephone number Une &URI avec une partie utilisateur numérique est un numéro de téléphone If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. Si vous cochez cette case, Twinkle considère une adresse SIP qui a une partie utilisateur constituée de chiffre,*,#,+ et des symboles spéciaux comme un numéro de téléphone. Dans un message sortant, Twinkle ajoutera le paramètre "user=phone" pour ce type d'URI. &Remove special symbols from numerical dial strings &Supprimer les symboles spéciaux pour les chaines numériques Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. Les numéros de téléphone sont souvent écrit avec des caractères spéciaux pour les rendre plus facile à lire. Quand vous composez ce genre de numéro, les caractères spéciaux doivent être supprimés. Pour vous permettre de copier/coller ce type de numéro, Twinkle supprimera ces caractères à la numérotation. &Special symbols: &Symboles spéciaux: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. Les symboles spéciaux utilisables pour respecter le format usuel des numéros de téléphone mais qui doivent être supprimé à la numérotation. Number conversion Conversion des numéros Match expression Expression de recherche Replace Remplacer <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> <p> Souvent le format des numéros de téléphone que vous devez composer est différent du format eregistré dans votre carnet d'adresse, ex: votre numéro commence par "+" suivi du code pays, mais votre fournisseur de service attend "00" à la plase de "+", ou vous êtes au bureau et tous les numéros sortants doivent être précédés de "0". Vous pouvez spécifier ici une conversion de numéro en expression régulière Perl ou chaine formatée. </p> <p> Pour tous les numéros que vous compsez, Twinkle essaiera de trouver une occurence dans la liste des expressions. Lors de la première concordance, le numéro sera remplacé en suivant le formatage par chaine. Si aucune occurence n'est rencontrée, le numéro reste inchangé. </p> <p> Les règes de conversion des numéro sont également appliquées aux appels entrant. Les numéros seroont donc affichés au format souhaité. </p> <h3>Exemple 1</h3> <p> En considérant que votre code pays est 33 et que vous avez enregistré tous les numéros de votre carnet d'adresse au format internationnal, ex +338712345678. Pour la numéroation des numéro de votre propre pays, vous voulez remplacer "+33" par "0". Pour les numéros à l'étranger, vous voulez remplacer "+" par "00". </p> <p> Voici les règles à créer: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace =(sp)(sp)0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Exemple 2</h3> <p> Au bureau, tous les numéros commençant par 0 doivent recevoir un préfixe 9 pour un appel sortant. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace =(sp)(sp)9$&<br> </tt> </blockquote> Move the selected number conversion rule upwards in the list. Déplacer la règle de conversion sélectionnée vers le haut de la liste. Move the selected number conversion rule downwards in the list. Déplacer la règle de conversion sélectionnée vers le bas de la liste.. &Add &Ajouter Add a number conversion rule. Ajouter une règle de conversion de numéro. Re&move &Supprimer Remove the selected number conversion rule. Supprimer la règle de conversion de numéro sélectionnée. &Edit &Editer Edit the selected number conversion rule. Editer la règle de conversion de numéro sélectionnée.. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. Saisissez ici un numéro de téléphone et appuyer sur le bouton Test pour voir comment il est converti par la liste des règles de conversion de numéros. &Test &Test Test how a number is converted by the number conversion rules. Test la façon de convertir d'un numéro par les règles de conversion. for STUN pour STUN Keep alive timer for the STUN protocol. If you have enabled STUN, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. Garder actif le décompte pour le protocole STUN. Si vous avez activé STUN, Twinkle enverra des paquets à cet intervalle pour garder l'adresse dans votre interface NAT active. When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". Quand un appel entrant est reçu, le décompte est lancé. Si l'utilisateur répond à l'appel, le chronomètre est arrèté. Si le décompte se termine avant que l'utilisateur ne réponde, Twinkle rejettera l'appel avec un message "480 User Not Responding" (L'utilisateur ne répond pas). NAT &keep alive: &STUN NAT-keep-alive: &No answer: &Pas de réponse: Ring &back tone: &Tonalité: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p>Entrez un nom de fichier wav qui sera utilisé comme tonalité pour cette utilisateur.</p> <p>Cette tonalité est prioritaire sur celle définie dans les paramètres système.</p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> <p>Entrez un nom de fichier wav qui sera utilisé comme sonnerie pour cette utilisateur.</p> <p>Cette sonnerie est prioritaire sur celle définie dans les paramètres système.</p> &Ring tone: &Sonnerie: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé au raccrochage. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP de la demande sortante SIP BYE sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <br> <b>SIPREQUEST_METHOD=BYE</b>. <br> <b>SIPREQUEST_URI</b> contient la demande URI de BYE. <br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé en cas d'échec d'appel entrant. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP de la réponse d'échec sortante SIP sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <br> <b>SIPSTATUS_CODE</b> contient le code de statut de la réponse d'échec.<br> <b>SIPSTATUS_REASON</b> contient la raison.<br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé en cas de raccrochage de la part du correspondant. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP de la demande entrante SIP BYE sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <br> <b>SIPREQUEST_METHOD=BYE</b>. <br> <b>SIPREQUEST_URI</b> contient la demande URI de BYE. <br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé quand votre correspondant répond à votre appel. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP d'un 200 OK entrant sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <br> <b>SIPSTATUS_CODE=200</b><br> <b>SIPSTATUS_REASON</b> contient la raison.<br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé quand vous répondez à un appel entrant. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP d'un 200 OK sortant sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <br> <b>SIPSTATUS_CODE=200</b><br> <b>SIPSTATUS_REASON</b> contient la raison.<br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. Call released locall&y: Appel raccroché locale&ment: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé en cas d'échec d'appel sortant. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP de la réponse d'échec entrante SIP sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <br> <b>SIPSTATUS_CODE</b> contient le code de statut de la réponse d'échec.<br> <b>SIPSTATUS_REASON</b> contient la raison.<br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Ce script est appelé quand vous passez un appel. </p> <h3>Variables d'environnement</h3> <p> Les valeurs de toutes les entêtes SIP d'un INVITE sortant sont passées en variables d'environnement à votre script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <br> <b>SIPSTATUS_CODE=INVITE</b><br> <b>SIPREQUEST_URI</b> contient la demande URI de INVITE. <br> <b>TWINKLE_USER_PROFILE</b> contient le nom du profil utilisé. Outgoing call a&nswered: Appel sortant répo&ndu: Incoming call &failed: Appel entrant &manqué: &Incoming call: Appel &entrant: Call released &remotely: Appel &terminé par le correspondant: Incoming call &answered: Appel entrant répo&ndu: O&utgoing call: Appel &sortant: Out&going call failed: Appel entrant &échoué: &Enable ZRTP/SRTP encryption Activer la cryptographie &ZRTP/SRTP When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. Quand ZRT/SRTP est activé, Twinkle essaiera de crypter les appels que vous émettez ou recevez. L'encodage ne réussira que si le correspondant accepte le ZRTP/SRTP. Dans le cas contraire l'appel ne sera pas crypté. ZRTP settings Paramètres ZRTP O&nly encrypt audio if remote party indicated ZRTP support in SDP Encoder &seulement si le correspondant accepte le ZRTP en SDP A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. Un terminal SIP supportant ZRTP doit l'indiquer pendant l'établissement de l'appel. En cochant cette case, Twinkle n'encryptera les appels que si le correspondant indique qu'il accepte le ZRTP. &Indicate ZRTP support in SDP &Indiquer le support de ZRTP dans SDP Twinkle will indicate ZRTP support during call setup in its signalling. Twinkle indiquera qu'il accepte le ZRTP dans sa signature pendant l'établissement de l'appel. &Popup warning when remote party disables encryption during call Afficher un &avertissement quand le correspondant désactive la cryptographie pendant l'appel A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. Un correspondant d'un appel encrypté doit envoyer une commande de fin ZRTP (go-clear) pour arréter la cryptographie. Quand Twinkle reçoit cette commande, un avertissement s'affichera si cette case est cochée. Dynamic payload type %1 is used more than once. Le type %1 de charge utile dynamique est utilisé plu d'une fois. You must fill in a user name for your SIP account. Vous devez saisir un nom d'utilisateur pour votre compte SIP. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Vous devez saisir un nom de domaine pour votre compte SIP. il est également possible de saisir le nom de l'hôte ou l'adresse IP de votre PC si vous voulez faire des appels directs de PC à PC. Invalid user name. Nom d'utilisateur invalide. Invalid domain. Domaine invalide. Invalid value for registrar. Registrar invalde. Invalid value for outbound proxy. Proxy sortant invalide. Value for public IP address missing. Absence d'adresse IP publique. Invalid value for STUN server. Absence de valeur pour le serveur STUN. Ring tones Description of .wav files in file dialog Sonneries Choose ring tone Choisir une sonnerie Ring back tones Description of .wav files in file dialog Sonneries de tonalité All files Tous les fichiers Choose incoming call script Sélectionner le scipt d'appel entrant Choose incoming call answered script Sélectionner le scipt d'appel entrant répondu Choose incoming call failed script Sélectionner le scipt d'appel entrant échoué Choose outgoing call script Sélectionner le scipt d'appel sortant Choose outgoing call answered script Sélectionner le scipt d'appel sortant répondu Choose outgoing call failed script Sélectionner le scipt d'appel sortant échoué Choose local release script Sélectionner le scipt de raccrochage local Choose remote release script Sélectionner le scipt de raccrochage local distant Voice mail Boîte vocale &Follow codec preference from far end on incoming calls &Suivre la préférence de codec du correspondant pour les appels entrants <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. Choisit le premier codec de la demande SDP qui est également dans la liste des codecs actifs.<br> Si vous désactivez cette option, c'est le premier codec de la liste des codecs actifs qui est également dans la demande SDP qui est choisi. Follow codec &preference from far end on outgoing calls &Suivre la préférence de codec du correspondant pour les appels sortants <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. Choisit le premier codec de la réponse SDP qui est également dans la liste des codecs actifs.<br> Si vous désactivez cette option, c'est le premier codec de la liste des codecs actifs qui est également dans la réponse SDP qui est choisi. Codeword &packing order: Ordre de compression du codec (codeword &packing order): RFC 3551 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. Il existe 2 standards de compression pour le codec G726 dans un paquet RTP. RFC 3551 est la compression par défaut. Quelques interfaces SIP utilisent ATM AAL2. Si vous avez une mauvaise qualité en G726 avec la compression RFC 3551, utilisez ATM AAL2. Replaces Remplace Indicates if the Replaces-extenstion is supported. Indique si Replaces-Extension est supporté. Attended refer to AoR (Address of Record) Refer avec consultation vers "Address of Record" An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. Un transfert avec consultation doit utiliser l'URI du contact comme cible du refer. Cependant, une URI de contact ne doit pas être routable. L'AoR doit être utlisée à la place. Un incovéniant est que l'AoR peut router vers plusieurs destinataires alors que l'URI de contact route vers un destinataire unique. Privacy Confidentialité Privacy options Options de confidentialité &Send P-Preferred-Identity header when hiding user identity &Envoyer "P-Preferred-Identity Header" quand l'identité est cachée Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. Inclure un "P-Preferred-Identity Header" à votre identité dans une demande INVITE pour un appel à l'identité cachée. <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Vous pouvez personnaliser la façon dont Twinkle gère les appels entrants. Twinkle peut appel un script quand un appel arriver. Sur la base de la sortie du script, Twinkle accepte, rejette ou redirige l'appel. Si l'appel est accepté, la sonnerie peut également être presonnalisée par un script. Le script peut être un programme executable. </p> <p> <b>Nota:</b> Twinkle est suspendu pendant que votre script tourne. Il est recommandé que votre script ne dure pas plus de 200 ms. Quand vous avez besoin de plus de temps, vous pouvez envoyer les paramètres suivis de <b>end</b> et continuer d'executer. Twinkle continuera quand il recevra le paramètre <b>end</b>.(new line) </p> <p> Avec votre script vous pouvez personnaliser la gestion d'appel en renvoyant un ou plusieurs des paramètres suivants à stdout. Chaque paramètre doit être sur un ligne différente. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;adresse de redirection&gt;<br> caller_name=&lt;non de l'appelant à afficher&gt;<br> ringtone=&lt;nom de fichier wav&gt;<br> display_msg=&lt;message à afficher sur l'écran&gt;<br> end<br> </tt> </blockquote> </p> <h2>Paramètres</h2> <h3>action</h3> <p> <b>continue</b> - poursuivre la gestion d'appel comme d'habitude<br> <b>reject</b> - rejeter l'appel<br> <b>dnd</b> - rejeter l'appel avec un message "ne pas derranger"<br> <b>redirect</b> - rediriger l'appel vers l'adresse de<b>contact</b><br> <b>autoanswer</b> - répondre automatiquement à l'appel<br> </p> <p> Quand le script ne renvoie pas d'action à stdout, alors l'action par défaut se poursuit. </p> <p> <b>reason: </b> Avec le paramètre "reason" vous pouvez affecter la valeur "reject" ou "dnd". Ce sera montré au correspondant. </p> <p> <b>caller_name: </b> Ce paramètre ne tient pas compte du nom l'appelant affiché. </p> <p> <b>ringtone: </b> Ce paramètre indique quel fichier wav utiliser comme sonnerie. </p> <h2>Environment variables</h2> <p> Les valeurs de toutes les entêtes SIP d'un message INVITE entrant sont passées en variable d'environnement à votre script. Les nom de varibles sont les suivants:<b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contien le valeur de l'entête from. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. la demande URI d'une INVITE sera dans <b>SIPREQUEST_URI</b>. le nom du profile utilisateur sera dans: <b>TWINKLE_USER_PROFILE</b>. &Voice mail address: Adresse de la &boîte vocale: The SIP address or telephone number to access your voice mail. L'adresse SIP ou le numéro de téléphone pour accéder à votre boît vocale. Unsollicited Non désiré Sollicited RFC 3842 <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> <H2>Type de message en attente</H2>(new line) <p>(new line) Si votre fournisseur de service propose la signalisation d'un message d'attente , Twinkle peut vous indiquer qu'un nouveau message est arrivé. Demander à votre fournisseur, quel type de signalisation est fourni.(new line) </p>(new line) <H3>Non sollicité</H3>(new line) <p>(new line) Signalisation de message en attente non sollicité .(new line) </p>(new line) <H3>Sollicité</H3>(new line) <p>(new line) Signalisation de message en attente sollicité com spécifié par le RFC 3842.(new line) </p> &MWI type: Type &MWI: Sollicited MWI RFC 3842 Subscription &duration: &durée de souscription: Mailbox &user name: Nom d'&utilisateur de boîte vocale: The hostname, domain name or IP address of your voice mailbox server. Le nom d l'hôte, le nom de domaine ou l'adresse IP du serveur de boîte vocale. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Pour le RFC 3842 MWI sollicité, un terminal souscrit au message de statut pour une durée limité. Juste avant l'expiration le terminal doit raffraichir la subcription. Your user name for accessing your voice mailbox. Votre nom d'utilisateur de boîte vocale. Mailbox &server: &Server de boîte vocale: Via outbound &proxy Via &proxy sortant Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. Cocher cette case si Twinkle doit envoyer les messages au serveur de boîte vocale par un proxy sortant. You must fill in a mailbox user name. Vous devez saisir un nom d'utilisateur de boîte vocale. You must fill in a mailbox server Vous devez saisir un nom de serveur de boîte vocale Invalid mailbox server. Serveur de boîte vocale invalide. Invalid mailbox user name. Nom d'utilisateur de boîte vocale invalide. Use domain &name to create a unique contact header value Utiliser le &nom de domaine pour créer une valeur unique de l'entête de contact Select ring back tone file. Sélectionnez votre sonnerie de tonalité. Select ring tone file. Sélectionner un fichier de sonnerie. Select script file. Sélectionner un script. %1 converts to %2 %1 convertit en %2 Instant message Message instantané Presence Présence &Maximum number of sessions: Nombre &maximum de sessions: When you have this number of instant message sessions open, new incoming message sessions will be rejected. Quand ce nombre de sessions de message instantané est atteint, les nouvelles sessions de message entrant seront rejetées. Your presence Votre présence &Publish availability at startup &Publier la disponibilité au démarrage Publish your availability at startup. Publier la disponibilité au démarrage. Buddy presence Présence d'avatar Publication &refresh interval (sec): Intervalle d'&actualisation de la publication (sec): Refresh rate of presence publications. Période d'actualisation de la publication de votre présence. &Subscription refresh interval (sec): Intervalle d'&actualisation de la connexion (sec): Refresh rate of presence subscriptions. Période d'actualisation de la connexion. Transport/NAT Transport/NAT Add q-value to registration Ajouter la q-value à la connexion The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. La q-value indique la priorité de l'interface connectée. Si en plus de Twinkle, vous connectez une autre interface SIP pour ce compte, alors le réseau utilisera ces valeurs pour déterminer quelle interface tester en premier pour effectuer un appel. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. La q-value est une valeur comprise ent 0.000 et 1.000. Une valeur superieure signifie une priorité plus importante. SIP transport Transport SIP UDP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. Mode de transport SIP. En mode auto, la taille du message détermine quel protocole de transport utiliser. Les messages plus grand que la limite de l'UDP sont envoyés via TCP. T&ransport protocol: Protocole de T&ransport: UDP t&hreshold: &Limite UDP: bytes octets Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. Les messages plus grand que la limite sont envoyés via TCP. Les messages plus petits sont envoyés via UDP. Use &STUN (does not work for incoming TCP) Utiliser &STUN (ne fonctionne pas pour le TCP entrant) P&ersistent TCP connection Connexion TCP p&ercistante Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. Conserve la connexion TCP pendant l'ouverture de l'enregistrement de façon à ce que le proxy SIP puisse réutiliser cette connexion pour envoyer des requêtes. Des ping sont enoyés pour tester si la connexion est toujours en établie. &Send composing indications when typing a message. &Envoi de l'indication composite en un message. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. Twinkle envoie une indication composite quand vous écrivez un message. Ainsi, l'interlocuteur peut voir que vous êtes en train d'écrire un message. AKA AM&F: AKA AM&F: A&KA OP: A&KA OP: Authentication management field for AKAv1-MD5 authentication. Champ de gestion de l'authentification en AKAv1-MD5. Operator variant key for AKAv1-MD5 authentication. Clé de l'opérateur en AKAv1-MD5. Prepr&ocessing Préinterprétati&on Preprocessing (improves quality at remote end) La préinterpretation améliore la qualité distante &Automatic gain control Contrôle &automatique du gain Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Le contrôle automatique du gain (AGC) tient compte de la possible variation importante du volume d'enregistrement entre deux paramètres. L'AGC permet d'ajuste le volume de référence. Ceci est très pratique car il supprime la nécessité d'ajuster le gain du microphone manuellement. Un autre avantage est de permettre de régler le gain du microphone à un niveau assez bas pour éviter les coupures. Automatic gain control &level: &Niveau du contrôle automtaique du gain: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. Ce niveau représente un pourcentage du gain du microphone. La valeur recommandée est 25%. &Voice activity detection Détection de l'activité de la &voix When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. La détection de l'activité détecte si le signal d'entrée est de la parole ou du silence/bruit de fond et ne transmet pas ce bruit. &Noise reduction Réduction du &bruit The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. La réduction du bruit peut être utilisée pour réduire le niveau de bruit de fond dans le signal d'entrée. Ceci améliore la qualité du son. Acoustic &Echo Cancellation Suppression de l'&Echo In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Dans toute communication VOIP, si le son venant du correspondant est sur amplificateur, il est enregistré par le microphone. Si le son enregistré par le micropohne est directement envoyé au correspondant, alors il entend sa voix en écho. La suppression de l'écho est consue pour supprimer cet écho avant qu'il ne soit transmis. Il est important de comprendre que la suppression de l'écho est consue pour améliorer la qualite du son pour le correspondant. Variable &bit-rate Taux de compression varia&ble Discontinuous &Transmission &Transmission discontinue &Quality: &Qualité: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. Speex est un codec à perte, ce qui signifie qu'il assure la compression au dépend de la fidélité au son d'entrée. A la différence de quelques autres codecs, il est possible de contrôler l'équilibre entre qualité et compression. Le pocessus d'encodage Speex est contrôlé la plupart du temps par un paramêtre de qualité entre 0 et 10. bytes octets Use tel-URI for telephone &number Utiliser tel-URI comme &numéro de téléphone Expand a dialed telephone number to a tel-URI instead of a sip-URI. Transcrit un numéro de téléphone entré en tel-URI et non en sip-URI. Accept call &transfer request (incoming REFER) Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. Enable NAT &keep alive Send UDP NAT keep alive packets. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. WizardForm Twinkle - Wizard Twinkle - Assitant The hostname, domain name or IP address of the STUN server. Le nom d l'hôte, le nom de domaine ou l'adresse IP du serveur STUN. S&TUN server: Serveur S&TUN: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. Le nom d'utilisateur SIP donné par votre fournisseur de service. C'est la partie "utilisateur" de votre adresse SIP, <b>utilisateur</b>@domain.com. Ceci peut être un numéro de téléphone. <br><br> Ce champ est obligatoire. &Domain*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. Sélectionnez votre fournisseur de service SIP. S'il n'es pas dans la liste, sélectionnez <b>Autre</b> et remplissez les paramètres que vous avez reçu de votre fournisseur.<br><br> Si vous sélectionnez un des fournisseurs prédéfinis, vous n'avez qu'à saisir votre nom, nom d'utilisateur, nom d'authentification, et mot de passe. &Authentication name: Nom d'&authentification: &Your name: &Votre nom: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Votre nom d'authentification SIP. Souvent il est le même que votre nom d'utilisateur SIP. Cependant, il peut être différent. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Le domaine de votre adresse SIP, username@<b>domain.com</b>. A la place d'un vrai nom de domaine, il est également possible de saisir le nom de l'hôte ou l'adresse IP de votre <b>proxy SIP</b>. Si vous voulez uniquement des communications de PC à PC, saisissez le nom de l'hôte ou l'adresse IP de votre ordinateur. <br><br> Ce champ est obligatoire. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. C'est simplement votre nom complet, ex: Pierre Dupond. Il est utilisé pour l'affichage. Quand vous ferez un appel, ceci sera montré à votre correspondant. SIP pro&xy: Pro&xy SIP: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. Le nom d'hôte, le nom de domaine ou l'adresse IP de votre proxy SIP. Si c'est le même valeur que votre domaine, vous pouvez laisser ce champ vide. &SIP service provider: Fournisseur de service &SIP: &Password: Mot de &passe: &User name*: Nom d'&utilisateur*: Your password for authentication. Votre mot de passe pour authentification. &OK Alt+O &Cancel Annuler (Es&c) Alt+C None (direct IP to IP calls) Aucun (appels directs d'IP à IP) Other Autre User profile wizard: Assistant pour profil utilisateur: You must fill in a user name for your SIP account. Vous devez saisir un nom d'utilisateur pour votre compte SIP. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Vous devez saisir un nom de domaine pour votre compte SIP. il est également possible de saisir le nom de l'hôte ou l'adresse IP de votre PC si vous voulez faire des appels directs de PC à PC. Invalid value for SIP proxy. Valeur invalide pour le proxy SIP. Invalid value for STUN server. Valeur invalide pour le serveur STUN. YesNoDialog &Yes &Oui &No &Non twinkle-1.4.2/src/gui/lang/twinkle_nl.ts0000644000175000001440000100666311151060343015130 00000000000000 AddressCardForm Twinkle - Address Card Twinkle - Adres &Remark: Op&merkingen: Infix name of contact. Tussenvoegsel. First name of contact. Voornaam. &First name: Voor&naam: You may place any remark about the contact here. Hier kunt u opmerkingen kwijt. &Phone: &Telefoon: &Infix name: Tu&ssenvoegsel: Phone number or SIP address of contact. Telefoonnummer of SIP adres. Last name of contact. Achternaam. &Last name: &Achternaam: &OK &OK Alt+O &Cancel Ann&uleren Alt+C Alt+U You must fill in a name. U moet een naam invullen. You must fill in a phone number or SIP address. U moet een telefoonnummer of SIP adres invullen. AuthenticationForm Twinkle - Authentication Twinkle - Authenticatie The user for which authentication is requested. De gebruiker waarvoor authenticatie vereist is. The user profile of the user for which authentication is requested. Het gebruikersprofiel van de gebruiker. User profile: Gebruikersprofiel: User: Gebruiker: &Password: &Paswoord: Your password for authentication. Uw paswoord voor authenticatie. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Uw SIP gebruikersnaam voor authenticatie. Meestal is dit hetzelfde als uw SIP gebruikersnaam. &User name: &Gebruikersnaam: &OK &OK &Cancel Ann&uleren Login required for realm: Realm: The realm for which you need to authenticate. De "realm" waarvoor u zich moet authenticeren. user No need to translate profile No need to translate realm No need to translate BuddyForm Twinkle - Buddy Twinkle - Vriend Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. &Phone: &Telefoon: Name of your buddy. Naam van uw vriend. &Show availability &Toon beschikbaarheid Alt+S Alt+T Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. Vink deze optie aan als u de beschikbaarheid van uw vriend wilt zien. Dit werkt alleen als uw provider een presence agent heeft. &Name: &Naam: SIP address your buddy. SIP adres van uw vriend. &OK &OK Alt+O &Cancel Ann&uleren Alt+C Alt+U You must fill in a name. U moet een naam invullen. Invalid phone. Foutief telefoonnummer. Failed to save buddy list: %1 Opslaan van vriendenlijst is mislukt: %1 BuddyList Availability Beschikbaarheid unknown onbekend offline offline online online request rejected verzoek geweigerd not published niet gepubliceerd failed to publish publicatie mislukt request failed verzoel mislukt Click right to add a buddy. Klik rechts om een vriend toe te voegen. CoreAudio Failed to open sound card Openen geluidskaart mislukt Failed to create a UDP socket (RTP) on port %1 UDP socket (RTP) creatie op port %1 mislukt Failed to create audio receiver thread. Creatie van audio receiver thread mislukt. Failed to create audio transmitter thread. Creatie van audio transmitter thread mislukt. CoreCallHistory local user lokale partij remote user andere partij failure fout unknown onbekend in in out uit DeregisterForm Twinkle - Deregister Twinkle - Deregistreren deregister all devices deregistreer alle apparaten &OK &OK &Cancel Ann&uleren DiamondcardProfileForm Twinkle - Diamondcard User Profile Twinkle - Diamondcard gebruikersprofiel <p>With a Diamondcard account you can make worldwide calls to regular and cell phones. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> <p>Met een Diamondcard account kunt u wereldwijd bellen naar vaste en mobiele telefoons. U kunt zich aanmelden voor een Diamondcard account door op de onderstaande "aanmelden" link te klikken. Na aanmelding ontvangt u een account ID en PIN code. Voer dit account ID en de PIN code hieronder in om een Twinkle gebruikersprofiel voor uw Diamondcard account te maken.</p> <p>Beltarieven kunt u vinden op de aanmeldingspagina die u krijgt als u op de "aanmelden" link klinkt.</p> Your Diamondcard account ID. Uw Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Dit is uw eigen naam. bijv. Jan Jansen. Als u iemand belt, kan deze naam getoond worden. &Account ID: &Account ID: &PIN code: &PIN code: &Your name: U&w naam: <p align="center"><u>Sign up for a Diamondcard account</u></p> <p align="center"><u>Aanmelden voor een Diamondcard account</u></p> &OK &OK Alt+O &Cancel Ann&uleren Alt+C Fill in your account ID. Vul uw account ID in. Fill in your PIN code. Vul uw PIN code in. A user profile with name %1 already exists. Een gebruikersprofiel met de naam %1 bestaat al. Your Diamondcard PIN code. Uw Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> <p>Met een Diamondcard account kunt u wereldwijd bellen naar vaste en mobiele telefoons en SMS berichten versturen. U kunt zich aanmelden voor een Diamondcard account door op de onderstaande "aanmelden" link te klikken. Na aanmelding ontvangt u een account ID en PIN code. Voer dit account ID en de PIN code hieronder in om een Twinkle gebruikersprofiel voor uw Diamondcard account te maken.</p> <p>Beltarieven kunt u vinden op de aanmeldingspagina die u krijgt als u op de "aanmelden" link klinkt.</p> DtmfForm Twinkle - DTMF Twinkle - DTMF Keypad Toetsen 2 2 3 3 Over decadic A. Normally not needed. A (normaal niet nodig). 4 4 5 5 6 6 Over decadic B. Normally not needed. B (normaal niet nodig). 7 7 8 8 9 9 Over decadic C. Normally not needed. C (normaal niet nodig). Star (*) Ster (*) 0 0 Pound (#) Hekje (#) Over decadic D. Normally not needed. D (normaal niet nodig). 1 1 &Close &Sluiten Alt+C Alt+S FreeDeskSysTray Show/Hide Toon/Verberg Quit Afsluiten GUI Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Geen netwerkverbinding gevonden. Twinkle gebruikt nu 127.0.0.1 als lokaal IP adres. Als u weer een netwerkverbinging heeft, dan moet u Twinkle opnieuw starten om het correcte IP adres te gebruiken. Terminal capabilities of %1 Terminal eigenschappen van %1 unknown onbekend none geen %1, registration failed: %2 %3 %1, registratie mislukt: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, registratie geslaagd (duur = %2 seconden) %1, registration failed: STUN failure %1, registratie mislukt: STUN fout %1, de-registration succeeded: %2 %3 %1, deregistratie gesglaagd: %2 %3 %1, fetching registrations failed: %2 %3 %1, opvragen registraties mislukt: %2 %3 : you are not registered : u bent niet geregistreerd : you have the following registrations : u heeft de volgende registraties : fetching registrations... : opvragen registraties... Redirecting request to: %1 Verzoek doorgewezen naar: %1 invalid DTMF telephone event (%1) foutief DTMF signaal (%1) Redirecting call Gesprek doorverwezen User profile: Gebruikersprofiel: User: Gebruiker: Do you allow the call to be redirected to the following destination? Staat u toe dat u wordt doorverwezen naar de volgende bestemming? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. Als u deze vraag niet meer wilt zien, dan kunt u dit aangeven in de SIP protocol instellingen van uw gebruikersprofiel. Redirecting request Verzoek doorverwezen Do you allow the %1 request to be redirected to the following destination? Staat u toe dat het %1 verzoek wordt doorverwezen naar de volgende bestemming? Transferring call Gesprek doorverbonden Request to transfer call received from: Verzoek om gesprek door te verbinden van: Do you allow the call to be transferred to the following destination? Staat u toe dat u wordt doorverbonden naar de volgende bestemming? Info: Info: Warning: Waarschuwing: Critical: Ernstige fout: Firewall / NAT discovery... Firewall / NAT verkennen... Abort Afbreken Line %1 Lijn %1 Click the padlock to confirm a correct SAS. Klik op het hangslot om een juiste SAS te bevestigen. The remote user on line %1 disabled the encryption. De andere partij op lijn %1 heeft encryptie uitgeschakeld. Failed to start conference. Starten van conferentie mislukt. You can only run multiple profiles for different users. U kunt alleen meerdere profielen voor verschillende gebruikers starten. Line %1: incoming call for %2 Lijn %1: inkomend gesprek voor %2 Call transferred by %1 Gesprek doorverbonden door %1 Line %1: far end cancelled call. Lijn %1: andere partij heeft gesprek geannuleerd. Line %1: far end released call. Lijn %1: andere partij heeft gesprek beëindigd. Line %1: SDP answer from far end not supported. Lijn %1: SDP van andere partij wordt niet ondersteund. Line %1: SDP answer from far end missing. Lijn %1: SDP van andere partij ontbreekt. Line %1: Unsupported content type in answer from far end. Lijn %1: niet-ondersteunde "content type" ontvangen van andere partij. Line %1: no ACK received, call will be terminated. Lijn %1: geen ACK ontvangen, gesprek wordt afgebroken. Line %1: no PRACK received, call will be terminated. Lijn %1: geen PRACK ontvangen, gesprek wordt afgebroken. Line %1: PRACK failed. Lijn %1: PRACK mislukt. Line %1: failed to cancel call. Lijn %1: annuleren van gesprek is mislukt. Line %1: far end answered call. Lijn %1: gesprek beantwoord. Line %1: call failed. Lijn %1: gesprek mislukt. The call can be redirected to: U kunt het nogmaals proberen naar: Line %1: call released. Lijn %1: gesprek beëindigd. Line %1: call established. Lijn %1: gesprek verbonden. Accepted body types: Geaccepteerde "body" typen: Accepted encodings: Geaccepteerde encoderingen: Accepted languages: Geaccepteerde talen: Supported extensions: Ondersteunde extensies: End point type: Toesteltype: Line %1: call retrieve failed. Lijn %1: terughalen gesprek mislukt. Line %1: redirecting request to Lijn %1: verzoek doorverwezen naar Line %1: send DTMF %2 Lijn %1: stuur DTMF %2 Line %1: far end does not support DTMF telephone events. Lijn %1: andere partij ondersteund geen DTMF "telephone events". Line %1: received notification. Lijn %1: notificatie ontvangen. Event: %1 Gebeurtenis: %1 State: %1 Toestand: %1 Reason: %1 Reden: %1 Progress: %1 %2 Voortgang: %1 %2 Line %1: call transfer failed. Lijn %1: doorverbinden gesprek mislukt. Line %1: call succesfully transferred. Lijn %1: doorverbinden gesprek geslaagd. Line %1: call transfer still in progress. Lijn %1: nog steeds bezig met doorverbinden gesprek. No further notifications will be received. Er komen geen notificaties meer. Line %1: transferring call to %2 Lijn %1: doorverbinden gesprek met %2 Transfer requested by %1 Verzoek tot doorverbinden door %1 Line %1: Call transfer failed. Retrieving original call. Lijn %1: doorverbinden mislukt. Oorspronkelijk gesprek wordt teruggehaald. Line %1: SAS confirmed. Lijn %1: SAS bevestigd. Line %1: SAS confirmation reset. Lijn %1: SAS bevestiging gewist. Line %1: call rejected. Lijn %1: gesprek afgewezen. Line %1: call redirected. Lijn %1: gesprek doorverwezen. Response on terminal capability request: %1 %2 Antwoord op verzoek om terminal eigenschappen: %1 %2 The following profiles are both for user %1 De volgende profielen zijn beiden voor gebruiker %1 Allowed requests: Toegestane verzoeken: Line %1: DTMF detected: Lijn %1: DTMF gedetecteerd: Failed to create a UDP socket (SIP) on port %1 Opzetten UDP socket (SIP) op port %1 mislukt Override lock file and start anyway? Wilt u het lock bestand overschrijven en opstarten? %1, voice mail status failure. %1, voice mail status fout. %1, voice mail status rejected. %1, voice mail status geweigerd. %1, voice mailbox does not exist. %1, voice mailbox bestaat niet. %1, voice mail status terminated. %1, voice mail status beëindigd. %1, STUN request failed: %2 %3 %1, STUN verzoek mislukt: %2 %3 %1, STUN request failed. %1, STUN verzoek mislukt. %1, de-registration failed: %2 %3 %1, deregistratie mislukt: %2 %3 Request to transfer call received. Verzoek om gesprek door te verbinden. If these are users for different domains, then enable the following option in your user profile (SIP protocol) Als dit gebruikers in verschillende domeinen zijn, dan moet u de volgende optie in uw gebruikersprofiel (SIP protocol) aanzetten Use domain name to create a unique contact header Gebruik domeinnaam voor een unieke contact header Failed to create a %1 socket (SIP) on port %2 SIP %1 poort kan niet geopend worden Accepted by network Geaccepteerd door netwerk Failed to save message attachment: %1 Opslaan van bijlage %1 mislukt Transferred by: %1 Doorverbonden door: %1 Cannot open web browser: %1 Web browser kan niet geopend worden: %1 Configure your web browser in the system settings. Configureer uw web browser in de systeeminstellingen. GetAddressForm Twinkle - Select address Twinkle - Kies adres Name Naam Type Type Phone Telefoon &Show only SIP addresses &Toon alleen SIP adressen Alt+S Alt+T Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". Vink deze optie aan als u alleen contacten met een SIP adres wilt zien, d.w.z. adressen die starten met "<b>sip:</b>". &Reload &Herladen Alt+R Alt+H Reload the list of addresses from KAddressbook. Haal de adressen opnieuw op uit KAddressbook. &OK &OK Alt+O Alt+O &Cancel Ann&uleren Alt+C Alt+U &KAddressBook &KAddressBook This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. Deze lijst met adressen komt uit <b>KAddressBook</b>. Contacten waarvoor u geen telefoonnummer heeft opgenomen staan niet in deze lijst. Om adresinformatie te wijzigen moet u KAddressBook gebruiken. &Local address book &Lokaal adresboek Remark Opmerkingen Contacts in the local address book of Twinkle. Adresgegevens uit het lokale adresboek van Twinkle. &Add To&evoegen Alt+A Alt+E Add a new contact to the local address book. Voeg een adres toe aan het lokale adresboek. &Delete &Verwijderen Alt+D Alt+V Delete a contact from the local address book. Verwijder een adres uit het lokale adresboek. &Edit &Bewerk Alt+E Alt+B Edit a contact from the local address book. Wijzig adresgegevens. <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> <p>U heeft geen contacten met een telefoonnummer in <b>KAddressBook</b>, KDE's adresboek applicatie. Twinkle haalt alle contacten met een telefoonnummer uit KAdressBook. Om uw contacten te beheren, moet u KAddressbook gebruiken.</p> <p>Als alternatief kunt u het lokale adresboek van Twinkle gebruiken.</p> GetProfileNameForm Twinkle - Profile name Twinkle - Profielnaam &OK &OK &Cancel Ann&uleren Enter a name for your profile: Voer de naam voor uw profiel in: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> <b>De naam van uw profiel</b> <br><br> Een profiel bevat uw gebruikersinstellingen, bijv. uw gebruikersnaam en paswoord. U moet elk profiel een naam geven. <br><br> Als u meerde SIP accounts heeft, dan kunt u meerdere profielen maken. Als u Twinkle opstart dan krijgt u een lijst met alle profielnamen te zien. Uit deze lijst kunt u kiezen welk profiel u wilt starten. <br><br> Om uw gebruikersprofielen makkelijk uit elkaar te houden kunt u uw SIP gebruikersnaam als profielnaam gebruiken, bijv. <b>example@example.com</b> Cannot find .twinkle directory in your home directory. .twinkle folder kan niet gevonden worden in uw thuis folder. Profile already exists. Profiel bestaat al. Rename profile '%1' to: Hernoem profiel '%1' naar: HistoryForm Twinkle - Call History Twinkle - Gesprekshistorie Time Tijd From/To Van/Naar Subject Onderwerp Status Status Call details Gespreksdetails Details of the selected call record. Details van het geselecteerde gesprek. View Toon &Incoming calls &Inkomende gesprekken Alt+I Alt+I Check this option to show incoming calls. Vink deze optie aan om inkomende gesprekken te tonen. &Outgoing calls &Uitgaande gesprekken Alt+O Alt+U Check this option to show outgoing calls. Vink deze optie aan om uitgaande gesprekken te tonen. &Answered calls Be&antwoorde gesprekken Alt+A Alt+A Check this option to show answered calls. Vink deze optie aan om beantwoorde gesprekken te tonen. &Missed calls Ge&miste gesprekken Alt+M Alt+M Check this option to show missed calls. Vink deze optie aan om gemiste gesprekken te tonen. Current &user profiles only Alleen actieve &profielen Alt+U Alt+P Check this option to show only calls associated with this user profile. Vink deze optie aan om alleen gesprekken behorende bij de nu actieve profielen te tonen. C&lear &Wis Alt+L Alt+W <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> <p>Wis de gehele gespreksgeschiedenig.</p> <p><b>Noot:</b> hiermee wist u <b>alle</b> gespreksgegevens, ook gegevens die niet getoond worden afhankelijk van de toon-opties.</p> Alt+C Alt+S Close this window. Sluit dit venster. Call start: Begin: Call answer: Beantwoord: Call end: Eind: Call duration: Duur: Direction: Richting: From: Van: To: Naar: Reply to: Antwoord aan: Referred by: Doorverbonden door: Subject: Onderwerp: Released by: Beëindigd door: Status: Status: Far end device: Toestel partner: User profile: Gebruikersprofiel: conversation gesprek Call... Bel... Delete Wis Re: Antw: In/Out In/Uit Call selected address. Bel geselecteerd adres. Clo&se &Sluiten Alt+S Alt+S &Call &Bel Number of calls: Aantal gesprekken: ### Total call duration: Totale duur: InviteForm Twinkle - Call Twinkle - Bellen &To: &Aan: Optionally you can provide a subject here. This might be shown to the callee. Hier kunt u optioneel een onderwerp invoeren. Dit kan getoond worden aan de gebelde partij. Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Het adres dat u wilt bellen. Dit kan een volledig SIP adres zijn zoals <b>sip:example@example.com</b> of alleen een gebruikersnaam of telefoonnummer. Als u geen volledig adres invoert, dan zal Twinkle het adres afmaken met de waarde die u voor domein heeft ingevuld in uw gebruikersprofiel. The user that will make the call. Het gebruikersprofiel waarmee u het gesprek wilt maken. &Subject: O&nderwerp: &From: &Van: &OK &OK &Cancel Ann&uleren &Hide identity &Identiteit verbergen Alt+H Alt+I <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> <p> Met deze optie verzoekt u uw SIP provider om uw identiteit verborgen te houden voor degene die u belt. Alleen uw SIP adres of telefoonnummer blijft geheim. Uw IP adres wordt <b>niet</b> verborgen. </p> <p> <b>Waarschuwing:</b> niet alle providers ondersteunen het verbergen van uw identiteit. </p> Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. Niet alle SIP providers ondersteunen het verbergen van uw identiteit. Verzeker u ervan dat uw SIP provider dit ondersteunt als u dit nodig heeft. F10 F10 LogViewForm Twinkle - Log Twinkle - Log &Close &Sluiten Alt+C Alt+S C&lear &Wis Alt+L Alt+W Clear the log window. This does <b>not</b> clear the log file itself. Wis het log venster. Hiermee wist u <b>niet</b> het log bestand zelf. Contents of the current log file (~/.twinkle/twinkle.log) Inhoud van het log bestand (~/.twinkle/twinkle.log) MessageForm Twinkle - Instant message Twinkle - Instant bericht &To: &Aan: The user that will send the message. De gebruiker die het bericht stuurt. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Het adres van de persoon aan wie u een bericht wilt sturen. Dit kan een volledig SIP adres zijn zoals <b>sip:example@example.com</b> of een een telefoonnummer. Als u geen volledig adres opgeeft, dan zal Twinkle dit adres compleet maken door de domeinnaam uit uw gebruikersprofiel toe te voegen. Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. &User profile: &Gebruikersprofiel: Conversation Conversatie The exchanged messages. De uitgewisselde berichten. Type your message here and then press "send" to send it. Typ uw bericht en druk op "zend" om het te verzenden. &Send &Zend Alt+S Alt+Z Send the message. Zend het bericht. Delivery failure Afleverfout Delivery notification Aflevernotificatie Instant message toolbar Instant berichten Send file... Zend bestand... Send file Zend bestand image size is scaled down in preview plaatje is verkleind voor preview Open with %1... Openen met %1... Open with... Openen met... Save attachment as... Bijlage opslaan als... File already exists. Do you want to overwrite this file? Bestand bestaat al. Wilt u dit bestand overschrijven? Failed to save attachment. Opslaan bijlage mislukt. %1 is typing a message. %1 schrijft een bericht. F10 F10 Size Lengte MessageFormView sending message bericht wordt verstuurd MphoneForm Twinkle Twinkle The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Het adres dat u wilt bellen. Dit kan een volledig SIP adres zijn zoals <b>sip:example@example.com</b> of alleen een gebruikersnaam of telefoonnummer. Als u geen volledig adres invoert, dan zal Twinkle het adres afmaken met de waarde die u voor domein heeft ingevuld in uw gebruikersprofiel. The user that will make the call. Het gebruikersprofiel waarmee u het gesprek wilt maken. &User: &Gebruiker: Dial Bel Dial the address. Bel het adres. Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. Auto answer indication. Indicate automatisch beantwoord. Call redirect indication. Indicatie doorverwijzen. Do not disturb indication. Indicatie niet storen. Missed call indication. Indicatie gemiste gesprekken. Registration status. Registratiestatus. Display Scherm Line status Lijnstatus Line &1: Lijn &1: Alt+1 Alt+1 Click to switch to line 1. Kliek hier om over te schakelen naar lijn 1. From: Van: To: Naar: Subject: Onderwerp: idle vrij Call is on hold Gesprek staat in de wacht Voice is muted Geluid is onderdrukt Conference call Conferentiegesprek Transferring call Gesprek doorverbonden <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> <p> Het hangslot geeft aan dat het geluidskanaal versleuteld is tijdens transport over het netwerk. </p> <h3>SAS - Short Authentication String</h3> <p> Beide kanten van een versleuteld geluidskanaal ontvangen dezelfde SAS bij het eerste gesprek. Als de SAS niet hetzelfde is aan beide kanten, dan kan uw geluidskanaal gecompromiteerd zijn door een "man-in-the-middle" aanval (MitM). </p> <p> Als de SAS aan beide kanten hetzelfde is, dan moet u die bevestigen door op het hangslot te klikken voor hogere veiligheid van toekomstige gesprekken naar dezelfde bestemming. Voor toekomstige gesprekken naar deze bestemming, hoeft u de SAS dan niet nogmaals te bevestigen. Het hangslot toont een verificatie symbool als de SAS bevestigd is. </p> Short authentication string Short authentication string Audio codec Audio codec 0:00:00 0:00:00 Call duration Gespreksduur Line &2: Lijn &2: Alt+2 Alt+2 Click to switch to line 2. Klik hier om over te schakelen naar lijn 2. &File &Bestand &Edit Be&werk C&all Ge&sprek Activate line Activeer lijn &Registration &Registratie &Services &Diensten &View &Toon &Help &Help Call Toolbar Gespreksbalk Quit Afsluiten &Quit &Aflsuiten Ctrl+Q Ctrl+Q About Twinkle Over Twinkle &About Twinkle Over &Twinkle Call someone Iemand bellen F5 F5 Answer incoming call Beantwoord een binnenkomend gesprek F6 F6 Release call Beëindig een gesprek Reject incoming call Wijs een binnenkomend gesprek af F8 F8 Put a call on hold, or retrieve a held call Zet een gesprek in de wacht, of haal een gesprek uit de wacht Redirect incoming call without answering Verwijs een binnenkomend gesprek naar een andere bestemming zonder te antwoorden Open keypad to enter digits for voice menu's Open een toetsenbord om cijfers in te voeren voor een stem gestuurd menu Register Registreren &Register &Registreren Deregister Deregistreren &Deregister &Deregistreren Deregister this device Deregistreer dit apparaat Show registrations Toon registraties &Show registrations &Toon registraties Terminal capabilities Terminal eigenschappen Request terminal capabilities from someone Vraag terminal eigenschappen van iemand op Do not disturb Niet storen &Do not disturb &Niet storen Call &redirection... &Doorverwijzen... Repeat last call Herhaal het laatste gesprek F12 F12 About Qt Over Qt About &Qt Over &Qt &User profile... &Gebruikersprofiel... Join two calls in a 3-way conference Verbind twee gesprekken in een 3-weg conferentie Mute a call Onderdruk het geluid Transfer call Gesprek doorverbinden &System settings... &Systeeminstellingen... Deregister all Alles deregistreren Deregister &all &Alles deregistreren Deregister all your registered devices Deregistreer al uw geregistreerde apparaten Auto answer Automatisch beantwoorden &Auto answer &Automatisch beantwoorden Log Log &Log... &Log... Call &history... Gespreks&historie... F9 F9 Change user ... Wijzig gerbuiker... &Change user ... &Wijzig gebruiker... Activate or de-activate users Activeer of de-actieveer gebruikers What's This? Wat is dit? What's &This? &Wat is dit? Shift+F1 Shift+F1 Line 1 Lijn 1 Line 2 Lijn 2 idle No need to translate sas No need to translate g711a/g711a No need to translate sip:from No need to translate sip:to No need to translate subject No need to translate photo No need to translate dialing bellen attempting call, please wait gesprek opzetten, wacht aub incoming call inkomend gesprek establishing call, please wait gesprek verbinden, wacht aub established verbonden established (waiting for media) verbonden (wacht op media) releasing call, please wait gesprek afbreken, wacht aub unknown state onbekend Voice is encrypted Geluid is versleuteld Click to confirm SAS. Klik om SAS te bevestigen. Click to clear SAS verification. Klik om SAS bevestiging te wissen. Registration status: Registratiestatus: Registered Geregistreeerd Failed Mislukt Not registered Niet geregistreerd No users are registered. Niemand is geregistreerd. Do not disturb active for: Niet storen actief voor: Redirection active for: Doorverwijzen actief voor: Auto answer active for: Automatisch beantwoorden actief voor: Do not disturb is not active. Niet storen is niet actief. Redirection is not active. Doorverwijzen is niet actief. Auto answer is not active. Automatisch beantwoorden is niet actief. You have no missed calls. Geen gemiste gesprekken. You missed 1 call. U heeft 1 gemist gesprek. You missed %1 calls. U heeft %1 gemiste gesprekken. Click to see call history for details. Klik hier om de gesprekshistorie te zien. Starting user profiles... Opstarten gebruikersprofielen... You can only run multiple profiles for different users. U kunt alleen meerdere profielen voor verschillende gebruikers starten. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. U heeft de SIP UDP poort gewijzigd. Deze instelling wordt pas actief als u Twinkle opnieuw opstart. User: Gebruiker: Call: Bel: The following profiles are both for user %1 De volgende profielen zijn beiden voor gebruiker %1 Visual indication of line state. Visuele indicatie van de lijnstatus. Call redirection Doorverwijzen User profile Gebruikersprofiel System settings Systeeminstellingen Call history Gesprekshistorie &Call: Label in front of combobox to enter address B&el: Esc Esc Transfer consultation Ruggespraak doorverbinden Hide identity Identiteit verbergen Click to show registrations. Klik om registraties te tonen. %1 new, 1 old message %1 nieuw, 1 oud bericht %1 new, %2 old messages %1 nieuw, %2 oude berichten 1 new message 1 nieuw bericht %1 new messages %1 nieuwe berichten 1 old message 1 oud bericht %1 old messages %1 oude berichten Messages waiting Er zijn berichten No messages Geen berichten <b>Voice mail status:</b> <b>Voice mail status:</b> Failure Fout Unknown Onbekend Click to access voice mail. Klik voor toegang to voice mail. Click to activate/deactivate Klik om te activeren/deactiveren Click to activate Klik om te activeren not provisioned niet ingesteld You must provision your voice mail address in your user profile, before you can access it. Voor toegang tot voice mail moet u eerst uw voice mail nummer in uw gebruikersprofiel invullen. The line is busy. Cannot access voice mail. De lijn is bezet. Geen toegang tot voice mail. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Het voice mail nummer %1 is ongeldig. Vul een geldig nummer in in uw gebruikersprofiel. Call toolbar text Bel &Call... call menu text &Bel... Answer toolbar text Antw &Answer menu text &Antwoord Bye toolbar text Einde &Bye menu text &Einde Reject toolbar text Afwijzen &Reject menu text A&fwijzen Hold toolbar text Wacht &Hold menu text &Wacht Redirect toolbar text Verwijs R&edirect... menu text &Verwijs... Dtmf toolbar text Dtmf &Dtmf... menu text Dt&mf... &Terminal capabilities... menu text &Terminal eigenschappen... Redial toolbar text Herh &Redial menu text &Herhaal Conf toolbar text Conf &Conference menu text &Conferentie Mute toolbar text Stil &Mute menu text &Stil Xfer toolbar text Xfer Trans&fer... menu text &Doorverbinden... Voice mail Voice mail &Voice mail &Voice mail Access voice mail Bel voice mail F11 F11 Message waiting indication. Voice mail status. Buddy list Vrienden &Message &Bericht Msg Bericht Instant &message... Instant &bericht... Instant message Instant bericht &Call... &Bel... &Edit... Be&werk... &Delete &Verwijderen O&ffline O&ffline &Online &Online &Change availability &Wijzig beschikbaarheid &Add buddy... &Vriend toevoegen... Failed to save buddy list: %1 Opslaan van vriendenlijst is mislukt: %1 You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. Voor elk gebruikersprofiel kunt u een vriendenlijst aanleggen. Om de beschikbaarheid van uw vrienden te zien en uw eigen beschikbaarheid te publiceren, moet uw provider over een presence server beschikken. &Buddy list &Vrienden &Display &Scherm F10 F10 Diamondcard Manual Handleiding &Manual &Handleinding Sign up Aanmelden &Sign up... &Aanmelden... Recharge... Opwaarderen... Balance history... Balansoverzicht... Call history... Gesprekkenoverzicht... Admin center... Admin center... Recharge Opwaarderen Balance history Balansoverzicht Admin center Admin center NumberConversionForm &Match expression: &Match expressie: &Replace: &Vervang: Perl style format string for the replacement number. Formaat string (Perl syntax) voor het vervangen van het nummer in. Perl style regular expression matching the number format you want to modify. Reguliere expressie (Perl syntax) voor het matchen van het nummerformaat dat u wilt modificeren. &OK &OK Alt+O Alt+O &Cancel Ann&uleren Alt+C Alt+U Twinkle - Number conversion Twinkle - Nummerconversie Match expression may not be empty. Match expressie mag niet leeg zijn. Replace value may not be empty. Vervangwaarde mag niet leeg zijn. Invalid regular expression. Ongeldige reguliere expressie. RedirectForm Twinkle - Redirect Twinkle - Doorverwijzen Redirect incoming call to Verwijs inkomend gesprek naar You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. U kan tot 3 bestemmingen invoeren waarnaar u een gesprek wilt doorverwijzen. Als de eerste bestemming niet opneemt, dan wordt de tweede bestemming geprobeerd enz. &3rd choice destination: &3e bestemming: &2nd choice destination: &2e bestemming: &1st choice destination: &1e bestemming: Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. &OK &OK &Cancel Ann&uleren F10 F10 F12 F12 F11 F11 SelectNicForm Twinkle - Select NIC Twinkle - Kies NIC Select the network interface/IP address that you want to use: Kies de netwerk interface/IP adres die u wilt gebruiken: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. U heeft meerdere IP adressen. Hier moet u aangeven welk IP adres gebruikt moet worden. Dit adres wordt gebruikt in de SIP berichten. Set as default &IP Default &IP Alt+I Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Het geselecteerde IP adres wordt het default IP adres. De volgende keer dat u Twinkle start wordt dit IP adres automatisch geslecteerd. Set as default &NIC Default &NIC Alt+N Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. De geslecteerde netwerk interface wordt de default interface. De volgende keer dat u Twinkle opstart wordt deze interface automatisch geslecteerd. &OK &OK Alt+O Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. Als u de default later wilt verwijderen of wijzigen, dan kan dat via de systeeminstellingen. SelectProfileForm Twinkle - Select user profile Twinkle - Kies gebruikersprofiel Select user profile(s) to run: Selecteer de gebruikersprofielen die u wilt activeren: User profile Gebruikersprofiel Tick the check boxes of the user profiles that you want to run and press run. Vink de gebruikersprofielen aan die u wilt activeren. &New &Nieuw Alt+N Alt+N Create a new profile with the profile editor. Maak een nieuw profiel met de profielen editor. &Wizard Wi&zard Alt+W Alt+Z Create a new profile with the wizard. Maak een nieuw profiel met de wizard. &Edit Be&werk Alt+E Alt+W Edit the highlighted profile. Bewerk het huidige profiel. &Delete &Verwijderen Alt+D Alt+V Delete the highlighted profile. Verwijder het huidige profiel. Ren&ame &Hernoemen Alt+A Alt+H Rename the highlighted profile. Hernoem het huidige profiel. &Set as default &Default Alt+S Alt+D Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. Markeer de geselecteerde profielen als default profielen. De volgende keer dat u Twinkle opstart, zullen deze profielen automatisch gestart worden. &Run &Start Alt+R Alt+S Run Twinkle with the selected profiles. Start Twinkle met de geselecteerde profielen. S&ystem settings S&ysteeminstellingen Alt+Y Alt+Y Edit the system settings. Wijzig de systeeminstellingen. &Cancel Ann&uleren Alt+C Alt+U <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> <html>Voordat u Twinkle kunt gebruiken, moet u een gebruikerspofiel maken.<br>Klik op OK om een gebruikersprofiel te maken.</html> <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>Choose what method you wish to use.</html> <html>U kunt de profieleditor gebruiken om een gebruikersprofiel te maken. Met de profieleditor kunt u diverse instellingen met betrekking tot het SIP protocol, RTP en vele andere zaken wijzigen.<br><br>Met de wizard kunt u snel een gebruikersprofiel maken. De wizard vraagt u alleen om een aantal essentiële instellingen. Als u een gebruikersprofiel met de wizard maakt, dan kun u deze op een later tijdstip alsnog met de profieleditor wijzigen.<br><br>Kies op welke wijze u een gebruikersprofiel wilt maken.</html> <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> <html>U kunt nu de systeeminstellingen wijzigen. Deze instellingen kunt u altijd wijzigen op een later tijdstip.<br><br>Klik op OK om de systeeminstellingen te bekijken en eventueel te wijzigen.</html> You did not select any user profile to run. Please select a profile. U heeft geen gebruikersprofiel geselecteerd. Kies eerst een gebruikersprofiel. Are you sure you want to delete profile '%1'? Weet u zeker dat u profiel '%1' wilt verwijderen? Delete profile Verwijder profiel Failed to delete profile. Profiel verwijderen mislukt. Failed to rename profile. Profiel hernoemen mislukt. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> <p>Als u de default later wilt verwijderen of wijzigen, dan kunt u dat doen via de systeeminstellingen.</p> Cannot find .twinkle directory in your home directory. .twinkle folder kan niet gevonden worden in uw thuis folder. &Profile editor &Profieleditor Create profile Maak gebruikersprofiel Ed&itor Ed&itor Alt+I Alt+I Dia&mondcard Dia&mondcard Alt+M Alt+M Modify profile Bewerk gebruikersprofiel Startup profile Starten gebruikersprofiel <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones.<br><br>Choose what method you wish to use.</html> <html>U kunt de profieleditor gebruiken om een gebruikersprofiel te maken. Met de profieleditor kunt u diverse instellingen met betrekking tot het SIP protocol, RTP en vele andere zaken wijzigen.<br><br>Met de wizard kunt u snel een gebruikersprofiel maken. De wizard vraagt u alleen om een aantal essentiële instellingen. Als u een gebruikersprofiel met de wizard maakt, dan kun u deze op een later tijdstip alsnog met de profieleditor wijzigen.<br><br>U kunt een Diamondcard account aanmaken waarmee u wereldwijd kunt bellen naar vaste en mobiele telefoonnummers.<br><br>Kies op welke wijze u een gebruikersprofiel wilt maken.</html> &Diamondcard &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones. Maak een gebruikersprofiel voor een Diamondcard account. Met een Diamondcard account kunt u wereldwijd bellen naar vaste en mobiele telefoonnummers. Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. Maak een gebruikersprofiel voor een Diamondcard account. Met een Diamondcard account kunt u wereldwijd bellen naar vaste en mobiele telefoonnummers en SMS berichten versturen. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> <html>U kunt de profieleditor gebruiken om een gebruikersprofiel te maken. Met de profieleditor kunt u diverse instellingen met betrekking tot het SIP protocol, RTP en vele andere zaken wijzigen.<br><br>Met de wizard kunt u snel een gebruikersprofiel maken. De wizard vraagt u alleen om een aantal essentiële instellingen. Als u een gebruikersprofiel met de wizard maakt, dan kun u deze op een later tijdstip alsnog met de profieleditor wijzigen.<br><br>U kunt een Diamondcard account aanmaken waarmee u wereldwijd kunt bellen naar vaste en mobiele telefoonnummers en SMS berichten versturen.<br><br>Kies op welke wijze u een gebruikersprofiel wilt maken.</html> SelectUserForm Twinkle - Select user Twinkle - Kies gebruiker &Cancel Ann&uleren Alt+C Alt+U &Select all &Selecteer alles Alt+S Alt+S &OK &OK Alt+O Alt+O C&lear all &Wis alles Alt+L Alt+W User Gebruiker Register Registreren Select users that you want to register. Selecteer welke gebruikers u wilt registreren. Deregister Deregistreren Select users that you want to deregister. Kies de gebruikers die u wilt deregistreren. Deregister all devices Deregistreer alle apparaten Select users for which you want to deregister all devices. Kies de gebruikers voor wie u alle apparaten wilt deregistreren. Do not disturb Niet storen Select users for which you want to enable 'do not disturb'. Kies de gebruikers voor wie u 'niet storen' wilt aanzetten. Auto answer Automatisch beantwoorden Select users for which you want to enable 'auto answer'. Kies de gebruikers voor wie u 'automatisch beantwoorden' wilt aanzetten. purpose No need to translate SendFileForm Twinkle - Send File Twinkle - Zend bestand Select file to send. Kies het bestand dat u wilt zenden. &File: &Bestand: &Subject: O&nderwerp: &OK &OK Alt+O &Cancel Ann&uleren Alt+C File does not exist. Bestand bestaat niet. Send file... Zend bestand... SrvRedirectForm Twinkle - Call Redirection Twinkle - Doorverwijzen User: Gebruiker: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> Er zijn 3 doorverwijsdiensten:<p> <b>Onvoorwaardelijk:</b> alle inkomende gesprekken worden doorverwezen </p> <p> <b>Bezet:</b> een inkomend gesprek wordt doorverwezen als beide lijnen bezet zijn </p> <p> <b>Geen antwoord:</b> een inkomend gesprek wordt doorverwezen als u niet opneemt </p> &Unconditional O&nvoorwaardelijk &Redirect all calls &Alle gesprekken doorverwijzen Alt+R Alt+A Activate the unconditional redirection service. Activeer de onvoorwaardelijk doorverwijzen. Redirect to Doorverwijzen naar You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. U kan tot 3 bestemmingen invoeren waarnaar u een gesprek wilt doorverwijzen. Als de eerste bestemming niet opneemt, dan wordt de tweede bestemming geprobeerd enz. &3rd choice destination: &3e bestemming: &2nd choice destination: &2e bestemming: &1st choice destination: &1e bestemming: Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. &Busy &Bezet &Redirect calls when I am busy Gesprekken &doorverwijzen als alle lijnen bezet zijn Activate the redirection when busy service. Activeer doorverwijzen bij bezet. &No answer Geen &antwoord &Redirect calls when I do not answer Gesprekken &doorverwijzen als ik niet antwoord Activate the redirection on no answer service. Activeer doorverwijzen bij geen antwoord. &OK &OK Alt+O Alt+O Accept and save all changes. Sla de huidige instellingen op. &Cancel Ann&uleren Alt+C Alt+U Undo your changes and close the window. Maak uw wijzigingen ongedaan en sluit het venster. You have entered an invalid destination. U heeft een ongeldige bestemming ingevoerd. F10 F10 F11 F11 F12 F12 SysSettingsForm Twinkle - System Settings Twinkle - Systeeminstellingen General Algemeen Audio Audio Ring tones Ring tones Address book Adresboek Network Netwerk Log Log Select a category for which you want to see or modify the settings. Kies de categorie waarvoor u instellingen wilt wijzigen. Sound Card Geluidskaart Select the sound card for playing the ring tone for incoming calls. Kies de geluidskaart voor het afspelen van de ring tone bij een binnenkomend gesprek. Select the sound card to which your microphone is connected. Kies de geluidskaart waarmee uw microfoon is verbonden. Select the sound card for the speaker function during a call. Kies de geluidskaart waarmee uw speaker of headset verbonden is. &Speaker: &Speaker: &Ring tone: &Ring tone: Other device: Ander apparaat: &Microphone: &Microfoon: When using ALSA, it is not recommended to use the default device for the microphone as it gives poor sound quality. Als u ALSA gebruikt, dan is het niet aan te raden om het default apparaat als microfoon te gebruiken omdat die een matige geluidskwaliteit heeft. Reduce &noise from the microphone &Verminder ruis van de microfoon Alt+N Alt+V Recordings from the microphone can contain noise. This could be annoying to the person on the other side of your call. This option removes soft noise coming from the microphone. The noise reduction algorithm is very simplistic. Sound is captured as 16 bits signed linear PCM samples. All samples between -50 and 50 are truncated to 0. Opnames van de microfoon kunnen ruis bevatten. Dit kan vervelend zijn voor de persoon aan de andere kant van de lijn. Deze instelling kan zachte ruis van de microfoon verwijderen. Het algoritme om ruis te verminderen is erg simplistisch. Geluid wordt gedigitaliseerd als 16 bits lineaire PCM samples. Alle samples tussen de waarden -50 en 50 worden afgerond naar 0. Advanced Expert instellingen OSS &fragment size: OSS &fragment grootte: 16 16 32 32 64 64 128 128 256 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. De ALSA afspeel periode grootte is van invloed op het real time gedrag van uw geluidskaart bij het afspelen van geluid. Als het geluid hapert bij het gebruik van ALSA, dan kunt u een andere waarde proberen. ALSA &play period size: ALSA afspeel-&periode grootte: &ALSA capture period size: &ALSA opneem-periode grootte: The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. De OSS fragment grootte is van invloed op het real time gedrag van uw geluidskaart. Als het geluid hapert bij het gebruik van OSS, dan kunt u een andere waarde proberen. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. De ALSA opneem-periode grootte is van invloed op het real time gedrag van uw geluidskaart bij het opnemen van geluid. Als het geluid aan de andere kant van de lijn hapert bij het gebruik van ALSA, dan kunt u een andere waarde proberen. &Max log size: &Max log grootte: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. De maximum omvang van het log bestand in MB. Als de log file groter wordt dan deze omvang, dan wordt een backup van de log file gemaakt en wordt de huidige log file gewist. Er wordt slechts één backup log bestand bewaard. MB MB Log &debug reports Log &debug meldingen Alt+D Alt+D Indicates if reports marked as "debug" will be logged. Plaats "debug" meldingen in het log bestand. Log &SIP reports Log &SIP meldingen Alt+S Alt+S Indicates if SIP messages will be logged. Plaats SIP meldingen in het log bestand. Log S&TUN reports Log S&TUN meldingen Alt+T Alt+T Indicates if STUN messages will be logged. Plaats STUN meldingen in het log bestand. Log m&emory reports Log g&eheugen meldingen Alt+E Alt+E Indicates if reports concerning memory management will be logged. Plaats meldingen met betrekking tot geheugenbeheer in het log bestand. System tray Systeemvak Create &system tray icon on startup Maak een icoon in het &systeemvak bij opstarten Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. Met deze optie wordt er een icoon in het systeemvak geplaatst bij het opstarten van Twinkle. &Hide in system tray when closing main window &Verbergen in systeemvak bij sluiten van het hoofdvenster Alt+H Alt+V Enable this option if you want Twinkle to hide in the system tray when you close the main window. Met deze optie verbert Twinkle zich in het systeemvak als u het hoofdvenster sluit. Startup Opstarten Next time you start Twinkle, this IP address will be automatically selected. This is only useful when your computer has multiple and static IP addresses. De volgende keer dat u Twinkle opstart wordt dit IP adres automatisch geselecteerd. Dit is alleen handig als uw computer meerdere statische IP adressen heeft. Default &IP address: Default &IP adres: Next time you start Twinkle, the IP address of this network interface be automatically selected. This is only useful when your computer has multiple network devices. De volgende keer dat u Twinkle opstart wordt het IP adres van deze netwerk interface automatisch geselecteerd. Dit is alleen handig als uw computer meerdere netwerk interfaces heeft. Default &network interface: Default &netwerk interface: S&tartup hidden in system tray Verborgen ops&tarten in systeemvak Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. De volgende keer dat u Twinkle opstart, zal Twinkle zich onmiddelijk verbergen in het systeemvak. Dit werkt het beste als u ook een default gebruikersprofiel selecteert. Default user profiles Default gebruikersprofielen If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. Als u altijd dezelfde gebruikersprofielen gebruikt, dan kunt u deze profielen als default markeren. De volgdende keer dat u Twinkle opstart, wordt u dan niet meer gevraagd om een gebruikers profiel te kiezen. De default profielen worden automatisch opgestart. Services Diensten Call &waiting &Wisselgesprek Alt+W Alt+W With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. Met wisselgesprek kunt een inkomend gesprek ontvangen als slechts één lijn bezet is. Als u wisselgesprek uitschakelt, dan wordt een binnekomend gesprek automatisch geweigerd als één lijn bezet is. Hang up &both lines when ending a 3-way conference call. Hang &beide lijnen op bij het beëindigen van een 3-weg conferentiegesprek. Alt+B Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. Hang beide lijnen op als u een 3-weg gesprek beëindigd. Als u deze optie uitschakelt, dan zal alleen de actieve lijn worden opgehangen. U kunt dan doorpraten met de partij op de andere lijn. &Maximum calls in call history: &Maximum aantal gesrpekken in gesprekshistorie: The maximum number of calls that will be kept in the call history. Het maximum aantal gesprekken dat in de gesprekshistorie wordt bewaard. &Auto show main window on incoming call after Toon hoofdvenster &automatisch bij een inkomend gesprek na Alt+A Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Als het hoofdvenster verborgen is, dan wordt deze automatisch getoond bij een inkomend gesprek na het aantal aangegeven seconden. Number of seconds after which the main window should be shown. Het aantal seconden waarna het hoofdvenster getoond moet worden. secs s The UDP port used for sending and receiving SIP messages. De UDP poort voor het sturen en ontvangen van SIP berichten. &RTP port: &RTP poort: The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. De UDP poort wordt gebruikt voor het sturen en ontvangen van RTP op de eerste lijn. De UDP poort voor de tweede lijn is 2 hoger. Voorbeeld: als poort 8000 wordt gebruikt voor de eerste lijn, dan wordt 8002 voor de tweede lijn gebruikt. Als u de dienst "doorverbinden" gebruikt dan wordt de volgende even poort (bijv. 8004) ook gebruikt. &SIP UDP port: &SIP UDP poort: Ring tone Ring tone &Play ring tone on incoming call &Speel ring tone bij inkomend gesprek Alt+P Alt+S Indicates if a ring tone should be played when a call comes in. Geeft aan dat een ring tone gespeeld moet worden bij een inkomend gesprek. &Default ring tone &Default reing tone Play the default ring tone when a call comes in. Speel de default ring tone bij een inkomend gesprek. C&ustom ring tone &Eigen ring tone Alt+U Alt+E Play a custom ring tone when a call comes in. Speel een eigen ring tone bij een inkomend gesprek. Specify the file name of a .wav file that you want to be played as ring tone. De bestandsnaam van een .wav bestand dat u als ring tone wilt afspelen. Ring back tone Ring back tone P&lay ring back tone when network does not play ring back tone S&peel ring back tone als het netwerk geen ring back tone speelt Alt+L Alt+P <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> <p> Speel een ring back tone (de toon die u hoort als u iemand belt) als u wacht op antwoord van de gebelde partij. </p> <p> Afhankelijk van uw SIP provider, kan het netwerk een ring back tone spelen. </p> D&efault ring back tone De&fault ring back tone Play the default ring back tone. Speel de default ring back tone. Cu&stom ring back tone Ei&gen ring back tone Play a custom ring back tone. Speel een eigen ring back tone. Specify the file name of a .wav file that you want to be played as ring back tone. De bestandsnaam van een .wav bestand dat u als ring back tone wilt afspelen. &Lookup name for incoming call Naam op&zoeken voor een inkomend gesprek Ove&rride received display name Gevonden naam heeft voor&rang op ontvangen naam Alt+R Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. De beller kan een naam meesturen met een inkomend gesprek. Als u deze optie selecteert, dan zal Twinkle toch de naam uit uw adresboek tonen als deze gevonden wordt. Lookup &photo for incoming call Opzoeken &foto bij inkomend gesprek Lookup the photo of a caller in your address book and display it on an incoming call. Zoek de foto van de beller op in uw adresboek en toon het bij een inkomend gesprek. &OK &OK Alt+O Alt+O Accept and save your changes. Sla de instellingen op. &Cancel Ann&uleren Alt+C Alt+U Undo all your changes and close the window. Maak alle wijzigingen ongedaan en sluit het venster. none This is the 'none' in default IP address combo geen none This is the 'none' in default network interface combo geen Either choose a default IP address or a default network interface. Kies óf een default IP adres óf een default netwerk interface. Ring tones Description of .wav files in file dialog Ring tones Choose ring tone Kies ring tone Ring back tones Description of .wav files in file dialog Ring back tones Choose ring back tone Kies ring back tone &Validate devices before usage &Valideer apparaten voor gebruik Alt+V Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. <p> Twinkle valideert de geluidsapparaten voor gebruik om te voorkomen dat een gesprek zonder geluidskanaal wordt opgezet. <p> Bij het opstarten geeft Twinkle een waarschuwing als een geluidsapparaat niet beschikbaar is. <p> Als voor het maken van een gesprek, de microfoon of speaker niet beschikbaar zijn, dan krijgt u een waarschuwing en kunt u het gesprek niet maken. <p> Als voor het beantwoorden van een inkomend gesprek, de microfoon of speaker onbeschikbaar zijn, dan krijgt u een waarschuwing en kunt u het gesprek niet beantwoorden. On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. Bij een inkomend gesprek, probeert Twinkle de naam van de beller op te zoeken in het adresboek. Deze naam wordt dan getoond. Select ring tone file. Selecteer ring tone bestand. Select ring back tone file. Selecteer ring back tone bestand. Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. Maximum omvang (0-65535) van een inkomend SIP bericht over UDP in bytes. &SIP port: &SIP poort: Max. SIP message size (&TCP): Max. omvang SIP bericht (&TCP): The UDP/TCP port used for sending and receiving SIP messages. De TCP/UDP poort die wordt gebruikt voor SIP verkeer. Max. SIP message size (&UDP): Max. omvang SIP bericht (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. Maxmimum grootte (0-4294967295) van een SIP bericht over TCP in bytes. W&eb browser command: Command voor opstarten w&eb browser: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. Het commando waamee uw web browser kan worden opgestart. Als u dit veld leeg laat, dan zal Twinkle zelf proberen om uw standaard web browser op te starten. SysTrayPopup Answer Antwoord Reject Afwijzen Incoming Call Inkomend gesprek TermCapForm Twinkle - Terminal Capabilities Twinkle - Terminal Eigenschappen &From: &Van: Get terminal capabilities of Opvragen terminal eigenschappen van &To: &Aan: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Het adres waarvoor u de eigenschappen (OPTION verzoek) wilt weten. Dit kan een volledig SIP adres zijn zoals <b>sip:example@example.com</b> of alleen een gebruikersnaam of telefoonnummer. Als u geen volledig adres invoert, dan zal Twinkle het adres afmaken met de waarde die u voor domein heeft ingevuld in uw gebruikersprofiel. Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. &OK &OK &Cancel Ann&uleren F10 F10 TransferForm Twinkle - Transfer Twinkle - Doorverbinden Transfer call to Doorverbinden naar &To: &Aan: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Het adres waarnaar u wilt doorverbinden. Dit kan een volledig SIP adres zijn zoals <b>sip:example@example.com</b> of alleen een gebruikersnaam of telefoonnummer. Als u geen volledig adres invoert, dan zal Twinkle het adres afmaken met de waarde die u voor domein heeft ingevuld in uw gebruikersprofiel. Address book Adresboek Select an address from the address book. Kies een adres uit het adresboek. &OK &OK Alt+O Alt+O &Cancel Ann&uleren Type of transfer Doorverbindmethode &Blind transfer &Blind doorverbinden Alt+B Alt+B Transfer the call to a third party without contacting that third party yourself. Doorverbinden van het gesprek naar een derde partij zonder dat u die derde partij eerst zelf raadpleegt. T&ransfer with consultation Doorverbinden met &ruggespraak Alt+R Alt+R Before transferring the call to a third party, first consult the party yourself. Alvorens een gesprek door te verbinden naar een derde partij, houdt u eerst ruggespraak met die partij. Transfer to other &line Doorverbinden naar andere &lijn Alt+L Alt+L Connect the remote party on the active line with the remote party on the other line. Verbind de persoon op deze lijn door met de persoon op de andere lijn. F10 F10 TwinkleCore Directory %1 does not exist. Folder %1 bestaat niet. Lock file %1 already exist, but cannot be opened. Lock bestand %1 bestaat al, maar kan niet geopend worden. %1 is already running. Lock file %2 already exists. %1 is al actief. Lock bestand %2 bestaat al. Failed to create log file %1 . Aanmaken van log bestand %1 mislukt. Cannot open file for reading: %1 Bestand kan niet geopend worden om te lezen: %1 File system error while reading file %1 . Bestandssysteem fout tijdens lezen van file %1 . Cannot open file for writing: %1 Bestand niet geopend worden om te schrijven: %1 File system error while writing file %1 . Bestandssysteem fout tijdens schrijven van bestand %1 . Excessive number of socket errors. Excessief aantal socket fouten. Built with support for: Gebouwd met ondersteuning voor: Contributions: Bijdragen: This software contains the following software from 3rd parties: Deze software bevat de volgende software van derden: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * GSM codec van Jutta Degener en Carsten Bormann, Universiteit van Berlijn * G.711/G.726 codecs from Sun Microsystems (public domain) * G.711/G.726 codecs van Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * iLBC implementatie uit RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * Delen van het STUN project op http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ * Delen van libsrv op http://libsrv.sourceforge.net/ For RTP the following dynamic libraries are linked: Voor RTP zijn de volgende dynamische libraries gelinkt: Translated to english by <your name> Nederlandse vertaling door Michel de Boer Cannot open file %1 . Betand %1 kan niet geopend worden. %1 is not set to your home directory. %1 heeft niet de waarde van uw thuis folder. Directory %1 (%2) does not exist. Folder %1 (%2) bestaat niet. Cannot create directory %1 . Folder %1 kan niet aangemaakt worden. Cannot create %1 . %1 kan niet aangemaakt worden. Cannot write to %1 . Kan niet schrijven naar %1 . Syntax error in file %1 . Syntactische fout in bestand %1 . Failed to backup %1 to %2 Backuppen van %1 naar %2 mislukt unknown name (device is busy) naam onbekend (apparaat bezet) Default device Default apparaat Anonymous Anoniem Warning: Waarschuwing: Call transfer - %1 Doorverbinden - %1 Sound card cannot be set to full duplex. Geluidskaart werkt niet in full duplex modus. Cannot set buffer size on sound card. De buffergrootte van de geluidskaart kan niet ingesteld worden. Sound card cannot be set to %1 channels. Geluidskaar ondersteunt geen %1 kanalen. Cannot set sound card to 16 bits recording. Geluidskaart ondersteunt geen 16 bits opname. Cannot set sound card to 16 bits playing. Geluidskaar ondersteunt geen 16 bits afspelen. Cannot set sound card sample rate to %1 Geluidskaar ondersteunt sampling rate %1 niet Opening ALSA driver failed Openen ALSA stuurprogramma mislukt Cannot open ALSA driver for PCM playback ALSA stuur programma voor PCM afspelen kan niet geopend worden Cannot resolve STUN server: %1 IP adres van STUN server niet gevonden: %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. U bevindt zich achter een symmetrische NAT. STUN zal niet werken. Configureer uw publieke IP adres in uw gebruikersprofiel en creëer de volgende statische UDP mapping in uw NAT. public IP: %1 --> private IP: %2 (SIP signaling) publiek IP: %1 --> privé IP: %2 (SIP signalering) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) publiek IP: %1-%2 --> privé IP: %3-%4 (RTP/RTCP) Cannot reach the STUN server: %1 STUN server onbereikbaar: %1 Port %1 (SIP signaling) Poort %1 (SIP signalering) NAT type discovery via STUN failed. Verkenning van NAT type via STUN is mislukt. If you are behind a firewall then you need to open the following UDP ports. Als u zich achter een firewall bevindt dan moet u de volgende UDP poorten open zetten. Ports %1-%2 (RTP/RTCP) Poorten %1-%2 (RTP/RTCP) Cannot access the ring tone device (%1). Ring tone apparaat niet beschikbaar (%1). Cannot access the speaker (%1). Speaker niet beschikbaar (%1). Cannot access the microphone (%1). Microfoon niet beschikbaar (%1). Cannot open ALSA driver for PCM capture ALSA stuurapparaat kan niet geopend worden voor openemen Cannot receive incoming TCP connections. Kan geen inkomende TCP verbindingen ontvangen. Failed to create file %1 Creëren van bestand %1 mislukt Failed to write data to file %1 Schrijven naar bestand %1 mislukt Failed to send message. Zenden bericht mislukt. Cannot lock %1 . Kan geen lock zetten op %1 . UserProfileForm Twinkle - User Profile Twinkle - Gebruikersprofiel User profile: Gebruikersprofiel: Select which profile you want to edit. Kies het gebruikersprofiel dat u wilt bewerken. User Gebruiker SIP server SIP server RTP audio RTP audio SIP protocol SIP protocol NAT NAT Address format Adresformaat Timers Timers Ring tones Ring tones Scripts Scripts Security Beveiliging Select a category for which you want to see or modify the settings. Kies de categorie die u wilt bewerken. &OK &OK Alt+O Alt+O Accept and save your changes. Bewaar uw wijzigingen. &Cancel Ann&uleren Alt+C Alt+U Undo all your changes and close the window. Maak alle wijzigingen ongedaan en sluit het venster. SIP account SIP account &User name*: Ge&bruikersnaam*: &Domain*: &Domein*: Or&ganization: Or&ganisatie: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. De SIP gebruikersnaam die u van uw provider heeft gekregen. Dit het gebruikersdeel in uw SIP adres, <b>gebruikersnaame</b>@domein.nl Dit kan een telefoonnummer zijn. <br><br> Dit is een verplicht veld. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Dit is het domein deel van uw SIP adres, gebruikersnaame@<b>domein.nl</b>. In plaats van een echt domein kan dit ook de host naam of het IP van uw <b>SIP proxy</b> zijn. Als u direct van IP adres naar IP adres wilt bellen, dan vult u hier de host naam of IP adres van uw computer in. <br><br> Dit is een verplicht veld. You may fill in the name of your organization. When you make a call, this might be shown to the called party. Hier kunt u de naam van uw organisatie invullen. Als u iemand belt, dan kan dit getoond worden. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Dit is uw eigen naam. bijv. Jan Jansen. Als u iemand belt, kan deze naam getoond worden. &Your name: U&w naam: SIP authentication SIP authenticatie &Realm: &Realm: &Password: &Paswoord: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. De authenticatie realm. Deze waarde moet verstrekt worden door uw SIP provider. Als u dit veld leeg laat, dan zal Twinkle automatisch de realm gebruiken die de SIP proxy stuurt. Als u de realm niet weet, laat dit veld dan leeg. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Uw SIP gebruikersnaam voor authenticatie. Meestal is dit hetzelfde als uw SIP gebruikersnaam. Your password for authentication. Uw paswoord voor authenticatie. Registrar Registratie server &Registrar: &Registratie server: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. De host naam, domein naam of IP adres van uw registratie server. Als u een uitgaande proxy gebruikt die tevens uw registratie server is, dan kunt u dit veld leeg laten en alleen het adres voor de uitgaande proxy invullen. &Expiry: &Interval: The registration expiry time that Twinkle will request. Het registratie interval dat Twinkle zal aanvragen. seconds sec Re&gister at startup Re&gistreer tijdens opstarten Alt+G Alt+G Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Geeft aan of Twinkle zich automatisch moet registrerent als u dit gebruikersprofiel start. U moet deze optie uitschakelen als u direct van IP adres naar IP adres wilt bellen zonder tussenkomst van een SIP proxy. Outbound Proxy Uitgaande Proxy &Use outbound proxy &Gebruik uitgaande proxy Alt+U Alt+G Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Geeft aan dat Twinkle een uitgaande proxy moet gebruiken. Als een uitgaande proxy gebruikt wordt, dan worden alle SIP berichten naar die proxy gestuurd. Zonder uitgaande proxy, zal Twinkle zelf proberen om een SIP adres naar een IP adres te veralen. Outbound &proxy: Uitgaande &proxy: &Send in-dialog requests to proxy &Stuur "in-dialog SIP request" naar de proxy Alt+S Alt+S SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. SIP verzoeken binnen een SIP dialog worden normaliter naar het adres uit de contact-header gestuurd. Dit adres wordt tijdens de gespreksopbouw bepaald. Als u deze optie aanvinkt, dan zal Twinkle dat adres negeren en zullen in-dialog requests ook naar de uitgaande proxy gestuurd worden. &Don't send a request to proxy if its destination can be resolved locally. Stuur een &verzoek niet naar de proxy als de bestemming lokaal bepaald kan worden. Alt+D Alt+V When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) Als u deze optie aanvinkt, dan zal Twinkle eerst zelf proberen om een SIP adres naar een IP adres te vertalen. Als dat lukt, dan zal het SIP verzoek naar dat IP adres worden gestuurd. Als dat niet lukt dan wordt het verzoek naar de proxy gestuurd (letop: als het om een in-dialog request gaat, dan moet ook de voorgaande optie aan staan, als u wilt dat deze naar de proxy gaat.) The hostname, domain name or IP address of your outbound proxy. Host naam, domein of IP adres van uw uitgaande proxy. Codecs Codecs Available codecs: Beschikbare codecs: G.711 A-law G.711 A-law G.711 u-law G.711 u-law GSM GSM speex-nb (8 kHz) speex-nb (8 kHz) speex-wb (16 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) speex-uwb (32 kHz) List of available codecs. Lijst met beschikbare codecs. Move a codec from the list of available codecs to the list of active codecs. Verplaats een codec van de lijst met beschikbare codecs naar de lijst met actieve codecs. Move a codec from the list of active codecs to the list of available codecs. Verplaats een codec van de lijst met actieve codecs naar de lijst met beschikbare codecs. Active codecs: Actieve codecs: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. Lijst met actieve codecs. Deze codecs worden gebruikt in de media onderhandeling tijdens de gespreksopbouw. De volgorde van de codecs geeft de voorkeur aan. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. Schuif een codec omhoog in de lijst met actieve codec, d.w.z. verhoog de voorkeur. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. Verschuif een codec omlaag in de lijst met actieve codecs, d.w.z. verlaag de voorkeur. &G.711/G.726 payload size: &G.711/G.726 payload grootte: The preferred payload size for the G.711 and G.726 codecs. De gewenste payload grootte voor de G.711 en G.726 codecs. ms ms &iLBC &iLBC iLBC iLBC i&LBC payload type: i&LBC payload type: iLBC &payload size (ms): iLBC &payload grootte (ms): The dynamic type value (96 or higher) to be used for iLBC. Het dynamische payload type (96 of hoger) voor iLBC. 20 20 30 30 The preferred payload size for iLBC. De gewenste payload grootte voor iLBC. &Speex &Speex Speex Speex Perceptual &enhancement Perceptual &enhancement Alt+E Alt+W Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). Perceptual enhancement tracht de ruis geproduceert door het coderings/decoderings proces te verminderen (een subjectieve verbetering). &Ultra wide band payload type: U&ltra wide band payload type: &VAD &VAD Alt+V Alt+V When enabled, voice activity detection detects whether the audio being encoded is speech or silence/background noise. VAD is always implicitly activated when encoding in VBR, so the option is only useful in non-VBR operation. In this case, Speex detects non-speech periods and encode them with just enough bits to reproduce the background noise. This is called "comfort noise generation" (CNG). Voice activity detection detecteert of de opgenomen audio spraak of stilte dan wel achtergrondruis is. VAD staat atlijd impliciet aan als VBR wordt gebruikt. VAD is dus alleen nutting als VBR uitstaat. De Speex codec stuurt dan slechts een paar bits tijdens stilte periodes. Dit heet comfort noise generation (CNG). &Wide band payload type: &Wide band payload type: V&BR V&BR Alt+B Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. Met variable bit-rate (VBR) past de codec de bit-rate dynamisch aan aan de complexiteit van de opgenomen audio. The dynamic type value (96 or higher) to be used for speex wide band. Het dynamische payload type (96 of hoger) voor speex wide band. Co&mplexity: Co&mplexiteit: DT&X DT&X Alt+X Alt+X Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. Discontinuous transmission (DTX) is een extra optie boven op VAD. Met DTX wordt helemaal niets gestuurd tijdens stilte periodes. The dynamic type value (96 or higher) to be used for speex narrow band. Het dynamische payload type (96 of hoger) voor speex narrow band. With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. Voor Speex kan de complexiteit van de encoder ingesteld worden. Deze instelling is vergelijkbaar met de -1 tot -9 opties voor gzip en bzip2 compressie. Voor normaal gebruik is het ruisniveau bij complexiteit 1 tussen de 1 en 2 dB hoger dan bij complexiteit 10. De benodigde CPU kracht is bij complexiteit 10 ongeveer 5 keer zo hoog als bij complexiteit 1. In de praktijk is een complexiteit tussen 2 en 4 genoeg. Hogere complexiteit kan nuttig zijn bij het versturen van niet-spraak audio, bijvoorbeeld DTMF tonen. &Narrow band payload type: &Narrow band payload type: G.726 G.726 G.726 &40 kbps payload type: G.726 &40 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 40 kbps. Het dynamische payload type (96 of hoger) voor G.726 40 kbps. The dynamic type value (96 or higher) to be used for G.726 32 kbps. Het dynamische payload type (96 of hoger) voor G.726 32 kbps. G.726 &24 kbps payload type: G.726 &24 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 24 kbps. Het dynamische payload type (96 of hoger) voor G.726 24 kbps. G.726 &32 kbps payload type: G.726 &32 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 16 kbps. Het dynamische payload type (96 of hoger) voor G.726 16 kbps. G.726 &16 kbps payload type: G.726 &16 kbps payload type: DT&MF DT&MF DTMF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). Het dynamische payload type (96 of hoger) voor DTMF (RFC 2833). DTMF vo&lume: DTMF vo&lume: The power level of the DTMF tone in dB. Het volume van de DTMF toon in dB. The pause after a DTMF tone. Pauze na het sturen van een DTMF toon. DTMF &duration: DTMF &duur: DTMF payload &type: DTMF payload &type: DTMF &pause: DTMF &pauze: dB dB Duration of a DTMF tone. Duur van een DTMF toon. DTMF t&ransport: DTMF t&ransport: Auto Auto RFC 2833 RFC 2833 Inband Inband Out-of-band (SIP INFO) Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> <h2>RFC 2833</h2> <p>Stuur DTMF tonen als RFC 2833 events.</p> <h2>Inband</h2> <p>Stuur DTMF inband toon.</p> <h2>Auto</h2> <p>Als de andere partij RFC 2833 ondersteund dan wordt RFC 2833 gebruikt, anders wordt de DTMF toon inband gestuurd. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Stuur DTMF out-of-band in een SIP INFO verzoek. </p> General Algemeen Redirection Doorverwijzen &Allow redirection St&a doorverwijzen toe Alt+A Alt+A Ask user &permission to redirect &Vraag toestemming voor doorverwijzen Alt+P Alt+V Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Geeft aan of Twinkle de gebruiker om toestemming moet vragen alvorens een verzoek door te verwijzen bij een 3XX antwoord. Max re&directions: Max &doorverwijzingen: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. Het maximaal aantal doorverwijzingen dat Twinkle probeert om een verzoek af te leveren. Dit maximum voorkomt dat een verzoek eeuwig wordt doorverwezen. Protocol options Protocol opties Call &Hold variant: Wac&ht variant: RFC 2543 RFC 2543 RFC 3264 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. Geeft aan of RFC 2543 (zet media IP adres in SDP op 0.0.0.0) of RFC 3264 (gebruikt "direction" attribuut in SDP) gebruikt moet worden om een gesprek in de wacht te plaatsen. Allow m&issing Contact header in 200 OK on REGISTER Ontbrekende Contact header &in 200 OK op REGISTER toegestaan Alt+I Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. Een 200 OK antwoord op een REGISTER verzoek moet een Contact header bevatten. Sommige registratie servers stoppen echter geen of een foutieve Contact header de 200 OK. Met deze optie staat u een dergelijke afwijking van de specificaties toe. &Max-Forwards header is mandatory &Max-Forwards header verplicht Alt+M Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Volgens RFC 3261 is de Max-Forwards header verplicht. Veel implementaties sturen deze header echter niet. Als u deze optie aanvinkt, dan zal Twinkle een SIP verzoek zonder Max-Forwards weigeren. Put &registration expiry time in contact header &Registratie interval in contact header Alt+R Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. In een REGISTER verzoek kan het registratie interval zowel in de Contact header als in de Expires header geplaatst worden. Als u deze optie aanvinkt, dan wordt het interval in de Contact header geplaatst, anders in de Expires header. &Use compact header names &Compacte header namen Indicates if compact header names should be used for headers that have a compact form. Geeft aan of compacte header namen gebruikt moeten worden voor headers die een compacte naam hebben. Allow SDP change during call setup SDP wijziging tijdens gespreksopbouw toestaan <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> <p>Een SIP UAS kan SDP in een 1XX antwoord sturen voor bijvoorbeeld een ring back tone. Als het gesprek beantwoord wordt, dan moet de SIP UAS dezelfde SDP in de 200 OK sturen volgens RFC 3261: <i>Once SDP has been received, SDP in subsequent responses should be discarded.</i></p> <p>Door een SDP wijziging toe te staan, zal Twinkle de SDP in de 200 OK niet negeren in dit geval en de media parameters aanpassen. Als de SDP wijzigt, dan moet die wel een nieuwe versienummer in de o= lijn hebben.</p> <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> <p> Twinkle maakt een unieke contact header waarde door de SIP gebruikersnaam te combineren met de domeinnaam: </p> <p> <tt>&nbsp;gebruikersnaam_domeinnaam@ip</tt> </p> <p> Zo krijgen 2 gebruikersprofielen met dezelfde gebruikersnaam, maar verschillende domeinnamen, toch een uniek contact adres. Hierdoor kunnen beide profielen tegelijkertijd geactiveerd worden. </p> <p> Sommige proxies vinden dit niet leuk. U kunt deze optie uitzetten voor een meer gangbare contact header: </p> <p> <tt>&nbsp;gebruikersnaam@ip</tt> </p> &Encode Via, Route, Record-Route as list Cod&eer Via, Route, Record-Route als lijst The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. De Via, Route en Record-Route headers kunnen als een lijst met door komma's gescheiden waarden worden gecodeerd of als meerdere voorkomens van dezelfde header. SIP extensions SIP extensies &100 rel (PRACK): &100 rel (PRACK): disabled uitgeschakeld supported ondersteund required vereist preferred voorkeur Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. Geeft aan of de 100rel extensie (PRACK) wordt ondersteund: <b>uitgeschakeld</b>: 100rel extensie is uitgeschakeld <br><br> <b>ondersteund</b>: 100rel wordt ondersteund (wordt toegevoegd aan de supported header in een INVITE). <br><br> <b>vereist</b>: 100rel is vereist (wordt toegevoegd aan de require header in een INVITE). Als een inkomende INVITE ondersteuning aangeeft voor 100rel, dan zal Twinkle een PRACK eisen bij het sturen van een 1XX antwoord. Een gesprek mislukt als de andere partij 100rel niet ondersteund. <br><br> <b>voorkeur</b>: Vergelijkbaar met <b>vereist</b>, maar als het gesprek mislukt omdat de andere partij 100rel niet ondersteund (420 antwoord), dan wordt het gesprek nogmaals opgezet zonder de 100rel eis. REFER REFER Call transfer (REFER) Doorverbinden (REFER) Allow call &transfer (incoming REFER) Doorverbinden &toestaan (inkomende REFER) Alt+T Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. Geeft aan of Twinkle een gesprek moet doorverbinden als een REFER verzoek wordt ontvangen. As&k user permission to transfer &Vraag toestemming voor doorverbinden Alt+K Alt+V Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Geeft aan of Twinkle de gebruiker om toestemming moet vragen alvorens een gesprek door te verbinden als een REFER verzoek ontvangen wordt. Hold call &with referrer while setting up call to transfer target Zet de partij die u doorverbindt in de &wacht tijdens doorverbinden Alt+W Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Geeft aan of Twinkle het huidige gesprek in de wacht moet zetten als een REFER verzoek is ontvangen. Ho&ld call with referee before sending REFER &Zet andere partij in de wacht voor sturen REFER Alt+L Alt+Z Indicates if Twinkle should put the current call on hold when you transfer a call. Geeft aan of Twinkle de andere partij in de wacht moet zetten als u een gesprek doorverbindt. Auto re&fresh subscription to refer event while call transfer is not finished Automatisch verversen van re&fer subscriptie tijdens doorverbinden Alt+F Alt+F While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. Tijdens doorverbinden, stuurt de partij die wordt doorverbonden NOTIFY berichten naar de partij die doorverbindt. Deze NOTIFY berichten geven de voortgang van het doorverbinden aan. Deze berichten worden voor een bepaalde tijdsduur gestuurd. Als u deze optie aanvinkt, dan zal Twinkle automatisch een SUBSCRIBE verzoek sturen om de tijdsduur te verlengen als deze verloopt voordat het doorverbinden klaar is. NAT traversal NAT oplossing &NAT traversal not needed Geen &NAT Alt+N Alt+N Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. Kies deze optie als er geen router met netwerk adres translatie (NAT) zit tussen u en uw SIP proxy of als uw SIP provider "hosted NAT traversal" biedt. &Use statically configured public IP address inside SIP messages St&atisch publiek IP adres in SIP berichten Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Geeft aan of Twinkle een statisch IP adres in de SIP berichten moet plaatsen, bijv. in headers en SDP in plaats van het prive IP adres van uw netwerk interface.<br><br> Als u deze optie kiest, dan moet u teven een adres vertaling in uw NAT router aanbrengen. U moet dezelfde RTP poorten op het publieke en prive adres gebruiken. Use &STUN &STUN Choose this option when your SIP provider offers a STUN server for NAT traversal. Kies deze optie als uw SIP provider een STUN server aanbiedt. S&TUN server: S&TUN server: The hostname, domain name or IP address of the STUN server. Host naam, domeinnaam of IP adres van de STUN server. &Public IP address: &Publiek IP adres: The public IP address of your NAT. Het publieke IP adres van uw NAT router. Telephone numbers Telefoonnummers Only &display user part of URI for telephone number Toon alleen gebruikers&deel van een URI voor een telnr If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. Als een URI een telefoonnummer is, toon dan alleen het gebruikersdeel. Voorbeeld: een gesprek komt binnen van sip:123456@twinklephone.com, dan wordt alleen "123456" getoond. Een URI is een telefoonnummer als het de parameter "user=phone" bevat of als het gebruikersdeel numeriek is en u vinkt de volgende optie aan. &URI with numerical user part is a telephone number URI met &numeriek gebruikersdeel is een telefoonnumer If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. Als u deze optie aanvinkt, dan ziet Twinkle een SIP adres dat bestaat uit cijfers, *, #, + en speciale symbolen als een telefoonnummer. In een uitgaand bericht, zal Twinkle dan de parameter "user=phone" toevoegen. &Remove special symbols from numerical dial strings Ve&rwijder speciale symbolen van numerieke strings Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. Telefoonnummers worden vaak opgeschreven met speciale symbolen zoals streepjes voor de leesbaarheid. Als u een dergelijk nummer draait, dan moeten de speciale symbolen niet gedraaid worden. Om ervoor te zorgen dat u makkelijke telefoonnumers kan knippen en plakken naar Twinkle, kan Twinkle deze symbolen verwijderen als u op de "bel" knop drukt. &Special symbols: &Speciale symbolen: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. De speciale symbolen die in een telefoonnummer kunnen staan voor de leesbaarheid, maar die verwijderd moeten worden bij het bellen. Number conversion Nummer conversie Match expression Match expressie Replace Vervang <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> <p> Vaak is het formaat van een telefoonnummer dat u moet draaien anders dan het formaat van het nummer in uw adresboek, bijv. uw nummers starten met een +-teken gevolgd door een landencode, maar uw provider verwacht '00' in plaats van het +-teken, of u bent op kantoor en u moet eerst een '9' draaien om naar buiten te bellen. Hier kunt u nummerformaatconversie definieren m.b.v. reguliere expressies en vervang strings (Perl syntax). </p> <p> Voor elk nummer dat u draait probeer Twinkle een match te vinden in de lijst met match expressies. Voor de eerste match die gevonden wordt, wordt het nummer vervangen door de vervang string. Als er geen match is, dan blijft het nummer onveranderd. </p> <p> Nummerconversie wordt ook toegepast op inkomende gesprekken, zodat de nummers getoond worden zoals u dat wilt. </p> <h3>Voorbeeld 1</h3> <p> Uw landencode is 31 en u heeft alle nummers in uw adresboek in volledig internationaal formaat opgeslagen, bijv. +318712345678. Om nummers binnen Nederland te draaien wilt u de '+31' vervangen door '0'. Voor het draaien van buitenlandse nummers wilt u de '+' vervangen door '00'. </p> <p> De volgende match/vervang regels doen dit voor u: </p> <blockquote> <tt> Match expressie = \+31([0-9]*) , Vervang = 0$1<br> Match expressie = \+([0-9]*) , Vervang = 00$1</br> </tt> </blockquote> <h3>Voorbeeld 2</h3> <p> U bent op kantoor en alle nummers met een 0 moeten voorafgegaan worden door een 9 voor een buitenlijn. </p> <blockquote> <tt> Match expressie = 0[0-9]* , Vervang = 9$&<br> </tt> </blockquote> Move the selected number conversion rule upwards in the list. Schuif de geselecteerde conversie omhoog in de lijst. Move the selected number conversion rule downwards in the list. Schuif de geselecteerde conversie omlaag in de lijst. &Add To&evoegen Add a number conversion rule. Voeg een nummerconversie toe. Re&move &Verwijder Remove the selected number conversion rule. Verwijder de geselcteerde nummerconversie. &Edit &Bewerk Edit the selected number conversion rule. Bewerk de geselecteerde nummerconversie. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. Voer een telefoonnummer in en druk op de Test-knop om te zien hoe het nummer geconverteerd wordt door de lijst van nummerconversies. &Test &Test Test how a number is converted by the number conversion rules. Test hoe een nummer geconverteerd wordt door de nummerconversies. for STUN STUN Keep alive timer for the STUN protocol. If you have enabled STUN, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. Keep alive timer voor het STUN protocol. Als u STUN aan heeft gezet, dan zal Twinkle keep alive pakketjes sturen met deze snelheid om de adresbindingen in uw NAT router in leven te houden. When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". Als een gesprek binnenkomt, dan wordt deze timer gestart. Als de gebruiker antwoordt, dan wordt de timer gestopt. Als de timer afloopt voordat de gebruiker antwoordt, dan weigert Twinkle het gesprek met "480 User Not Responding". NAT &keep alive: NAT &keep alive: &No answer: Gee&n antwoord: Ring &back tone: Ring &back tone: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p> Naam van het .wav bestand dat u gespeeld wilt hebben als ring back tone voor dit gebruikersprofiel. </p> <p> Deze ring back tone heeft voorrang boven de ring back tone in de systeeminstellingen. </p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> <p> Naam van het .wav bestand dat u gespeeld wilt hebben als ring tone voor dit gebruikersprofiel. </p> <p> Deze ring back tone heeft voorrang boven de ring tone in de systeeminstellingen. </p> &Ring tone: &Ring tone: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als u een gesprek beëindigd. </p> <h2>Variabelen</h2> <p> De waarden van alle SIP headers van de uitgaande SIP BYE verzoek worden via variabelen aan uw script doorgegeven. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> bevat request-URI van de BYE. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als een inkomend gesprek mislukt. </p> <h2>Variabelen</h2> De waarden van alle SIP headers van de uitgaande SIP fout indicatie worden via variabelen aan uw script doorgegeven. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> bevat de status code de fout indicatie. <b>SIPSTATUS_REASON</b> bevat de foutmelding. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als de andere partij het gesprek beëindigd. </p> <h2>Variabelen</h2> <p> De waarden van alle SIP headers van de inkomende SIP BYE worden via variabelen aan uw script doorgegeven. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> bevat de request-URI van de BYE. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als de andere partij uw gesprek beantwoordt. </p> <h2>Variabelen</h2> <p> De waarden van alle SIP headers van de inkomende 200 OK worden via variabelen aan uw script doorgegeven. </p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> bevat de status melding. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als u een inkomend gesprek beantwoordt. </p> <h2>Variabelen</h2> <p> De waarden van alle SIP headers van de uitgaande 200 OK worden via variabelen aan uw script doorgegeven. </p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> bevat de status melding. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. Call released locall&y: Gesprek beëindigd &door uzelf: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als een uitgaand gesprek mislukt. </p> <h2>Variabelen</h2> <p> De waarden van alle SIP headers van de inkomende SIP foutmelding worden via variabelen aan uw script doorgegeven. </p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> bevat de foutcode. <b>SIPSTATUS_REASON</b> bevat de foutmelding. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> Dit script wordt aangeroepen als u een nummer draait. </p> <h2>Variabelen</h2> <p> De waarden van alle SIP headers van de uitgaande SIP INVITE worden via variabelen aan uw script doorgegeven. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> bevat request-URI van de INVITE. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. Outgoing call a&nswered: Uitgaand gesprek bea&ntwoord: Incoming call &failed: Inkomend gesprek &mislukt: &Incoming call: &Inkomend gesprek: Call released &remotely: Gesp&rek beëindigd door ander: Incoming call &answered: Inkomend gesprek be&antwoord: O&utgoing call: Ui&tgaand gesprek: Out&going call failed: Uit&gaand gesprek mislukt: &Enable ZRTP/SRTP encryption ZRTP/SRTP &encryptie When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. Als u ZRTP/SRTP aanzet, dan zal Twinkle proberen om het audiokanaal van uw gesprekken te versleutelen. Versleuteling lukt alleen als uw gesprekspartner ook ZRTP/SRTP ondersteunt. Als uw gesprekspartner geen ZRTP/SRTP ondersteund, dan blijft het audiokanaal onversleuteld. ZRTP settings ZRTP instellingen O&nly encrypt audio if remote party indicated ZRTP support in SDP Allee&n versleutelen als de andere partij ZRTP ondersteuning in SDP aangeeft A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. Een SIP toestel kan tijdens de gespreksopbouw aangeven of het ZRTP ondersteunt. Met deze optie zal Twinkle de audio alleen proberen te versleutelen als de andere partij ondesteuning voor ZRTP gesignaleerd heeft. &Indicate ZRTP support in SDP S&ignaleer ZRTP ondersteuning in SDP Twinkle will indicate ZRTP support during call setup in its signalling. Twinkle zal tijdens gespreksopbouw aangeven dat het ZRTP ondersteunt. &Popup warning when remote party disables encryption during call &Popup waarschuwing als de andere partij versleuteling uitzet A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. Als de andere partij tijdens een versleuteld gesprek een ZRTP go-clear commando stuurt om de versleuteling te stoppen, dan zal Twinkle een waarschuwing geven. Dynamic payload type %1 is used more than once. Dynamische payload type %1 is meer malen gebruikt. You must fill in a user name for your SIP account. U moet een gebruikersnaam voor uw SIP account invullen. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. U moet een domeinnaam voor uw SIP account invullen. Dit kan de host naam of IP adres van uw PC zijn als u direct van PC naar PC wilt bellen. Invalid user name. Ongeldige gebruikersnaam. Invalid domain. Ongeldig domein. Invalid value for registrar. Ongeldige waarde voor de registratie server. Invalid value for outbound proxy. Ongeldige waarde voor de uitgaande proxy. Value for public IP address missing. Publiek IP adres ontbreekt. Invalid value for STUN server. Ongeldige waarde voor STUN server. Ring tones Description of .wav files in file dialog Ring tones Choose ring tone Kies ring tone Ring back tones Description of .wav files in file dialog Ring back tones All files Alle bestanden Choose incoming call script Kies script voor inkomende gesprekken Choose incoming call answered script Kies script voor beantwoording inkomend gesprek Choose incoming call failed script Kies script voor mislukken inkomend gesprek Choose outgoing call script Kies script voor uitgaande gesprekken Choose outgoing call answered script Kies script voor beantwoording uitgaande gesprek Choose outgoing call failed script Kies script voor mislukken uitgaande gesprek Choose local release script Kies script voor beëindigen gesprek door uzelf Choose remote release script Kies script voor beëindigen gesprek door ander Co&decs Co&decs Indicates if Twinkle should redirect a request if a 3XX response is received. Geeft aan of Twinkle een verzoek moet doorverwijzen als een 3XX antwoord wordt ontvangen. Authentication &name: Authenticatie &naam: Voice mail Voice mail &Follow codec preference from far end on incoming calls &Volg codec voorkeur van de beller bij inkomende gesprekken <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. <p> Volg de voorkeur van de beller (SDP aanbod) bij inkomende gesprekken. Neem de eerste codec uit het SDP aanbod dat ook in de lijst van actieve codecs voorkomt. <p> Als u deze optie uitschakeld, dan neemt Twinkle de eerste codec uit de actieve codec lijst die ook in het SDP aanbod voorkomt. Follow codec &preference from far end on outgoing calls Volg &codec voorkeur van de gebelde bij uitgaande gesprekken <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. <p> Volg de voorkeur van de gebelde (SDP antwoord) bij uitgaande gesprekken. Neem de eerste codec uit het SDP antwoord dat ook in de lijst van actieve codecs voorkomt. <p> Als u deze optie uitschakelt, dan neemt Twinkle de eerste codec uit de actieve codec lijst die ook in het SDP antwoord voorkomt. Replaces Replaces Indicates if the Replaces-extenstion is supported. Geeft aan of de Replaces-extensie ondersteund wordt. Attended refer to AoR (Address of Record) Begeleid doorverbinden maar AoR (Address of Record) An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. Bij begeleid doorverbinden, is de contact URI de doorverbindbestemming. Een contact URI kan echter niet globaal routeerbaar zijn. Als alternatief kan dan de AoR (Address of Record) gebruikt worden. Een nadeel van het gebruik van de AoR is dat deze routeerbaar kan zijn naar meerdere eindpunten in het geval van SIP forking. De contact URI routeert altijd naar een uniek eindpunt. Privacy Privacy Privacy options Privacy opties &Send P-Preferred-Identity header when hiding user identity &Stuur P-Preferred-Identity header bij anonieme gesprekken Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. Stuur de P-Preferred-Identity header in een INVITE verzoek, als u uw identiteit verbergt bij het maken van een gesprek. <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> U kunt het gedrag waarmee Twinkle inkomende gesprekken afhandelt aanpassen met een script dat Twinkle aanroept als een gesprek binnenkomt. Afhankelijk van de output van het script accepteert of weigert Twinkle het gesprek of verwijst het door. </p> <p> <b>Let op:</b> Twinkle staat stil als het script loopt. Het is aanbevolen dat uw script niet langer dan 200 ms loopt. Als u meer tijd nodig heeft, dan kunt u de parameters sturen gevolgd door <b>end</b>. Twinkle gaat verder zodra het <b>end</b> ontvangt, terwijl u script blijft draaien. </p> <p> U kunt Twinkle sturen door de volgende parameters naar stdout te schrijven. Elk op een nieuwe regel. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;adres voor doorverwijzen&gt;<br> caller_name=&lt;toon deze naam&gt;<br> ringtone=&lt;naam van .wav bestand&gt;<br> display_msg=&lt;toon bericht op scherm&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - handel gesprek af op normale wijze<br> <b>reject</b> - weiger gesprek<br> <b>dnd</b> - weiger gesprek met niet-storen indicatie<br> <b>redirect</b> - verwijs gesprek door naar <b>contact</b><br> <b>autoanswer</b> - automatisch antwoorden<br> </p> <p> Als een script geen actie op stdout zet, dan is de actie "continue" </p> <p> <b>reason: </b> Met de reason parameter, zet u de SIP reason string voor reject of dnd. Dit kan getoond worden aan de gebruiker. </p> <p> <b>caller_name: </b> Toon deze naam in plaats van de display naam. </p> <p> <b>ringtone: </b> De ring tone die gespeeld moet worden als de actie "continue" is. </p> <h2>Variables</h2> <p> De waarden van alle SIP headers van de inkomende INVITE worden via variabelen aan uw script doorgegeven. De variabele namen zijn als volgt samengesteld <b>SIP_&lt;HEADER_NAME&gt;</b> Bijv. SIP_FROM bevat de waarde van de from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. <b>SIPREQUEST_URI</b> bevat de request-URI van de INVITE. <b>TWINKLE_USER_PROFILE</b> bevat de gebruikersprofielnaam. &Voice mail address: &Voice mail adres: The SIP address or telephone number to access your voice mail. SIP adres of telefoonnummer van uw voice mail. Unsollicited Unsollicited Sollicited Sollicited <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> <H2>Message waiting indication type</H2> <p> Als uw provider de dienst aanbiedt waarmee u uw voice mail status kunt zien, dan kan Twinkle laten zien hoeveel nieuwe voice mail berichten er op u wachten. Er zijn 2 methoden waarop deze dienst kan worden aangeboden. </p> <H3>Unsollicited</H3> <p> Asterisk biedt unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication zoals gespecificeerd in RFC 3842. </p> &MWI type: &MWI type: Sollicited MWI Sollicited MWI Subscription &duration: Aanmeldings&duur: Mailbox &user name: Mailbox &gebruikersnaam: The hostname, domain name or IP address of your voice mailbox server. De host naam, domeinnaam of IP adres van uw voice mailbox server. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Twinkle meldt zich voor een bepaalde periode aan bij de voice mailbox server. Net voordat deze periode verstrijkt, zal Twinkle zich opnieuw aanmelden. Your user name for accessing your voice mailbox. Uw gebruikersnaam voor toegang tot uw mailbox. Mailbox &server: Mailbox &server: Via outbound &proxy Via uitgaande &proxy Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. Vink deze optie aan als Twinkle de SIP berichten naar de mailbox server via de uitgaande proxy moet sturen. You must fill in a mailbox user name. U moet een mailbox gebruikersnaam invullen. You must fill in a mailbox server U moet een mailbox server invullen Invalid mailbox server. Ongeldige mailbox server. Invalid mailbox user name. Ongeldige mailbox gebruikersnaam. Codeword &packing order: Codeword &packing volgorde: RFC 3551 RFC 3551 ATM AAL2 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. Er zijn 2 methoden om G.726 codewords in een RTP pakket te stoppen. RFC 3551 is de default methode. Sommige SIP apparaten gebruiken de ATM AAL2 methode echter. Als bij het gebruik van G.726 met RFC 3551 packing de geluidskwaliteit slecht is, probeer dan ATM AAL2 packing. Use domain &name to create a unique contact header value &Gebruik domeinnaam voor een unieke contact header Select ring back tone file. Selecteer ring back tone bestand. Select ring tone file. Selecteer ring tone bestand. Select script file. Selecteer script bestand. %1 converts to %2 %1 wordt geconverteerd naar %2 Instant message Instant bericht Presence Beschikbaarheid &Maximum number of sessions: &Maximum aantal sessies: When you have this number of instant message sessions open, new incoming message sessions will be rejected. Als u het maximum aantal berichtensessies actief heeft, dan zullen inkomende berichten voor nieuwe sessies geweigerd worden. Your presence Uw beschikbaarheid &Publish availability at startup &Publiceer beschikbaarheid bij opstarten Publish your availability at startup. Publiceer uw beschikbaarheid bij opstarten. Buddy presence Beschikbaarheid van vrienden Publication &refresh interval (sec): Publicatie &interval (sec): Refresh rate of presence publications. Verversingssnelheid van beschikbaarheidspublicaties. &Subscription refresh interval (sec): Aan&meldingsinterval (sec): Refresh rate of presence subscriptions. Verversingsnelheid van beschikbaarheidsaanmeldingen. Transport/NAT Transport/NAT Add q-value to registration Voeg q-waarde toe aan registratie The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. De q-waarde is de prioriteit van een apparaat. Als u naast Twinkle nog andere SIP apparaten bij het netwerk registreert voor deze gebruiker, dan kan het netwerk deze waarde gebruiken om te bepalen op welk apparaat een gesprek als eerste afgeleverd moet worden. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. De q-waarde is een waarde tussen 0,000 en 1,000. Een hogere waarde betekent een hogere prioriteit. SIP transport SIP transport UDP UDP TCP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. Transport modus voor SIP. In auto modus bepaalt de berichtgrootte welk transport protocol gebruikt wordt. Berichten groter dan de UDP drempel worden via TCP verstuurd. Kleinere berichten worden via UDP gestuurd. T&ransport protocol: T&ransport protocol: UDP t&hreshold: UDP &drempel: bytes bytes Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. Berichten groter dan de drempel worden via TCP verstuurd. Kleinere berichten worden via UDP verstuurd. Use &STUN (does not work for incoming TCP) &STUN (werkt niet voor inkomend TCP verkeer) P&ersistent TCP connection P&ersistente TCP verbinding Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. De TCP verbinding die opgezet wordt tijdens registratie blijft open, zodat de SIP proxy deze verbinding kan gebruiken om binnenkomende verzoeken te sturen. Ping pakketten worden gestuurd om te testen of de verbinding nog bestaat. &Send composing indications when typing a message. &Zend indicaties als u een bericht aan het schrijven bent. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. Twinkle stuurt een compositie indicatie als u een bericht aan het schrijven bent. De ontvanger van uw bericht kan dan zien dat u bezig bent met schrijven. AKA AM&F: AkA AM&F: A&KA OP: A&KA OP: Authentication management field for AKAv1-MD5 authentication. "Authentication management field" voor AKAv1-MD5 authenticatie. Operator variant key for AKAv1-MD5 authentication. "Operator variant key" voor AKAv1-MD5 authenticatie. Prepr&ocessing V&oorbewerking Preprocessing (improves quality at remote end) Voorbewerking (verbetert de geluidskwaliteit voor uw gesprekspartner) &Automatic gain control &Automatische sterkteregeling Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Automatische sterkteregeling versterkt zachte signalen en dempt luide signalen die door de microfoon worden opgenomen. Automatic gain control &level: Niveau automatische sterkterege&ling: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. Een waarde rond 25% is aanbevolen voor een goede geluidskwaliteit. &Voice activity detection &Voice activity detection When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. "Voice activity detection" detecteteert of een signaal spraak of stilte/ruid bevat. Stilte/ruis wordt niet over het netwerk gestuurd waardoor minder bandbreedte gebruikt wordt. &Noise reduction Ruisonderdrukki&ng The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. Ruisonderdrukking vermindert achtergrondruis in het microfoonsignaal. Acoustic &Echo Cancellation Acoustic &Echo Cancellation In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Spraak uit de speakers wordt opgevangen door de microfoon waardoor uw gesprekspartner een echo waarneemt. "Acoustic echo cancellation" verwijdert deze echo. Variable &bit-rate Variable &bit-rate Discontinuous &Transmission Discontinuous &Transmission &Quality: &Kwaliteit: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. Speex comprimeert het geluidssignaal ten koste van de kwaliteit. Hoe meer compressie, hoe minder bandbreedte nodig is, maar hoe slechter de geluidskwaliteit. Deze kwaliteitsfactor (0 tot 10) bepaalt de trade-off tussen kwaliteit en compressie. bytes bytes Use tel-URI for telephone &number Vestuur telefoon&nummer als tel-URI Expand a dialed telephone number to a tel-URI instead of a sip-URI. Expandeer een telefoonnummer naar een tel-URI in plaats van een sip-URI. Accept call &transfer request (incoming REFER) Accep&teer doorverbindverzoek (inkomende REFER) Allow call transfer while consultation in progress Doorverbinden toestaan tijdens opbouw ruggespraak gesprek When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. Bij doorverbinden met ruggespraak, verbindt u normaal pas door nadat u ruggespraak heeft gehouden. Met deze optie kunt u al doorverbinden terwijl het gesprek voor ruggespraak nog in opbouw is. Dit is een niet-standaard implementatie die mogelijk niet werkt met alle SIP apparaten. Enable NAT &keep alive NAT &keep alive Send UDP NAT keep alive packets. Stuur UDP NAT keep alive pakketten. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. Als u STUN of NAT keep alive aan heeft gezet, dan zal Twinkle keep alive pakketjes sturen met deze snelheid om de adresbindingen in uw NAT router in leven te houden. WizardForm Twinkle - Wizard Twinkle - Wizard The hostname, domain name or IP address of the STUN server. De host naam, domeinnaam of IP adres van de STUN server. S&TUN server: S&TUN server: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. De SIP gebruikersnaam die u van uw provider heeft gekregen. Dit het gebruikersdeel in uw SIP adres, <b>gebruikersnaame</b>@domein.nl Dit kan een telefoonnummer zijn. <br><br> Dit is een verplicht veld. &Domain*: &Domein*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. Kies uw SIP provider. Als uw SIP provider niet in de lijst voorkomt, kies dan <b>Anders</b> en vul de instellingen in die uw van uw provider hebt gekregen.<br><br> Als u een voorgedefinieerde SIP provider kiest, dan hoeft u alleen uw eigen naam, gebruikersnaam, authenticatie naam en paswoord in te voeren. &Authentication name: &Authenticatie naam: &Your name: U&w naam: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Uw SIP gebruikersnaam voor authenticatie. Meestal is dit hetzelfde als uw SIP gebruikersnaam. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Dit is het domein deel van uw SIP adres, gebruikersnaame@<b>domein.nl</b>. In plaats van een echt domein kan dit ook de host naam of het IP van uw <b>SIP proxy</b> zijn. Als u direct van IP adres naar IP adres wilt bellen, dan vult u hier de host naam of IP adres van uw computer in. <br><br> Dit is een verplicht veld. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Dit is uw eigen naam. bijv. Jan Jansen. Als u iemand belt, kan deze naam getoond worden. SIP pro&xy: SIP pro&xy: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. De host naam, domeinnaam of IP adres van uw SIP proxy. Als deze hetzelfde is als uw domeinnaam, dan mag u dit veld leeg laten. &SIP service provider: &SIP provider: &Password: &Paswoord: &User name*: Ge&bruikersnaam*: Your password for authentication. Uw paswoord voor authenticatie. &OK &OK Alt+O Alt+O &Cancel Ann&uleren Alt+C Alt+U None (direct IP to IP calls) Geen (directe IP naar IP gesprekken) Other Anders User profile wizard: Gebruikersprofiel wizard: You must fill in a user name for your SIP account. U moet een gebruikersnaam voor uw SIP account invullen. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. U moet een domeinnaam voor uw SIP account invullen. Dit kan de host naam of IP adres van uw PC zijn als u direct van PC naar PC wilt bellen. Invalid value for SIP proxy. Ongeldige waarde voor SIP proxy. Invalid value for STUN server. Ongeldige waared voor STUN server. YesNoDialog &Yes &Ja &No &Nee twinkle-1.4.2/src/gui/lang/twinkle_ru.ts0000644000175000001440000077001611151060224015142 00000000000000 AddressCardForm Twinkle - Address Card Twinkle - Карточка абонента &Remark: &ОпиÑание: Infix name of contact. ÐŸÑ€ÐµÑ„Ð¸ÐºÑ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°. First name of contact. Ð˜Ð¼Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°. &First name: &ИмÑ: You may place any remark about the contact here. Ð’Ñ‹ можете впиÑать Ñюда любое опиÑание Ñтого контакта. &Phone: &Телефон: &Infix name: &ÐŸÑ€ÐµÑ„Ð¸ÐºÑ Ð¸Ð¼ÐµÐ½Ð¸: Phone number or SIP address of contact. Телефонный номер или SIP Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°. Last name of contact. Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°. &Last name: &ФамилиÑ: &OK &ПринÑть Alt+O &Cancel &Отмена Alt+C You must fill in a name. Ð’Ñ‹ должны заполнить поле имÑ. You must fill in a phone number or SIP address. Ð’Ñ‹ должны заполнить поле номер телефона или SIP Ð°Ð´Ñ€ÐµÑ AuthenticationForm Twinkle - Authentication Twinkle - ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ user No need to translate пользователь The user for which authentication is requested. Пользователь, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ запрашиваетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ. profile No need to translate профиль The user profile of the user for which authentication is requested. Профиль пользователÑ, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ запрашиваетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ. User profile: Профиль пользователÑ: User: Пользователь: &Password: &Пароль: Your password for authentication. Ваш пароль Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ваше аутентификационное Ð¸Ð¼Ñ Ð´Ð»Ñ SIP. Ð’ большинÑтве Ñлучаем Ñовпадает Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ SIP. Ð’Ñ‹ можете ввеÑти здеÑÑŒ другое Ð¸Ð¼Ñ Ð¿Ñ€Ð¸ необходимоÑти. &User name: &Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: &OK &ЗапиÑать &Cancel &Отмена Login required for realm: Ð˜Ð¼Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÐ¼Ð¾Ðµ Ð´Ð»Ñ Ð¾Ð±Ð»Ð°Ñти: realm No need to translate облаÑть The realm for which you need to authenticate. ОблаÑть Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ нужна авторизациÑ. BuddyForm Twinkle - Buddy Twinkle - Ð”Ñ€ÑƒÐ·ÑŒÑ Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. &Phone: &Телефон: Name of your buddy. Ð˜Ð¼Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ друга. &Show availability &Показать доÑтупноÑть Alt+S Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. Выберите Ñту опцию еÑли вы хотите видеть доÑтупноÑть вашего друга. Это работает, только еÑли ваш провайдер предоÑтавлÑет уÑлугу проверки доÑтупноÑти. &Name: &ИмÑ: SIP address your buddy. SIP Ð°Ð´Ñ€ÐµÑ Ñ‚Ð²Ð¾ÐµÐ³Ð¾ друга. &OK &ПринÑть Alt+O &Cancel &Отмена Alt+C You must fill in a name. Ð’Ñ‹ должны заполнить имÑ. Invalid phone. Ðе правильный телефон. Failed to save buddy list: %1 Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑпиÑка друзей: %1 BuddyList Availability ДоÑтупноÑть unknown неизвеÑтно offline не в Ñети online в Ñети request failed ошибка запроÑа request rejected Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¾Ñ‚ÐºÐ»Ð¾Ð½Ñ‘Ð½ not published не опубликован failed to publish ошибка публикации Click right to add a buddy. Правый клик Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ñ€ÑƒÐ·ÐµÐ¹. CoreAudio Failed to open sound card Ошибка Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð·Ð²ÑƒÐºÐ¾Ð²Ð¾Ð¹ карты Failed to create a UDP socket (RTP) on port %1 Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ UDP Ñокета (RTP) на порту %1 Failed to create audio receiver thread. Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð½Ð¸Ð¼Ð°ÐµÐ¼Ð¾Ð³Ð¾ аудиопотка. Failed to create audio transmitter thread. Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°ÐµÐ¼Ð¾Ð³Ð¾ аудиопотка. CoreCallHistory local user локальный пользователь remote user удалённый пользователь failure ошибка unknown неизвеÑтно in входÑщий out иÑходÑщий DeregisterForm Twinkle - Deregister Twinkle - РазрегиÑÑ‚Ð°Ñ‚Ñ€Ð°Ñ†Ð¸Ñ deregister all devices разрегиÑтрировать вÑе уÑтройÑтва &OK &ПринÑть &Cancel &Отмена DiamondcardProfileForm Twinkle - Diamondcard User Profile Your Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. &Account ID: &PIN code: &Your name: &Ваше имÑ: <p align="center"><u>Sign up for a Diamondcard account</u></p> &OK Alt+O &Cancel &Отмена Alt+C Fill in your account ID. Fill in your PIN code. A user profile with name %1 already exists. Your Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> DtmfForm Twinkle - DTMF Twinkle - DTMF Keypad Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ ÐºÐ»Ð°Ð²Ð¸Ð°Ñ‚ÑƒÑ€Ð° 2 3 Over decadic A. Normally not needed. Ðе цифровое A. Обычно не нужно. 4 5 6 Over decadic B. Normally not needed. Ðе цифровое B. Обычно не нужно. 7 8 9 Over decadic C. Normally not needed. Ðе цифровое C. Обычно не нужно. Star (*) Звезда (*) 0 Pound (#) Решётка (#) Over decadic D. Normally not needed. Ðе цифровое D. Обычно не нужно. 1 &Close &Закрыть Alt+C FreeDeskSysTray Show/Hide Показать/Скрыть Quit Выход GUI Failed to create a %1 socket (SIP) on port %2 Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ %1 Ñокет (SIP) на порту %2 Override lock file and start anyway? Перехватить файл блокировки и запуÑтитьÑÑ ÑейчаÑ? The following profiles are both for user %1 You can only run multiple profiles for different users. If these are users for different domains, then enable the following option in your user profile (SIP protocol) Use domain name to create a unique contact header ИÑпользуйте доменное Ð¸Ð¼Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ заголовка контакта Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Ðе могу найти Ñетевой интерфейÑ. Twinkle будет иÑпользовать 127.0.0.1 как локальный IP адреÑ. Когда вы будете Ñоединены Ñ Ñетью перезапуÑтите Twinkle Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð³Ð¾ IP адреÑа. Line %1: incoming call for %2 Ð›Ð¸Ð½Ð¸Ñ %1: входÑщий звонок Ð´Ð»Ñ %2 Call transferred by %1 Звонок переведён к %1 Line %1: far end cancelled call. Ð›Ð¸Ð½Ð¸Ñ %1: ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð°Ñ Ñторона прервала звонок. Line %1: far end released call. Ð›Ð¸Ð½Ð¸Ñ %1: ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð°Ñ Ñторона закончила звонок. Line %1: SDP answer from far end not supported. Ð›Ð¸Ð½Ð¸Ñ %1: SDP ответ от удалённой Ñтороны не поддерживаетÑÑ. Line %1: SDP answer from far end missing. Ð›Ð¸Ð½Ð¸Ñ %1: SDP ответ от удалённой Ñтороны отÑутÑтвует. Line %1: Unsupported content type in answer from far end. Ð›Ð¸Ð½Ð¸Ñ %1: Ðе поддерживаемый тип Ñодержимого в ответе от удалённой Ñтороны. Line %1: no ACK received, call will be terminated. Ð›Ð¸Ð½Ð¸Ñ %1: не получен ACK, звонок прерван. Line %1: no PRACK received, call will be terminated. Ð›Ð¸Ð½Ð¸Ñ %1: не получен PRACK, звонок будет прерван. Line %1: PRACK failed. Ð›Ð¸Ð½Ð¸Ñ %1: PRACK ошибка. Line %1: failed to cancel call. Ð›Ð¸Ð½Ð¸Ñ %1: Ошибка Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ°. Line %1: far end answered call. Ð›Ð¸Ð½Ð¸Ñ %1: ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð°Ñ Ñторона ответила на звонок. Line %1: call failed. Ð›Ð¸Ð½Ð¸Ñ %1: Ошибка звонка. The call can be redirected to: Звонок будет переведён к: Line %1: call released. Ð›Ð¸Ð½Ð¸Ñ %1: Ñоединение завершено. Line %1: call established. Ð›Ð¸Ð½Ð¸Ñ %1: Ñоединение уÑтановлено. Response on terminal capability request: %1 %2 Ответ на Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¾Ñ€Ð³Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ð¹ терминала: %1 %2 Terminal capabilities of %1 ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÑ€Ð¼Ð¸Ð½Ð°Ð»Ð° от %1 Accepted body types: Разрешённые типы Ñодержимого: unknown неизвеÑтный Accepted encodings: Подтверждённые кодировки: Accepted languages: Подтверждённые Ñзыки: Allowed requests: Разрешённые запроÑÑ‹: Supported extensions: Поддерживаемые раÑширениÑ: none нету End point type: Тип конечной точки: Line %1: call retrieve failed. Ð›Ð¸Ð½Ð¸Ñ %1: ошибка Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ°. %1, registration failed: %2 %3 %1, ошибка региÑтрации: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð° (уÑтаревание = %2 Ñекунд) %1, registration failed: STUN failure %1, ошибка региÑтрации: ошибка STUN %1, de-registration succeeded: %2 %3 %1, разрегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑоÑтоÑлаÑÑŒ: %2 %3 %1, de-registration failed: %2 %3 %1, ошибка разрегиÑтрации: %2 %3 %1, fetching registrations failed: %2 %3 %1, ошибка проверки региÑтрации: %2 %3 : you are not registered : вы не зарегиÑтрированы : you have the following registrations : вы имеете Ñледующие региÑтрации : fetching registrations... : проверка региÑтрации... Line %1: redirecting request to Ð›Ð¸Ð½Ð¸Ñ %1: перенаправление запроÑа к Redirecting request to: %1 Перенаправление запроÑа к: %1 Line %1: DTMF detected: Ð›Ð¸Ð½Ð¸Ñ %1: определён DTMF: invalid DTMF telephone event (%1) неправильное телефонное DTMF Ñобытие (%1) Line %1: send DTMF %2 Ð›Ð¸Ð½Ð¸Ñ %1: поÑылка DTMF %2 Line %1: far end does not support DTMF telephone events. Ð›Ð¸Ð½Ð¸Ñ %1: ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð°Ñ Ñтороны не поддерживает DTMF ÑобытиÑ. Line %1: received notification. Ð›Ð¸Ð½Ð¸Ñ %1: получено оповещение. Event: %1 Событие %1 State: %1 СоÑтоÑние: %1 Reason: %1 Причина: %1 Progress: %1 %2 ПрогреÑÑ: %1 %2 Line %1: call transfer failed. Ð›Ð¸Ð½Ð¸Ñ %1: ошибка передачи звонка. Line %1: call succesfully transferred. Ð›Ð¸Ð½Ð¸Ñ %1: Перевод звонка завершён. Line %1: call transfer still in progress. Ð›Ð¸Ð½Ð¸Ñ %1: перевод звонка. No further notifications will be received. Ðикакие дальнейшие ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ будут получены. Line %1: transferring call to %2 Ð›Ð¸Ð½Ð¸Ñ %1. передача звонка к %2 Transfer requested by %1 Перевод запрошен %1 Line %1: Call transfer failed. Retrieving original call. Ð›Ð¸Ð½Ð¸Ñ %1: Ошибка передачи звонка. Получение оригинального звонка. %1, STUN request failed: %2 %3 %1, ошибка STUN запроÑа: %2 %3 %1, STUN request failed. %1, Ошибка STUN запроÑа. Redirecting call Перенаправление звонка User profile: Профиль пользователÑ: User: Пользователь: Do you allow the call to be redirected to the following destination? Ð’Ñ‹ разрешаете переводить звонки к Ñледующему направлению? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. Redirecting request Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Do you allow the %1 request to be redirected to the following destination? Ð’Ñ‹ разрешаете перевеÑти Ð·Ð°Ð¿Ñ€Ð¾Ñ %1 к Ñледующему назначению? Transferring call Передача звонка Request to transfer call received from: Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð° звонка получен от: Request to transfer call received. Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð° звонка получен. Do you allow the call to be transferred to the following destination? Ð’Ñ‹ разрешаете передачу звонка к Ñледующему назначению? Info: ИнформациÑ: Warning: Внимание: Critical: КритичеÑкое: Firewall / NAT discovery... Фаервол / NAT обнаружение... Abort Прервать Line %1 Ð›Ð¸Ð½Ð¸Ñ %1 Click the padlock to confirm a correct SAS. Ðажмите на замок Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð´ÐµÐ½Ð¸Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾Ñти SAS. The remote user on line %1 disabled the encryption. Удалённый пользователь на линии %1 запретил шифрование. Line %1: SAS confirmed. Ð›Ð¸Ð½Ð¸Ñ %1: SAS подтверждён. Line %1: SAS confirmation reset. Ð›Ð¸Ð½Ð¸Ñ %1: ÑÐ±Ñ€Ð¾Ñ SAS подтверждениÑ. %1, voice mail status failure. %1, ошибка ÑтатуÑа голоÑовой почты. %1, voice mail status rejected. %1, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð³Ð¾Ð»Ð¾Ñовой почты не принÑÑ‚. %1, voice mailbox does not exist. %1, Ñщик голоÑовой почты не ÑущеÑтвует. %1, voice mail status terminated. %1, прерван ÑÑ‚Ð°Ñ‚ÑƒÑ Ð³Ð¾Ð»Ð¾Ñовой почты. Accepted by network Разрешён Ñетью Line %1: call rejected. Ð›Ð¸Ð½Ð¸Ñ %1: звонок Ñброшен. Line %1: call redirected. Ð›Ð¸Ð½Ð¸Ñ %1: звонок пенаправлен. Failed to start conference. Ошибка запуÑка конференции. Failed to save message attachment: %1 Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑообщениÑ: %1 Transferred by: %1 Cannot open web browser: %1 Configure your web browser in the system settings. GetAddressForm Twinkle - Select address Twinkle - Выбор адреÑа &KAddressBook ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° &KDE Name Ð˜Ð¼Ñ Type Тип Phone Телефон This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. Этот ÑпиÑок адреÑов получен из <b>ÐдреÑной книги KDE</b>. Контакты которые на Ñодержат телефонного номера здеÑÑŒ не показываютÑÑ. Ð”Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ, ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ модификации адреÑной информации вы должны иÑпользовать ÐдреÑную книгу KDE. &Show only SIP addresses &Показать только SIP адреÑа Alt+S Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". Отметьте Ñту опцию еÑли вы ходите видеть только контакты Ñ SIP адреÑами, те которые начинаютÑÑ Ñ <b>sip:</b>". &Reload &Обновить Alt+R Reload the list of addresses from KAddressbook. Перезагрузить ÑпиÑок адреÑов из ÐдреÑной книги KDE. &Local address book &Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð°Ð´Ñ€ÐµÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Remark ОпиÑание Contacts in the local address book of Twinkle. Контакты из локальной адреÑной книги Twinkle. &Add &Добавить Alt+A Add a new contact to the local address book. Добавить новый контакт в локальную адреÑную книгу. &Delete &Удалить Alt+D Delete a contact from the local address book. Удалить контакт из локальной адреÑной книги. &Edit &Редактировать Alt+E Edit a contact from the local address book. Редактировать контакт из локальной адреÑной книги. &OK &ПринÑть Alt+O &Cancel &Отмена Alt+C <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> <p>У Ð’Ð°Ñ Ð½ÐµÑ‚ ни одного контакта Ñ Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð½Ñ‹Ð¼ номером в <b>KAddressBook</b>(приложении KDE адреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð°). Twinkle получает вÑе контакты Ñ Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð½Ñ‹Ð¼Ð¸ номерами из ÐдреÑной книги KDE. Ð”Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ контактами вы должны иÑпользовать KAddressBook.<p>Как альтернативу вы можете иÑпользовать локальную адреÑную книгу Twinkle.</p> GetProfileNameForm Twinkle - Profile name Twinkle - Ð˜Ð¼Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ &OK &ПринÑть &Cancel &Отмена Enter a name for your profile: Введите Ð¸Ð¼Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ профилÑ: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> <b>Ð˜Ð¼Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ профилÑ</b> <br><br> Профиль Ñодержит ваши пользовательÑкие наÑтройки такие как Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль. Ð’Ñ‹ должны дать каждому профилю отдельное Ð¸Ð¼Ñ <br><br> ЕÑли у Ð²Ð°Ñ Ð½ÐµÑколько различных учётных запиÑей SIP, вы можете Ñоздать неÑколько профилей. При запуÑке Twinkle покажет вам ÑпиÑок профилей и вы Ñможете выбрать какой иÑпользовать при Ñтом запуÑке. <br><br> Чтобы легко различать Ñвои профили вы можете иÑпользовать ваше SIP Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ, как название профилÑ, например,<b>example@example.com</b> Cannot find .twinkle directory in your home directory. Ðе могу найти каталог .twinkle в вашем домашнем каталоге. Profile already exists. Профиль уже ÑущеÑтвует. Rename profile '%1' to: Переименовываю профиль '%1' в: HistoryForm Twinkle - Call History Twinkle - ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ¾Ð² Time Ð’Ñ€ÐµÐ¼Ñ In/Out ВходÑщий/иÑходÑщий From/To Откуда/Куда Subject Тема Status Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Call details Детали звонка Details of the selected call record. Детали выбранной запиÑи звонка. View Показать &Incoming calls &ВходÑщие звонки Alt+I Check this option to show incoming calls. Выберите Ñту опцию Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° входÑщих звонков. &Outgoing calls &ИÑходÑщие звонки Alt+O Check this option to show outgoing calls. Выберите Ñту опцию Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° иÑходÑщих звонков. &Answered calls &Отвеченные звонки Alt+A Check this option to show answered calls. Выберите Ñту опцию Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° отвеченных звонков. &Missed calls &Пропущенные звонки Alt+M Check this option to show missed calls. Выберите Ñту опцию Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° пропущенных звонков. Current &user profiles only Только профиль данного &Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Alt+U Check this option to show only calls associated with this user profile. Выберите Ñту опцию Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° звонков аÑÑоциированных Ñ Ñтим профилем пользователÑ. C&lear О&чиÑтить Alt+L <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> <p>ОчиÑтить вÑÑŽ иÑторию звонков.</p> <p><b>Заметка:</b> очищает <b>вÑе</b> запиÑи, запиÑи удалÑÑŽÑ‚ÑÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ñ€Ð°Ñ‚Ð½Ð¾, и вы никогда не увидите их в любых вариантах проÑмотра.</p> Clo&se &Закрыть Alt+S Close this window. Закрыть Ñто окно. &Call &Звонить Alt+C Call selected address. Звонить на выбранный адреÑ. Call... Звонить... Delete Удалить Call start: Звонок начат: Call answer: Звонок отвечен: Call end: Звонок закончен: Call duration: ПродолжительноÑть звонка: Direction: Ðаправление: From: Откуда: To: Куда: Reply to: Ответить на: Referred by: СÑылатьÑÑ Ð½Ð°: Subject: Тема: Released by: ИÑточник: Status: СтатуÑ: Far end device: Конечное уÑтройÑтво: User profile: Профиль пользователÑ: conversation разговор Re: Ответ: Number of calls: ### Total call duration: InviteForm Twinkle - Call Twinkle - Звонить &To: &Кому: Optionally you can provide a subject here. This might be shown to the callee. Опционально вы можете ввеÑти Ñюда тему. Возможно она будет показана удалённой Ñтороне при звонке. Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. ÐÐ´Ñ€ÐµÑ ÐºÑƒÐ´Ð° вы хотите позвонить. Это может быть полный SIP адреÑ, такой как <b>sip:example@example.com</b>, или проÑто чаÑть имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ телефонный номер. ЕÑли вы не указываете полного адреÑа, Twinkle дополнит Ñтот Ð°Ð´Ñ€ÐµÑ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ домена из вашего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ. The user that will make the call. Пользователь от которого вы будете производить звонок. &Subject: &Тема: &From: &Откуда: &Hide identity &Звонить анонимно Alt+H <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> <p> С Ñтой опцией вы запрашиваете у Ñвоего провайдера SIP уÑлуг убрать ваши идентификационные данные из данных направлÑемых к удалённой Ñтороне. Эта Ð¾Ð¿Ñ†Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ прÑчет ваши идентификационные данные такие как: ваш SIP адреÑ, телефонный номер, Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ. Она <b>не</b> Ñкрывает ваш IP адреÑ. </p> <p> <b>Внимание:</b> не вÑе провайдеры поддерживают анонимные звонки. </p> &OK &Звонить &Cancel &Отмена Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. Ðе вÑе SIP провайдеры поддерживают анонимные звонки. Уточните у Ñвоего провайдера дейÑтвительно ли он поддерживает Ñто. F10 LogViewForm Twinkle - Log Twinkle - Журнал Contents of the current log file (~/.twinkle/twinkle.log) Содержимое текущего журнала (~/.twinkle/twinkle.log) &Close &Закрыть Alt+C C&lear О&чиÑтить Alt+L Clear the log window. This does <b>not</b> clear the log file itself. ОчиÑтить окно журнала. Это <b>не </b> Ñтирает файл журнала и не очищает его. MessageForm Twinkle - Instant message Twinkle - Мгновенное Ñообщение &To: &Кому: The user that will send the message. Пользователь от которого вы будете поÑылать ÑообщениÑ. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¼Ñƒ вы поÑылаете Ñообщение. Это может быть полный SIP адреÑ, такой как <b>sip:example@example.com</b>, или проÑто чаÑть имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ телефонный номер. ЕÑли вы не указываете полного адреÑа, Twinkle дополнит Ñтот Ð°Ð´Ñ€ÐµÑ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ домена из вашего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ. Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. &User profile: &Профиль пользователÑ: Conversation Общение The exchanged messages. СообщениÑ, которыми вы обменÑлиÑÑŒ. Type your message here and then press "send" to send it. Введите ваше Ñообщение и нажмите "Отправить" Ð´Ð»Ñ ÐµÐ³Ð¾ отÑылки. &Send &Отправить Alt+S Send the message. Отправить Ñообщение. Delivery failure Ошибка доÑтавки Delivery notification Сообщение доÑтавки Instant message toolbar Панель мгновенных Ñообщений Send file... Отправить файл... Send file Отправить файл image size is scaled down in preview размер картинки уменьшен Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Open with %1... Открыть в %1... Open with... Открыть в... Save attachment as... Сохранить вложение как... File already exists. Do you want to overwrite this file? Файл уже ÑущеÑтвует. ПерезапиÑать данный файл? Failed to save attachment. Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ. %1 is typing a message. %1 пишет Ñообщение. F10 Size MessageFormView sending message отправка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ MphoneForm Twinkle Buddy list СпиÑок друзей You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. Ð’Ñ‹ можете Ñоздать раздельные лиÑты друзей Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ профилÑ. Ð’Ñ‹ можете только видеть доÑтупноÑть друзей и публиковать вашу личную доÑтупноÑть еÑли провайдер поддерживает функцию доÑтупноÑти на Ñервере. &Call: Label in front of combobox to enter address &Позвонить: The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. ÐÐ´Ñ€ÐµÑ ÐºÑƒÐ´Ð° вы хотите позвонить. Это может быть полный SIP адреÑ, такой как <b>sip:example@example.com</b>, или проÑто чаÑть имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ телефонный номер. ЕÑли вы не указываете полного адреÑа, Twinkle дополнит Ñтот Ð°Ð´Ñ€ÐµÑ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ домена из вашего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ. Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. Dial Ðабрать Dial the address. Ðабрать адреÑ. &User: &Пользователь: The user that will make the call. Пользователь от которого вы будете производить звонок. Auto answer indication. Индикатор автоответа. Call redirect indication. Индикатор Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ¾Ð². Do not disturb indication. Индикатор "Ðе тревожить". Message waiting indication. Индикатор Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ ÑообщениÑ. Missed call indication. Индикатор пропущенных звонков. Registration status. Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ€ÐµÐ³Ð¸Ñтрации. Display Монитор Line status Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð»Ð¸Ð½Ð¸Ð¹ Line &1: Ð›Ð¸Ð½Ð¸Ñ &1: Alt+1 Click to switch to line 1. Ðажмите Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº линии 1. From: Откуда: To: Куда: Subject: Тема: Visual indication of line state. ÐаглÑдное отображение ÑоÑтоÑÐ½Ð¸Ñ Ð»Ð¸Ð½Ð¸Ð¸. idle No need to translate проÑтой Call is on hold Звонок на удержании Voice is muted Микрофон заглушен Conference call Конференц ÑвÑзь Transferring call Передача звонка <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> sas No need to translate Short authentication string ÐšÐ¾Ñ€Ð¾Ñ‚ÐºÐ°Ñ Ñтрока авторизации g711a/g711a No need to translate Audio codec Ðудио кодек 0:00:00 Call duration ПродолжительноÑть звонка sip:from No need to translate sip:to No need to translate subject No need to translate photo No need to translate Line &2: Ð›Ð¸Ð½Ð¸Ñ &2: Alt+2 Click to switch to line 2. Ðажмите Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº линии 2. &File &Файл &Edit &Редактировать C&all З&вонить Activate line Ðктивировать линию &Message &Чат &Registration &РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ &Services &СервиÑÑ‹ &View &Показать &Help &Справка Call Toolbar Панель звонков Quit Выход &Quit &Выход Ctrl+Q About Twinkle О программе Twinkle &About Twinkle &О программе Twinkle Call toolbar text Звон &Call... call menu text &Звонить... Call someone Позвонить кому либо F5 Answer toolbar text Ответ &Answer menu text &Ответить Answer incoming call Ответить входÑщий звонок F6 Bye toolbar text Заверш &Bye menu text &Завершить Release call Завершить звонок Esc Reject toolbar text Отклон &Reject menu text &Отклонить Reject incoming call Отклонить входÑщий звонок F8 Hold toolbar text Удерж &Hold menu text &Удержать Put a call on hold, or retrieve a held call ПоÑтавить звонок на удержание, или ответить второй вызов Redirect toolbar text Ðаправ R&edirect... menu text П&еренаправить... Redirect incoming call without answering Перенаправить входÑщий звонок без ответа Dtmf toolbar text &Dtmf... menu text Open keypad to enter digits for voice menu's Открывает панель цифровых клавиш Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² голоÑовых меню Register РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ &Register &РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Deregister РазрегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ &Deregister &РазрегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Deregister this device РазрегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñтого уÑтройÑтва Show registrations Показать региÑтрации &Show registrations &Показать региÑтрации Terminal capabilities ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÑ€Ð¼Ð¸Ð½Ð°Ð»Ð° &Terminal capabilities... menu text &ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÑ€Ð¼Ð¸Ð½Ð°Ð»Ð°... Request terminal capabilities from someone Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¾Ñ€Ð³Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ð¹ терминала от кого-либо Do not disturb Ðе беÑпокоить &Do not disturb &Ðе беÑпокоить Call redirection Перенаправление звонка Call &redirection... &Перенаправление звонка... Redial toolbar text Повт &Redial menu text &Повторить Repeat last call Повторить поÑледний звонок F12 About Qt О Qt About &Qt О &Qt User profile Профиль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ &User profile... &Профиль пользователÑ... Conf toolbar text Конф &Conference menu text &ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ Join two calls in a 3-way conference Объединить два звонка в единую 3-Ñ… Ñтроннюю конференцию Mute toolbar text Вык.Зв &Mute menu text &Выключить звук Mute a call Отключить микрофон Xfer toolbar text Перекл Trans&fer... menu text Пере&ключить... Transfer call Переключить звонок на другого абонента System settings СиÑтемные наÑтройки &System settings... &СиÑтемные наÑтройки... Deregister all РазрегиÑтрировать вÑех Deregister &all РазрегиÑтрировать &вÑех Deregister all your registered devices РазрегиÑтрировать вÑе ваши зарегиÑтрированные уÑтройÑтва Auto answer Ðвтоответ &Auto answer &Ðвтоответ Log Журнал &Log... &Журнал... Call history ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ¾Ð² Call &history... &ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð²Ð¾Ð½ÐºÐ¾Ð²... F9 Change user ... Сменить Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ... &Change user ... &Сменить Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ... Activate or de-activate users Ðктивировать или деактивировать пользователей What's This? Что Ñто? What's &This? Что &Ñто? Shift+F1 Line 1 Ð›Ð¸Ð½Ð¸Ñ 1 Line 2 Ð›Ð¸Ð½Ð¸Ñ 2 &Display &Монитор Voice mail ГолоÑÐ¾Ð²Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° &Voice mail &ГолоÑÐ¾Ð²Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° Access voice mail ДоÑтуп к голоÑовой почте F11 Msg Чат Instant &message... Мгновенное &Ñообщение... Instant message Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ &Buddy list СпиÑок &друзей &Call... &Звонить... &Edit... &Редактировать... &Delete &Удалить O&ffline &Ðе в Ñети &Online &Ð’ Ñети &Change availability &Изменить доÑтупноÑть &Add buddy... &Добавить друзей... idle проÑтой dialing набор номера attempting call, please wait производитÑÑ Ð·Ð²Ð¾Ð½Ð¾Ðº, пожалуйÑта ждите incoming call входÑщий звонок establishing call, please wait уÑтановка ÑоединениÑ, пожалуйÑта ожидайте established уÑтановлено established (waiting for media) уÑтановлено (ожидание медиапотока) releasing call, please wait завершение ÑоединениÑ, пожалуйÑта ожидайте unknown state неизвеÑтное ÑоÑтоÑние Voice is encrypted Звук зашифрован Click to confirm SAS. Ðажмите Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ SAS. Click to clear SAS verification. Ðажмите Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки проверки SAS. Transfer consultation Передача Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð¾Ð¼ User: Пользователь: Call: Звонок: Hide identity Звонить анонимно Registration status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ€ÐµÐ³Ð¸Ñтрации: Registered ЗарегеÑтрирован Failed Oшибка Not registered Ðе зарегиÑтрирован Click to show registrations. Ðажмите Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° региÑтрации. No users are registered. Ðет зарегиÑтрированных пользователей. %1 new, 1 old message %1 новое, 1 Ñтарое Ñообщение %1 new, %2 old messages %1 новое, %2 Ñтарых Ñообщений 1 new message 1 новое Ñообщение %1 new messages %1 новых Ñообщений 1 old message 1 Ñтарое Ñообщение %1 old messages %1 Ñтарых Ñообщений Messages waiting Ожидание Ñообщений No messages Ðет Ñообщений <b>Voice mail status:</b> <b>Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð³Ð¾Ð»Ð¾Ñовой почты:</b> Failure Ошибка Unknown ÐеизвеÑтно Click to access voice mail. Ðажмите Ð´Ð»Ñ Ð´Ð¾Ñтупа к голоÑовой почте. Do not disturb active for: Ðе беÑпокоить активно длÑ: Redirection active for: Перенаправление ативно длÑ: Auto answer active for: Ðвтоответ активен длÑ: Click to activate/deactivate Ðажмите Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸/деактивации Click to activate Ðажмите Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ Do not disturb is not active. Ðе беÑпокоить не активно. Redirection is not active. Перенаправление не ативно. Auto answer is not active. Ðвтоответ не активен. Click to see call history for details. Ðажмите Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра подробноÑтей иÑтории звонков. You have no missed calls. У Ð²Ð°Ñ Ð½ÐµÑ‚ пропущенных звонков. You missed 1 call. У Ð²Ð°Ñ ÐµÑть 1 пропущенный звонок. You missed %1 calls. У Ð²Ð°Ñ %1 пропущенных звонков. Starting user profiles... ЗапуÑк Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ... The following profiles are both for user %1 You can only run multiple profiles for different users. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. Ð’Ñ‹ изменили SIP UDP порт. Эта наÑтройка применитÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ поÑле перезапуÑка Twinkle. not provisioned You must provision your voice mail address in your user profile, before you can access it. Ð’Ñ‹ должны предоÑтавить Ð°Ð´Ñ€ÐµÑ Ð³Ð¾Ð»Ð¾Ñовой почты в вашем профиле перед доÑтупом к ней. The line is busy. Cannot access voice mail. Ð›Ð¸Ð½Ð¸Ñ Ð·Ð°Ð½Ñта. Ðе могу получить доÑтуп к голоÑовой почте. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Ð°Ð´Ñ€ÐµÑ Ð³Ð¾Ð»Ð¾Ñовой почты %1 не ÑвлÑетÑÑ Ð²ÐµÑ€Ð½Ñ‹Ð¼. ПожалуйÑта предоÑтавьте правильный Ð°Ð´Ñ€ÐµÑ Ð² вашем профиле пользователÑ. Failed to save buddy list: %1 Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑпиÑка друзей: %1 F10 Diamondcard Manual &Manual Sign up &Sign up... Recharge... Balance history... Call history... Admin center... Recharge Balance history Admin center NumberConversionForm Twinkle - Number conversion Twinkle - Преобразователь номеров &Match expression: &Совпадение: &Replace: &Замена: Perl style format string for the replacement number. Perl Ñтиль формата Ñтроки Ð´Ð»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ‹ номера. Perl style regular expression matching the number format you want to modify. Perl Ñтиль регулÑрного Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÑÐ¾Ð²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° номера который вы хотите изменить. &OK Alt+O &Cancel &Отмена Alt+C Match expression may not be empty. Совпадающее выражение не может быть пуÑтым. Replace value may not be empty. ЗаменÑющее значение не может быть пуÑтым. Invalid regular expression. Ðеправильное регулÑрное выражение. RedirectForm Twinkle - Redirect Twinkle - Перенаправление Redirect incoming call to Перенаправление входÑщего звонка к You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Ð’Ñ‹ можете определить до 3 направлений куда будут перенаправлÑÑ‚ÑÑ Ð·Ð²Ð¾Ð½ÐºÐ¸. ЕÑли первое направление не отвечает на вызов, то звонок перейдёт на второе направление и так далее. &3rd choice destination: &3-й выбор направлениÑ: &2nd choice destination: &2-й выбор направлениÑ: &1st choice destination: &1-й выбор направлениÑ: Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. &OK &ПринÑть &Cancel &Отмена F10 F12 F11 SelectNicForm Twinkle - Select NIC Twinkle - Выбор Ñетевого интерфейÑа Select the network interface/IP address that you want to use: Выберите Ñетевой интеерфйÑ/IP адреÑÑ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¹ вы будете иÑпользовать: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. Ð’ вашей ÑиÑтеме неÑколько IP адреÑов. ЗдеÑÑŒ вы должны выбрать какой из IP адреÑов нужно иÑпользовать. Этот IP Ð°Ð´Ñ€ÐµÑ Ð±ÑƒÐ´ÐµÑ‚ иÑпользоватьÑÑ Ð²Ð½Ðµ SIP Ñообщений (заголовки ip пакетов). Set as default &IP УÑтановить как &IP по умолчанию Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Сделать выбранный IP Ð°Ð´Ñ€ÐµÑ Ð°Ð´Ñ€ÐµÑом по умолчанию. Ð’ Ñледующий раз когда Twinkle будет запуÑкатÑÑ, Ñтот IP Ð°Ð´Ñ€ÐµÑ Ð±ÑƒÐ´ÐµÑ‚ выбран автоматичеÑки. Set as default &NIC Выбрать как Ñетевую карту по &умолчанию Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. Сделать выбранный Ñетевой Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñом по умолчанию. Ð’ Ñледующий раз когда Twinkle будет запуÑкатÑÑ, Ñтот Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð±ÑƒÐ´ÐµÑ‚ выбран автоматичеÑки. &OK &ПринÑть Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. ЕÑли вы захотите удалить или изменить профиль по умолчанию позже, то вы можете Ñделать Ñто через ÑиÑтемные наÑтройки. SelectProfileForm Twinkle - Select user profile Twinkle - Выбор пользовательÑкого Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Select user profile(s) to run: Выберите пользовательÑкий профиль(ли) Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка: User profile Профиль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Tick the check boxes of the user profiles that you want to run and press run. ПоÑтавьте отметки на профилÑÑ… которые вы хотите запуÑтить и нажмите запуÑк. &New &Ðовый Create a new profile with the profile editor. Создание нового Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ редактора профилей. &Wizard &МаÑтер Alt+W Create a new profile with the wizard. Создание нового Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ маÑтера профилей. &Edit &Изменить Alt+E Edit the highlighted profile. Редактировать выделенный профиль. &Delete &Удалить Alt+D Delete the highlighted profile. Удалить выделенный профиль. Ren&ame Пер&еименовать Alt+A Rename the highlighted profile. Переименовать выделенный профиль. &Set as default &УÑÑ‚. по умолчанию Alt+S Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. Сделать выбранный профиль как профиль по умолчанию. При Ñледующих запуÑках Twinkle, Ñтот профиль будет автоматичеÑки запущен. &Run &ЗапуÑк Alt+R Run Twinkle with the selected profiles. ЗапуÑтить Twinkle Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ñ‹Ð¼ профилем. S&ystem settings С&иÑтемные наÑтройки Alt+Y Edit the system settings. Редактировать ÑиÑтемные наÑтройки. &Cancel &Отмена Alt+C <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> <html>Перед тем как иÑпользовать Twinkle, вы должны Ñоздать пользовательÑкий профиль.<br>Ðажмите OK Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ.</html> <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>Choose what method you wish to use.</html> <html>Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð²Ñ‹ можете иÑпользовать редактор профилей. Ð’ редакторе профилей вы можете гибко изменить наÑтройки Ð´Ð»Ñ SIP протокола, RTP и множеÑтво других тонких наÑтроек.<br><br>Как альтернативу вы можете иÑпользовать маÑтер Ð´Ð»Ñ Ð±Ñ‹Ñтрой наÑтройки. МаÑтер ÑпроÑит у Ð²Ð°Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñамые необходимые наÑтройки. ЕÑли вы Ñоздаёте профиль маÑтером, то позже Ñможете редактировать его редактором профилей.<br><br>Выберите метод который вы будете иÑпользовать.</html> &Profile editor &Редактор профилей <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> <html>Далее вы можете определить ÑиÑтемные наÑтройки. Ð’Ñ‹ можете изменить Ñти наÑтройки позже.<br><br>Ðажмите OK Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра и наÑтройки ÑиÑтемных наÑтроек.</html> You did not select any user profile to run. Please select a profile. Ð’Ñ‹ не выбрали ни одного Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка. ПожалуйÑта выберите профиль. Are you sure you want to delete profile '%1'? Ð’Ñ‹ уверены что хотите удалить профиль '%1'? Delete profile Удалить профиль Failed to delete profile. Ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ. Failed to rename profile. Ошибка Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> <p>ЕÑли вы захотите удалить или изменить профиль по умолчанию позже, то вы можете Ñделать Ñто через ÑиÑтемные наÑтройки.</p> Cannot find .twinkle directory in your home directory. Ðе могу найти .twinkle папку в вашей домашней директории. Create profile Ed&itor Alt+I Dia&mondcard Alt+M Modify profile Startup profile &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> SelectUserForm Twinkle - Select user Twinkle - Выбор Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ &Cancel &Отмена Alt+C &Select all &Выбрать вÑе Alt+S &OK &ПринÑть Alt+O C&lear all О&чиÑтить вÑе Alt+L purpose No need to translate User Пользователь Register РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Select users that you want to register. Выберите пользователей которых надо зарегиÑтрировать. Deregister РазрегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Select users that you want to deregister. Выберите пользователей которых надо разрегиÑтрировать. Deregister all devices разрегиÑтрировать вÑе уÑтройÑтва Select users for which you want to deregister all devices. Выберите пользователей Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… вы хотите "разрегиÑтрировать вÑе уÑтройÑтва". Do not disturb Ðе беÑпокоить Select users for which you want to enable 'do not disturb'. Выберите пользователей Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… вы хотите включить "не беÑпокоить". Auto answer Ðвтоответ Select users for which you want to enable 'auto answer'. Выберите пользователей Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… вы хотите включить "автоответ". SendFileForm Twinkle - Send File Twinkle - Отправить файл Select file to send. Выберите файл Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸. &File: &Файл: &Subject: &Тема: &OK &Отправить Alt+O &Cancel &Отмена Alt+C File does not exist. Файл не ÑущеÑтвует. Send file... Отправить файл... SrvRedirectForm Twinkle - Call Redirection Twinkle - Перенаправление звонков User: Пользователь: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> &Unconditional &БезуÑÐ»Ð¾Ð²Ð½Ð°Ñ &Redirect all calls &Перенаправление вÑех звонков Alt+R Activate the unconditional redirection service. Ðктивировать ÑÐµÑ€Ð²Ð¸Ñ Ð±ÐµÐ·ÑƒÑловой переадреÑации. Redirect to Перенаправить к You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Ð’Ñ‹ можете определить до 3 направлений куда будут перенаправлÑÑ‚ÑÑ Ð·Ð²Ð¾Ð½ÐºÐ¸. ЕÑли первое направление не отвечает на вызов, то звонок перейдёт на второе направление и так далее. &3rd choice destination: &3-й выбор направлениÑ: &2nd choice destination: &2-й выбор направлениÑ: &1st choice destination: &1-й выбор направлениÑ: Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. &Busy &ЗанÑтоÑть &Redirect calls when I am busy &ПеренаправлÑть звонки когда Ñ Ð·Ð°Ð½ÑÑ‚ Activate the redirection when busy service. Ðктивировать перенаправление когда Ñ Ð·Ð°Ð½ÑÑ‚. &No answer &Ðет ответа &Redirect calls when I do not answer &ПеренаправлÑть звонки когда Ñ Ð½Ðµ отвечаю Activate the redirection on no answer service. Ðктивировать перенаправление когда Ñ Ð½Ðµ отвечаю. &OK &ПринÑть Alt+O Accept and save all changes. ПринÑть и Ñохранить изменениÑ. &Cancel &Отмена Alt+C Undo your changes and close the window. Отменить вÑе Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ Ð¸ закрыть окно. You have entered an invalid destination. Ð’Ñ‹ ввели не верное направление F10 F11 F12 SysSettingsForm Twinkle - System Settings Twinkle - СиÑтемные наÑтройки General ОÑновные Audio Ðудио Ring tones Сигналы Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Network Сеть Log Журнал Select a category for which you want to see or modify the settings. Выберите категорию Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра и модификации наÑтроек. &OK &ПринÑть Alt+O Accept and save your changes. ПринÑть и Ñохранить изменениÑ. &Cancel &Отмена Alt+C Undo all your changes and close the window. Отменить вÑе Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ Ð¸ закрыть окно. Sound Card Ð—Ð²ÑƒÐºÐ¾Ð²Ð°Ñ ÐšÐ°Ñ€Ñ‚Ð° Select the sound card for playing the ring tone for incoming calls. Выберите звуковую карту Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð¸Ð³Ñ€Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñигнала вызова Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñщих звонков. Select the sound card to which your microphone is connected. Выберите звуковую карту к которой подключен ваш микрофон. Select the sound card for the speaker function during a call. Выберите звуковую карту к которой подключены ваши колонки или наушники. &Speaker: &Колонки: &Ring tone: &Сигнал вызова: Other device: Другое уÑтройÑтво: &Microphone: &Микрофон: &Validate devices before usage &ПроверÑть уÑтройÑтва перед иÑпользованием Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. Reduce &noise from the microphone ПодавлÑть &Ñхо от микрофона Advanced Дополнительно OSS &fragment size: OSS &размер фрагмента: 16 32 64 128 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. ALSA &play period size: ALSA размер периода &проигрываниÑ: &ALSA capture period size: ALSA размер периода &запиÑи: The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. &Max log size: &МакÑимальный размер журнала: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. МакÑимальный размер файла журнала в МБ. Когда журнал доÑтигает Ñтого размера, ÑоздаётÑÑ Ð°Ñ€Ñ…Ð¸Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð¸ текущий журнал удалÑетÑÑ. ОÑтаётÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð°Ñ€Ñ…Ð¸Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ. MB МБ Log &debug reports ЗапиÑывать &отладочные отчёты Alt+D Indicates if reports marked as "debug" will be logged. Указывает будут ли запиÑыватьÑÑ Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ñ‹Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² журнал. Log &SIP reports ЗапиÑывать &SIP отчёты Alt+S Indicates if SIP messages will be logged. Указывает будут ли запиÑыватьÑÑ SIP ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² журнал. Log S&TUN reports ЗапиÑывать S&TUN отчёты Alt+T Indicates if STUN messages will be logged. Указывает будут ли запиÑыватьÑÑ STUN ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² журнал. Log m&emory reports ЗапиÑывать отчёты п&амÑти Alt+E Indicates if reports concerning memory management will be logged. Указывает будут ли запиÑыватьÑÑ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ°ÑаÑющиеÑÑ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼Ñтью в журнал. System tray СиÑтемный лоток Create &system tray icon on startup Создавать значок в &ÑиÑтемном лотке при запуÑке Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. Включите Ñту опцию еÑли вы хотите видеть значок Twinkle в ÑиÑтемном лотке. Значок в ÑиÑтемном лотке ÑоздаётÑÑ Ð¿Ñ€Ð¸ Ñтарте Twinkle. &Hide in system tray when closing main window &ПрÑтать в ÑиÑтемном лотке при закрытии главного окна Alt+H Enable this option if you want Twinkle to hide in the system tray when you close the main window. Включите Ñту опцию еÑли вы хотите чтобы Twinkle прÑталÑÑ Ð² ÑиÑтемном лотке когда вы закрываете оÑновное окно. Startup ЗапуÑк S&tartup hidden in system tray При &запуÑке ÑвернутьÑÑ Ð² ÑиÑтемный лоток Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. При Ñледующих запуÑках Twinkle будет поÑтоÑнно прÑтатьÑÑ Ð² ÑиÑтемном лотке. Это удобно когда вы выбрали профиль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð¾ умолчанию. Default user profiles Стандартный профиль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. ЕÑли вы вÑегда иÑпользуете одинаковый профиль(лÑ), тогда вы можете отметить Ñтот профиль(лÑ) как профиль по умолчанию. При Ñледующем запуÑке Twinkle он не будет Ñпрашивать выбор Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка. Профиль по умолчанию загружаетÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки. Services СевиÑÑ‹ Call &waiting &Ожидание звонка Alt+W With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. При ожидании звонка еÑли одна из линий занÑта то входÑщий звонок будет разрешён. ЕÑли вы запретите ожидание звонка то еÑли одна из линий занÑта входÑщие звонки будут отклонены. Hang up &both lines when ending a 3-way conference call. Прерывать &обе линии при завершении 3-Ñ… Ñторонней конференции. Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. Прерывать обе линии при завершении 3-Ñ… Ñторонней конференции. ЕÑли Ñта Ð¾Ð¿Ñ†Ð¸Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°, только Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ прервана и вы Ñможете продолжить разговор Ñ ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð¾Ð¹ Ñтороной на другой линии. &Maximum calls in call history: &МакÑимальное количеÑтво звонков в иÑтории: The maximum number of calls that will be kept in the call history. МакÑимальное количеÑтво звонков которые будут ÑохранÑÑ‚ÑÑ Ð² иÑтории звонков. &Auto show main window on incoming call after &ÐвтоматичеÑки показывать главное окно при входÑщем звонке поÑле Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Когда главное окно Ñкрыто, оно будет автоматичеÑки показано при входÑщем звонке поÑле поÑле указанного количеÑтва Ñекунд. Number of seconds after which the main window should be shown. ЧиÑло Ñекунд поÑле которого главное окно будет показано. secs Ñекунд Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. МакÑимально разрешённый размер (0-65535) в байтах входÑщего SIP ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· UDP. &SIP port: &SIP порт: &RTP port: &RTP порт: Max. SIP message size (&TCP): МакÑ. размер SIP ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (&TCP): The UDP/TCP port used for sending and receiving SIP messages. UDP/TCP порт иÑпользуемый Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ и Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ SIP Ñообщений. Max. SIP message size (&UDP): МакÑ. размер SIP ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. МакÑимально разрешённый размер (0-4294967295) в байтах Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñщего SIP ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð²ÐµÑ€Ñ… TCP. The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. UDP порт иÑпользуемый Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ и приёма RTP Ð´Ð»Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ линии. UDP порт Ð´Ð»Ñ Ð²Ñ‚Ð¾Ñ€Ð¾Ð¹ линии на 2 больше. ЕÑли Ð´Ð»Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ линии иÑпользуетÑÑ Ð¿Ð¾Ñ€Ñ‚ 8000, значит Ð²Ñ‚Ð¾Ñ€Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð¸Ñпользует порт 8002. Когда вы иÑпользуете передачу звонка иÑпользуетÑÑ Ñледующий Ñвободный порт (8004). Ring tone Звонок &Play ring tone on incoming call &Играть звонок при входÑщем вызове Alt+P Indicates if a ring tone should be played when a call comes in. Указывает будет ли проигрыватьÑÑ Ð²Ñ‹Ð·Ñ‹Ð²Ð½Ð¾Ð¹ Ñигнал при входÑщем вызове. &Default ring tone &Стандартный звонок Play the default ring tone when a call comes in. Проигрывать вызывной Ñигнал по умолчанию при входÑщем звонке. C&ustom ring tone С&вой звонок Alt+U Play a custom ring tone when a call comes in. Проигрывать Ñвой Ñигнал по умолчанию при входÑщем звонке. Specify the file name of a .wav file that you want to be played as ring tone. Определите Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° из *.wav файлов, который будет проигрыватьÑÑ ÐºÐ°Ðº вызывной Ñигнал. Select ring tone file. Выберите файл вызывного Ñигнала. Ring back tone Гудок вызова P&lay ring back tone when network does not play ring back tone И&грать гудок когда Ñеть не играет вызывного Ñигнала Alt+L <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> D&efault ring back tone С&тандартный гудок вызова Play the default ring back tone. Играть Ñтандартный гудок при иÑходÑщем вызове. Cu&stom ring back tone С&вой гудок вызова Play a custom ring back tone. Играть Ñвой гудок вызова. Specify the file name of a .wav file that you want to be played as ring back tone. Определите файл из .wav файлов, который будет проигрыватьÑÑ ÐºÐ°Ðº гудок вызова Select ring back tone file. Выберите файл гудка вызова. &Lookup name for incoming call &ИÑкать Ð¸Ð¼Ñ Ð¿Ñ€Ð¸ входÑщем звонке On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. При входÑщем звонке, Twinkle будет пытатьÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ Ð¸Ð¼Ñ Ð² вашей адреÑной книге которое ÑоответÑтвует входÑщему SIP адреÑу. Это Ð¸Ð¼Ñ Ð±ÑƒÐ´ÐµÑ‚ отображено. Ove&rride received display name За&менÑть полученное Ð¸Ð¼Ñ Ð°Ð±Ð¾Ð½ÐµÐ½Ñ‚Ð° Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. ЗвонÑщий может предоÑтавить отображаемое имÑ. Отметьте Ñту опцию еÑли вы хотите заменить его данные данными из вашей адреÑной книги. Lookup &photo for incoming call ИÑкать &фотографию при входÑщем звонке Lookup the photo of a caller in your address book and display it on an incoming call. ИÑкать фото звонÑщего в вашей адреÑной книге и отобразить его при входÑщем звонке. none This is the 'none' in default IP address combo нету none This is the 'none' in default network interface combo нету Ring tones Description of .wav files in file dialog Вызывные Ñигналы Choose ring tone Выберите вызывной Ñигнал Ring back tones Description of .wav files in file dialog Гудок вызова Choose ring back tone Выберите гудок вызова W&eb browser command: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. SysTrayPopup Answer Ответить Reject Отклонить Incoming Call TermCapForm Twinkle - Terminal Capabilities Twinkle - ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° &From: &Откуда: Get terminal capabilities of Получить Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° от &To: &Откуда: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. &OK &ПринÑть &Cancel &Отмена F10 TransferForm Twinkle - Transfer Twinkle - Переключение Transfer call to Переключить звонок к &To: &Кому: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. ÐÐ´Ñ€ÐµÑ Ð°Ð±Ð¾Ð½ÐµÐ½Ñ‚Ð° которому вы хотите перевеÑти звонок. Это может быть полный Ð°Ð´Ñ€ÐµÑ Ð²Ð¸Ð´Ð° <b>sip:example@example.com</b> , только пользовательÑÐºÐ°Ñ Ñ‡Ð°Ñть или номер телефона из полного адреÑа. Когда вы не указываете полный адреÑ, Twinkle дополнÑет Ð°Ð´Ñ€ÐµÑ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¸Ð¼Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° из вашего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ. Address book ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Select an address from the address book. Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги. Type of transfer Тип Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ &Blind transfer &Слепой перевод Alt+B Transfer the call to a third party without contacting that third party yourself. Передача звонка другому абоненту без разговора Ñ Ð½Ð¸Ð¼. T&ransfer with consultation П&ередача Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð¾Ð¼ Alt+R Before transferring the call to a third party, first consult the party yourself. Перед передачей звонка другому абоненту вы можете предварительно переговорить Ñ Ð½Ð¸Ð¼. Transfer to other &line Передача на другую &линию Alt+L Connect the remote party on the active line with the remote party on the other line. &OK Alt+O &Cancel &Отмена F10 TwinkleCore Anonymous ÐеизвеÑтный Warning: Внимание: Failed to create log file %1 . Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° журнала: %1 . Cannot open file for reading: %1 Ðе могу открыть файл Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %1 File system error while reading file %1 . Ошибка файловой ÑиÑтемы при чтении файла %1 . Cannot open file for writing: %1 Ðе могу открыть файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи: %1 File system error while writing file %1 . Ошибка файловой ÑиÑтемы при запиÑи файла %1 . Excessive number of socket errors. Большое чиÑло ошибок Ñокета. Built with support for: Собрано Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ и длÑ: Contributions: При учаÑтии: This software contains the following software from 3rd parties: Ð”Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° Ñодержит Ñледующее програмное обеÑпечение от третьих Ñторон: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * GSM кодек от Jutta Degener and Carsten Bormann, University of Berlin * G.711/G.726 codecs from Sun Microsystems (public domain) * G.711/G.726 кодек от Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * iLBC Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾ RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * ЧаÑть из STUN проекта на http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ * ЧаÑть из libsrv на http://libsrv.sourceforge.net/ For RTP the following dynamic libraries are linked: Ð”Ð»Ñ RTP Ñледующие динамичеÑкие библиотеки были ÑвÑзаны: Translated to english by <your name> Перевод на руÑÑкий Ñзык: Ходоренко Михаил chodorenko@mail.ru Directory %1 does not exist. Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ %1 не ÑущеÑтвует. Cannot open file %1 . Ðе могу открыть файл %1 . %1 is not set to your home directory. %1 не уÑтановлена в вашу домашнюю директорию. Directory %1 (%2) does not exist. Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ %1 (%2) не ÑущеÑтвует. Cannot create directory %1 . Ðе могу Ñоздать директорию %1 . Lock file %1 already exist, but cannot be opened. Файл блокировки %1 уже ÑущеÑтвует и не может быть открыт. %1 is already running. Lock file %2 already exists. %1 уже запушен. файл блокировки %2 уже ÑущеÑтвует. Cannot create %1 . Ðе могу Ñоздать %1 . Cannot write to %1 . Ðе могу запиÑать %1 . Syntax error in file %1 . СинтакÑичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° в файле %1 . Failed to backup %1 to %2 Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð¹ копии %1 в %2 unknown name (device is busy) неизвеÑтное Ð¸Ð¼Ñ (уÑтройÑтво занÑто) Default device УÑтройÑтво по умолчанию Cannot access the ring tone device (%1). Ðе могу получить доÑтуп к уÑтройÑтву звукового Ñигнала (%1). Cannot access the speaker (%1). Ðе могу получить доÑтуп к аудиовыходу (%1). Cannot access the microphone (%1). Ðе могу получить доÑтуп к входу микрофона (%1). Cannot receive incoming TCP connections. Ðе могу получить входÑщие TCP ÑоединениÑ. Call transfer - %1 Перевод звонка - %1 Sound card cannot be set to full duplex. Ð—Ð²ÑƒÐºÐ¾Ð²Ð°Ñ ÐºÐ°Ñ€Ñ‚Ð° не может уÑтановить полнодуплекÑный режим. Cannot set buffer size on sound card. Ðе могу уÑтановить размер буфера на звуковой карте. Sound card cannot be set to %1 channels. Cannot set sound card to 16 bits recording. Ðе могу наÑтроить звуковую карту Ð´Ð»Ñ 16 битной запиÑи. Cannot set sound card to 16 bits playing. Ðе могу наÑтроить звуковую карту Ð´Ð»Ñ 16 битного проигрываниÑ. Cannot set sound card sample rate to %1 Opening ALSA driver failed Ошибка Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ ALSA драйвера Cannot open ALSA driver for PCM playback Ðе могу открыть ALSA драйвер Ð´Ð»Ñ Ð²Ð¾ÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ PCM Cannot open ALSA driver for PCM capture Ðе могу открыть ALSA драйвер Ð´Ð»Ñ Ð·Ð°Ñ…Ð²Ð°Ñ‚Ð° PCM Cannot resolve STUN server: %1 Ðе могу определить Ð¸Ð¼Ñ STUN Ñервера: %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. public IP: %1 --> private IP: %2 (SIP signaling) внешний IP: %1 --> внутренний IP: %2 (SIP оповещение) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) внешний IP: %1-%2 --> внутренний IP: %3-%4 (RTP/RTCP) Cannot reach the STUN server: %1 Ðе могу получить доÑтуп к STUN Ñерверу: %1 If you are behind a firewall then you need to open the following UDP ports. ЕÑли вы находитеÑÑŒ за фаерволом вам нужно открыть Ñледующие UDP порты. Port %1 (SIP signaling) Порт %1 (SIP оповещение) Ports %1-%2 (RTP/RTCP) Порта %1-%2 (RTP/RTCP) NAT type discovery via STUN failed. Ошибка Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° NAT через STUN. Failed to create file %1 Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° %1 Failed to write data to file %1 Ошибка запиÑи данных в файл %1 Failed to send message. Ошибка отправки ÑообщениÑ. Cannot lock %1 . UserProfileForm Twinkle - User Profile Twinkle - Профиль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ User profile: Профиль пользователÑ: Select which profile you want to edit. Выберите профиль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ. User Пользователь SIP server SIP Ñервер Voice mail ГолоÑÐ¾Ð²Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° Instant message Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Presence ДоÑтупноÑть RTP audio RTP аудио SIP protocol SIP протокол Transport/NAT ТранÑпорт/NAT Address format Формат адреÑа Timers Таймеры Ring tones Звуковые Ñигналы Scripts Скрипты Security БезопаÑтноÑть Select a category for which you want to see or modify the settings. Выберите категорию Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра и модификации наÑтроек. &OK &ПринÑть Alt+O Accept and save your changes. ПринÑть и Ñохранить изменениÑ. &Cancel &Отмена Alt+C Undo all your changes and close the window. Отменить вÑе Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ Ð¸ закрыть окно. SIP account Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ SIP &User name*: &Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ*: &Domain*: &Домен*: Or&ganization: Ор&ганизациÑ: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. SIP Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñтавленное вашим провайдером. ПользовательÑÐºÐ°Ñ Ñ‡Ð°Ñть вашего SIP адреÑа, <b>username</b>@domain.com может быть вашим телефонным номером. <br><br> Это поле ÑвлÑетÑÑ Ð¾Ð±Ñзательным. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Ð”Ð¾Ð¼ÐµÐ½Ð½Ð°Ñ Ñ‡Ð°Ñть вашего SIP адреÑа , username@<b>domain.com</b>. ВмеÑто реального домена также может быть именем машины или IP адреÑом вашего <b>SIP proxy</b>. ЕÑли вы звоните напрÑмую Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° на компьютер, то заполните именем или IP адреÑом вашей машины <br><br> Это поле ÑвлÑетÑÑ Ð¾Ð±Ñзательным. You may fill in the name of your organization. When you make a call, this might be shown to the called party. Ð’Ñ‹ можете заполнить Ð¸Ð¼Ñ Ð²Ð°ÑˆÐµÐ¹ организации. Когда вы будете оÑущеÑтвлÑть звонок оно может быть показано удалённой Ñтороне. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Это проÑто ваше полное имÑ, например John Doe. Оно иÑпользуетÑÑ Ð² качеÑтве отображаемого имени. Когда Ð’Ñ‹ делаете звонок, Ñто Ð¸Ð¼Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть укаазно в качеÑтве вызывающей Ñтороны. &Your name: &Ваше имÑ: SIP authentication SIP Ð°ÑƒÑ‚ÐµÑ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ &Realm: &ОблаÑть: Authentication &name: Ðутентификационное &имÑ: &Password: &Пароль: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. ОблаÑть аутентификации. Значение должно быть предоÑтавлено вашим SIP провайдером. ЕÑли вы оÑтавите Ñто поле пуÑтым , то Twinkle будет иÑпользовать Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль Ð´Ð»Ñ Ð»ÑŽÐ±Ð¾Ð¹ облаÑти ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ авторизации. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ваше аутентификационное Ð¸Ð¼Ñ Ð´Ð»Ñ SIP. Ð’ большинÑтве Ñлучаем Ñовпадает Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ SIP. Ð’Ñ‹ можете ввеÑти здеÑÑŒ другое Ð¸Ð¼Ñ Ð¿Ñ€Ð¸ необходимоÑти. Your password for authentication. Ваш пароль Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸. Registrar РегиÑтратор &Registrar: &РегиÑтратор: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. Ð˜Ð¼Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°, доменное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ региÑтратора. ЕÑли вы иÑпользуете иÑходÑщий прокÑи Ñовпадающий Ñ Ð²Ð°ÑˆÐ¸Ð¼ региÑтратором, вы можете оÑтавить его пуÑтым. &Expiry: &УÑтаревание: The registration expiry time that Twinkle will request. Ð’Ñ€ÐµÐ¼Ñ ÑƒÑтаревание региÑтрации, поÑле которого Twinkle перепошлёт Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð·Ð°Ð½Ð¾Ð²Ð¾. seconds Ñекунд Re&gister at startup Ре&гиÑтрироватьÑÑ Ð¿Ñ€Ð¸ запуÑке Alt+G Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Указывает должен ли Twinkle автоматичеÑки региÑтрироватьÑÑ ÐºÐ¾Ð³Ð´Ð° запуÑкаетÑÑ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»ÑŒ пользователÑ. ЕÑли отключить Ñту опцию то ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ проиÑходить напрÑмую между IP клиентами без Ð¾Ð±Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ðº SIP прокÑи. Add q-value to registration Добавить q-значение к региÑтрации The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. Q-значение указывает приоритет вашего зарегиÑтриванного уÑтройÑтва. ЕÑли кроме Twinkle вы региÑтрируете Ñту учётную запиÑÑŒ на другом SIP уÑтройÑтве. Сеть может определÑть по Ñтому значению какому уÑтройÑтву перенаправить вызов в первую очередь. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. Q-значение может изменÑÑ‚ÑÑ Ð² пределах между 0.000 и 1.000. Большее значение равно большему приоритету (Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð° 1 > 0.1 > 0.01). Outbound Proxy ИÑходÑщий ПрокÑи &Use outbound proxy &ИÑпользовать иÑходÑщий прокÑи Alt+U Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Outbound &proxy: ИÑходÑщий &прокÑи: &Send in-dialog requests to proxy Alt+S SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. &Don't send a request to proxy if its destination can be resolved locally. &Ðе поÑылать Ð·Ð°Ð¿Ñ€Ð¾Ñ Ðº прокÑи еÑли назначение может быть определено локально. Alt+D When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) ЕÑли вы отметите Ñту опцию Twinkle Ñначала попытаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ SIP Ð°Ð´Ñ€ÐµÑ ÐºÐ°Ðº IP адреÑ. ЕÑли Ñможет, то SIP Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð±ÑƒÐ´ÐµÑ‚ поÑлан напрÑмую. Только еÑли он не Ñможет опреелить адреÑ, Twinkle пошлёт SIP Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° прокÑи (замечание ) The hostname, domain name or IP address of your outbound proxy. Ð˜Ð¼Ñ Ñервера, доменное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ иÑходÑщего прокÑи. Co&decs Ко&деки Codecs Кодеки Available codecs: ДоÑтупные кодеки: G.711 A-law G.711 u-law GSM speex-nb (8 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) List of available codecs. СпиÑок доÑтупных кодеков. Move a codec from the list of available codecs to the list of active codecs. ПеремеÑтите кодек из ÑпиÑка доÑтупных кодеков в ÑпиÑок активных кодеков. Move a codec from the list of active codecs to the list of available codecs. ПеремеÑтите кодек из ÑпиÑка активных кодеков в ÑпиÑок доÑтупных кодеков. Active codecs: Ðктивные кодеки: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. СпиÑок активных кодеков. Эти кодеки будут иÑпользовании при ÑоглаÑовании медиа потоков при уÑтановке ÑоединениÑ. ОчерёдноÑть кодеков Ñто приоритетноÑть их иÑпользованиÑ. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. Перемещение кодеков вверх по ÑпиÑку увеличивает их приоритет при иÑпользовании. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. Перемещение кодеков вниз по ÑпиÑку понижает их приоритет при иÑпользовании. &G.711/G.726 payload size: The preferred payload size for the G.711 and G.726 codecs. Приоритетный payload размер Ð´Ð»Ñ G.711 и G.726 кодеков. ms Ð¼Ñ &Follow codec preference from far end on incoming calls &Следовать наÑтройкам кодеков удалённой Ñтороны при входÑщем звонке Alt+F <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. Follow codec &preference from far end on outgoing calls Следовать &наÑтройкам кодеков удалённой Ñтороны при иÑходÑщем звонке Alt+P <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. &iLBC iLBC i&LBC payload type: i&LBC payload тип: iLBC &payload size (ms): The dynamic type value (96 or higher) to be used for iLBC. 20 30 The preferred payload size for iLBC. Приоритетный payload размер Ð´Ð»Ñ iLBC. &Speex Speex Perceptual &enhancement Alt+E Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). &Ultra wide band payload type: Alt+V &Wide band payload type: Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. The dynamic type value (96 or higher) to be used for speex wide band. Co&mplexity: Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. The dynamic type value (96 or higher) to be used for speex narrow band. With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. &Narrow band payload type: G.726 G.726 &40 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 40 kbps. The dynamic type value (96 or higher) to be used for G.726 32 kbps. G.726 &24 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 24 kbps. G.726 &32 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 16 kbps. G.726 &16 kbps payload type: Codeword &packing order: RFC 3551 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. DT&MF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). DTMF vo&lume: DTMF ур&овень: The power level of the DTMF tone in dB. The pause after a DTMF tone. Пауза поÑле DTMF тона. DTMF &duration: DTMF &длинна: DTMF payload &type: DTMF &pause: DTMF &паузы: dB дБ Duration of a DTMF tone. ПродолжительноÑть поÑылки DTMF тона. DTMF t&ransport: DTMF Ñ‚&ранÑпорт: Auto Ðвто RFC 2833 Inband Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> General ОÑновные Protocol options Опции потокола Call &Hold variant: RFC 2543 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. Allow m&issing Contact header in 200 OK on REGISTER Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. &Max-Forwards header is mandatory Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Put &registration expiry time in contact header Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. &Use compact header names Indicates if compact header names should be used for headers that have a compact form. Allow SDP change during call setup <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> Use domain &name to create a unique contact header value Alt+N <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> &Encode Via, Route, Record-Route as list The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. Redirection &Allow redirection Alt+A Indicates if Twinkle should redirect a request if a 3XX response is received. Ask user &permission to redirect Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Max re&directions: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. SIP extensions disabled supported required preferred Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. &100 rel (PRACK): Replaces Indicates if the Replaces-extenstion is supported. REFER Call transfer (REFER) Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. As&k user permission to transfer Alt+K Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Hold call &with referrer while setting up call to transfer target Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Ho&ld call with referee before sending REFER Alt+L Indicates if Twinkle should put the current call on hold when you transfer a call. Auto re&fresh subscription to refer event while call transfer is not finished While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. Attended refer to AoR (Address of Record) An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. Privacy Privacy options &Send P-Preferred-Identity header when hiding user identity Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. SIP transport UDP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. T&ransport protocol: UDP t&hreshold: Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. NAT traversal &NAT traversal not needed Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. &Use statically configured public IP address inside SIP messages Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Use &STUN (does not work for incoming TCP) Choose this option when your SIP provider offers a STUN server for NAT traversal. S&TUN server: S&TUN Ñервер: The hostname, domain name or IP address of the STUN server. Ð˜Ð¼Ñ Ñервера, доменное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ STUN Ñервера. &Public IP address: The public IP address of your NAT. Telephone numbers Only &display user part of URI for telephone number If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. &URI with numerical user part is a telephone number If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. &Remove special symbols from numerical dial strings Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. &Special symbols: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. Number conversion Match expression Replace <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> Move the selected number conversion rule upwards in the list. Move the selected number conversion rule downwards in the list. &Add &Добавить Add a number conversion rule. Re&move Remove the selected number conversion rule. &Edit Edit the selected number conversion rule. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. &Test Test how a number is converted by the number conversion rules. When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". NAT &keep alive: &No answer: Select ring back tone file. Выберите файл гудка вызова. Select ring tone file. Выберите файл вызывного Ñигнала. Ring &back tone: Гудок &вызова: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> &Ring tone: &Сигнал вызова: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Select script file. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Call released locall&y: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Outgoing call a&nswered: Incoming call &failed: &Incoming call: Call released &remotely: Incoming call &answered: O&utgoing call: Out&going call failed: &Enable ZRTP/SRTP encryption &Включить ZRTP/SRTP шифрование When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. ZRTP settings ZRTP наÑтройки O&nly encrypt audio if remote party indicated ZRTP support in SDP A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. &Indicate ZRTP support in SDP Twinkle will indicate ZRTP support during call setup in its signalling. &Popup warning when remote party disables encryption during call A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. &Voice mail address: &ÐÐ´Ñ€ÐµÑ Ð³Ð¾Ð»Ð¾Ñовой почты: The SIP address or telephone number to access your voice mail. SIP Ð°Ð´Ñ€ÐµÑ Ð¸Ð»Ð¼ телефонный номер Ð´Ð»Ñ Ð´Ð¾Ñтупа к вашей голоÑовой почте. Unsollicited Sollicited <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> &MWI type: Sollicited MWI Subscription &duration: ПродолжительноÑть &подпиÑки: Mailbox &user name: Почтовый &Ñщик: The hostname, domain name or IP address of your voice mailbox server. Ð˜Ð¼Ñ Ñервера, доменное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ Ñервера голоÑовой почты. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Your user name for accessing your voice mailbox. Mailbox &server: Почтовый &Ñервер: Via outbound &proxy Через иÑходÑщий &прокÑи Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. &Maximum number of sessions: &МакÑимальное чиÑло ÑеÑÑий: When you have this number of instant message sessions open, new incoming message sessions will be rejected. Это чиÑло ограничивает количеÑтво открытых ÑеанÑов мгновенных Ñообщений, при превышении Ñтого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ñ‹Ðµ ÑеÑÑии будут отвергнуты. Your presence Ваша доÑтупноÑть &Publish availability at startup &Публиковать доÑтупноÑть при запуÑке Publish your availability at startup. Публикует вашу доÑтупноÑть при запуÑке. Publication &refresh interval (sec): Интервал &Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ (Ñек): Refresh rate of presence publications. ЧаÑтота обновлений публикации доÑтупноÑти. Buddy presence ДоÑтупноÑть друзей &Subscription refresh interval (sec): Интервал Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ &подпиÑки (Ñек): Refresh rate of presence subscriptions. ЧаÑтота обновлений подпиÑки. Dynamic payload type %1 is used more than once. You must fill in a user name for your SIP account. Ð’Ñ‹ должны заполнить Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ учётной запиÑи SIP. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. ВЫ должны заполнить доменное Ð¸Ð¼Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ учётной запиÑи SIP. Ñто может быть Ð¸Ð¼Ñ Ñервера или IP Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ компьютера при прÑмых звонках. Invalid domain. Ðе правильный домен. Invalid user name. Ðеправильное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ. Invalid value for registrar. Ðеправильное значение Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтратора. Invalid value for outbound proxy. Ðеправильное значение Ð´Ð»Ñ Ð¸ÑходÑщего прокÑи. You must fill in a mailbox user name. You must fill in a mailbox server Invalid mailbox server. Invalid mailbox user name. Value for public IP address missing. Значение Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ IP адреÑа отÑутÑтвует. Invalid value for STUN server. Ðеправильное значение Ð´Ð»Ñ STUN Ñервера. Ring tones Description of .wav files in file dialog Вызывные Ñигналы Choose ring tone Выберите вызывной Ñигнал Ring back tones Description of .wav files in file dialog Гудок вызова All files Ð’Ñе файлы Choose incoming call script Выберите Ñкрипт входÑщего звонка Choose incoming call answered script Выберите Ñкрипт входÑщего отвеченого звонка Choose incoming call failed script Выберите Ñкрипт входÑщего звонка Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ Choose outgoing call script Выберите Ñкрипт иÑходÑщего звонка Choose outgoing call answered script Выберите Ñкрипт иÑходÑщего отвеченого звонка Choose outgoing call failed script Выберите Ñкрипт иÑходÑщего звонка Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ Choose local release script Choose remote release script %1 converts to %2 %1 конвертирован в %2 AKA AM&F: A&KA OP: Authentication management field for AKAv1-MD5 authentication. Operator variant key for AKAv1-MD5 authentication. Prepr&ocessing Пред&обработка Preprocessing (improves quality at remote end) ÐŸÑ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ° (улучшает качеÑтво звука на удалённой Ñтороне) &Automatic gain control &ÐвтоматичеÑкий контроль уÑÐ¸Ð»ÐµÐ½Ð¸Ñ Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Automatic gain control &level: ÐвтоматичеÑкий контроль ÑƒÑ€Ð¾Ð²Ð½Ñ &уÑилениÑ: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. &Voice activity detection &Определение голоÑовой активноÑти When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. &Noise reduction &Понижение шума The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. Acoustic &Echo Cancellation In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Variable &bit-rate Переменный &битрейт Discontinuous &Transmission &Quality: &КачеÑтво: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. bytes байт P&ersistent TCP connection П&оÑтоÑнные TCP ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. Use tel-URI for telephone &number ИÑпользовать tel-URI Ð´Ð»Ñ Ñ‚ÐµÐ»ÐµÑ„Ð¾Ð½Ð½Ð¾Ð³Ð¾ &номера Expand a dialed telephone number to a tel-URI instead of a sip-URI. &Send composing indications when typing a message. &ПоÑылать оповещение о наборе теÑкта при вводе ÑообщениÑ. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. Twinkle поÑылает Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ наборе ÑообщениÑ. Получатель будет видеть когда вы печатате. Accept call &transfer request (incoming REFER) Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. Enable NAT &keep alive Send UDP NAT keep alive packets. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. WizardForm Twinkle - Wizard Twinkle - МаÑтер The hostname, domain name or IP address of the STUN server. Ð˜Ð¼Ñ Ñервера, доменное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ STUN Ñервера. S&TUN server: S&TUN Ñервер: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. SIP Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñтавленное вашим провайдером. ПользовательÑÐºÐ°Ñ Ñ‡Ð°Ñть вашего SIP адреÑа, <b>username</b>@domain.com может быть вашим телефонным номером. <br><br> Это поле ÑвлÑетÑÑ Ð¾Ð±Ñзательным. &Domain*: &Домен*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. Выберите вашего провайдера SIP уÑлуг. ЕÑли вашего провайдера нет в ÑпиÑке, тогда выберите <b>Other</b> и заполните Ð¿Ð¾Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ полученными от вашего провайдера.<br><br> ЕÑли вы выбрали одного из предопределённых провайдеров SIP уÑлуг, то вы должны только заполнить ваше имÑ, Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ, Ð¸Ð¼Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ и пароль. &Authentication name: &Ðутентификационное имÑ: &Your name: &Ваше имÑ: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ваше Ð¸Ð¼Ñ SIP аутентификации. Довольно чаÑто Ñовпадает Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ SIP. Однако может иметь и другое значение. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Ð”Ð¾Ð¼ÐµÐ½Ð½Ð°Ñ Ñ‡Ð°Ñть вашего SIP адреÑа , username@<b>domain.com</b>. ВмеÑто реального домена также может быть именем машины или IP адреÑом вашего <b>SIP proxy</b>. ЕÑли вы звоните напрÑмую Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° на компьютер, то заполните именем или IP адреÑом вашей машины <br><br> Это поле ÑвлÑетÑÑ Ð¾Ð±Ñзательным. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Это проÑто ваше полное имÑ, например John Doe. Оно иÑпользуетÑÑ Ð² качеÑтве отображаемого имени. Когда Ð’Ñ‹ делаете звонок, Ñто Ð¸Ð¼Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть указано в качеÑтве вызывающей Ñтороны. SIP pro&xy: SIP про&кÑи: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. Ð˜Ð¼Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°, доменное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ SIP прокÑи. ЕÑли оно Ñовпадает Ñо значением вашего домена, вы можете оÑтавить его пуÑтым. &SIP service provider: Провайдер &SIP уÑлуг: &Password: &Пароль: &User name*: &Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ*: Your password for authentication. Ваш пароль Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸. &OK &ПринÑть Alt+O &Cancel &Отмена Alt+C None (direct IP to IP calls) ОтÑутÑтвует (ПрÑмое IP - IP Ñоединение) Other Другой User profile wizard: Помошник Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: You must fill in a user name for your SIP account. Ð’Ñ‹ должны заполнить Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ учётной запиÑи SIP. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Ð’Ñ‹ должны заполнить Ð¸Ð¼Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ учётной запиÑи SIP. Это может быть Ð¸Ð¼Ñ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ компьютера еÑли вы выполнÑете прÑмые звонки между компьютерами. Invalid value for SIP proxy. Ðеправильное значение Ð´Ð»Ñ SIP прокÑи. Invalid value for STUN server. Ðеправильное значение Ð´Ð»Ñ STUN Ñервера. YesNoDialog &Yes &Да &No &Ðет twinkle-1.4.2/src/gui/lang/twinkle_sv.ts0000644000175000001440000066553611151060225015157 00000000000000 AddressCardForm Twinkle - Address Card Twinkle - Adresskort &Remark: Infix name of contact. First name of contact. Förnamn för kontakten. &First name: &Förnamn: You may place any remark about the contact here. &Phone: &Telefon: &Infix name: Phone number or SIP address of contact. Telefonnummer eller SIP-adress för kontakten. Last name of contact. Efternamn för kontakten. &Last name: &Efternamn: &OK &OK Alt+O Alt+O &Cancel &Avbryt Alt+C Alt+A You must fill in a name. Du mÃ¥ste ange ett namn. You must fill in a phone number or SIP address. Du mÃ¥ste ange ett telefonnummer eller SIP-adress. AuthenticationForm Twinkle - Authentication Twinkle - Autentisering user No need to translate användare The user for which authentication is requested. Användaren för vilken autentisering begärs. profile No need to translate profil The user profile of the user for which authentication is requested. Användarprofilen för användaren för vilken autentisering begärs. User profile: Användarprofil: User: Användare: &Password: &Lösenord: Your password for authentication. Ditt lösenord för autentisering. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ditt SIP-autentiseringsnamn. Ganska ofta är detta samma som ditt SIP-användarnamn. Det kan dock vara ett annat namn. &User name: Användar&namn: &OK &OK &Cancel &Avbryt Login required for realm: realm No need to translate The realm for which you need to authenticate. BuddyForm Twinkle - Buddy Twinkle - Kompis Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. &Phone: &Telefon: Name of your buddy. Namnet pÃ¥ din kompis. &Show availability &Visa tillgänglighet Alt+S Alt+V Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. Kryssa för detta alternativ om du vill se tillgängligheten för din kompis. Detta kommer endast att fungera om din leverantör erbjuder en närvaroagent. &Name: &Namn: SIP address your buddy. SIP-adress till din kompis. &OK &OK Alt+O Alt+O &Cancel &Avbryt Alt+C Alt+A You must fill in a name. Du mÃ¥ste ange ett namn. Invalid phone. Ogiltig telefon. Failed to save buddy list: %1 Misslyckades med att spara kompislista: %1 BuddyList Availability Tillgänglighet unknown okänd offline frÃ¥nkopplad online ansluten request failed begäran misslyckades request rejected begäran avvisades not published inte publicerad failed to publish misslyckades med att publicera Click right to add a buddy. Högerklicka för att lägga till en kompis. CoreAudio Failed to open sound card MIsslyckades med att öppna ljudkortet Failed to create a UDP socket (RTP) on port %1 Misslyckades med att skapa ett UDP-uttag(RTP) pÃ¥ port %1 Failed to create audio receiver thread. Misslyckades med att skapa ljudmottagartrÃ¥d. Failed to create audio transmitter thread. Misslyckades med att skapa ljudsändartrÃ¥d. CoreCallHistory local user lokal användare remote user fjärranvändare failure fel unknown okänd in in out ut DeregisterForm Twinkle - Deregister Twinkle - Avregistrering deregister all devices avregistrera alla enheter &OK &OK &Cancel &Avbryt DiamondcardProfileForm Twinkle - Diamondcard User Profile Your Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Detta är helt enkelt ditt fullständiga namn, t.ex. Sven Svensson. Det används endast för visning. När du ringer ett samtal kan dock detta namn visas för motparten. &Account ID: &PIN code: &Your name: &Ditt namn: <p align="center"><u>Sign up for a Diamondcard account</u></p> &OK &OK Alt+O &Cancel &Avbryt Alt+C Fill in your account ID. Fill in your PIN code. A user profile with name %1 already exists. Your Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> DtmfForm Twinkle - DTMF Twinkle - DTMF Keypad Knappsats 2 2 3 3 Over decadic A. Normally not needed. Över dekadiskt A. Behövs oftast inte. 4 4 5 5 6 6 Over decadic B. Normally not needed. Över dekadiskt B. Behövs oftast inte. 7 7 8 8 9 9 Over decadic C. Normally not needed. Över dekadiskt C. Behövs oftast inte. Star (*) Stjärna (*) 0 0 Pound (#) Fyrkant (#) Over decadic D. Normally not needed. Över dekadiskt D. Behövs oftast inte. 1 1 &Close S&täng Alt+C Alt+T FreeDeskSysTray Show/Hide Visa/Göm Quit Avsluta GUI Failed to create a UDP socket (SIP) on port %1 Kunde inte skapa UDP-socket (SIP) pÃ¥ port %1 Override lock file and start anyway? Strunta i lÃ¥sfil och starta ändÃ¥? The following profiles are both for user %1 Följande profiler är bÃ¥da för användaren %1 You can only run multiple profiles for different users. Du kan endast köra flera profiler för olika användare. Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Kan inte hitta ett nätverkskort. Twinkle kommer att använda 127.0.0.1 som lokal IP-adress. När du ansluter till nätverket sÃ¥ mÃ¥ste du starta om Twinkle för att använda den korrekta IP-adressen. Line %1: incoming call for %2 Linje %1: inkommande samtal för %2 Call transferred by %1 Samtal kopplat av %1 Line %1: far end cancelled call. Line %1: far end released call. Line %1: SDP answer from far end not supported. Linje %1: SDP-svar frÃ¥n andra parten stöds inte. Line %1: SDP answer from far end missing. Linje %1: Inget SDP-svar frÃ¥n andra parten. Line %1: Unsupported content type in answer from far end. Line %1: no ACK received, call will be terminated. Linje %1: inget ACK mottaget. Samtalet kommer avslutas. Line %1: no PRACK received, call will be terminated. Linje %1: inget PRACK mottaget. Samtalet kommer avslutas. Line %1: PRACK failed. Linje %1: PRACK misslyckades. Line %1: failed to cancel call. Linje %1: misslyckades med att avbryta samtal. Line %1: far end answered call. Linje %1: motparten svarade pÃ¥ samtalet. Line %1: call failed. Linje %1: samtal misslyckades. The call can be redirected to: Samtalet kan vidarekopplas till: Line %1: call released. Line %1: call established. Linje %1: samtal etablerat. Response on terminal capability request: %1 %2 Svar pÃ¥ begäran om terminalförmÃ¥gor: %1 %2 Terminal capabilities of %1 TerminalförmÃ¥gor för %1 Accepted body types: unknown okänt Accepted encodings: Accepterade kodningar: Accepted languages: Accepterade sprÃ¥k: Allowed requests: TillÃ¥tna begäran: Supported extensions: none End point type: Typ av motpart: Line %1: call retrieve failed. %1, registration failed: %2 %3 %1, registrering misslyckades: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, registrering lyckades (gÃ¥r ut om = %2 sekunder) %1, registration failed: STUN failure %1, registrering misslyckades: STUN-problem %1, de-registration succeeded: %2 %3 %1, avregistrering lyckades: %2 %3 %1, de-registration failed: %2 %3 %1, avregistrering misslyckades: %2 %3 %1, fetching registrations failed: %2 %3 : you are not registered : du är inte registrerad : you have the following registrations : du har följande registreringar : fetching registrations... : hämtar registreringar... Line %1: redirecting request to Linje %1: Skickar vidare till Redirecting request to: %1 Skickar vidare till: %1 Line %1: DTMF detected: Linje %1: DTMF detekterad: invalid DTMF telephone event (%1) Line %1: send DTMF %2 Linje %1: skicka DTMF %2 Line %1: far end does not support DTMF telephone events. Line %1: received notification. Event: %1 Händelse: %1 State: %1 TillstÃ¥nd: %1 Reason: %1 Anledning: %1 Progress: %1 %2 Förlopp: %1 %2 Line %1: call transfer failed. Linje %1: samtalskoppling misslyckades. Line %1: call succesfully transferred. Linje %1: samtal kopplades. Line %1: call transfer still in progress. Linje %1: samtalskoppling pÃ¥gÃ¥r fortfarande. No further notifications will be received. Line %1: transferring call to %2 Linje %1: kopplar samtal till %2 Transfer requested by %1 Koppilng begärd av %1 Line %1: Call transfer failed. Retrieving original call. %1, STUN request failed: %2 %3 %1. STUN-begäran misslyckades: %2 %3 %1, STUN request failed. %1, STUN-begäran misslyckades. Redirecting call Vidarekoppling av samtal User profile: Användarprofil: User: Användare: Do you allow the call to be redirected to the following destination? TillÃ¥ter du samtalet att hänvisas till följande destination? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. Om du inte vill bli frÃ¥gad detta igen mÃ¥ste du ändra inställningarna i sektionen SIP-protokoll för användarprofilen. Redirecting request Do you allow the %1 request to be redirected to the following destination? Transferring call Request to transfer call received from: Request to transfer call received. Do you allow the call to be transferred to the following destination? TillÃ¥ter du samtalet att kopplas vidare till följande destination? Info: Warning: Varning: Critical: Firewall / NAT discovery... Brandvägg / NAT-identifiering... Abort Avbryt Line %1 Linje %1 Click the padlock to confirm a correct SAS. Klicka pÃ¥ hänglÃ¥set för att bekräfta en korrekt SAS. The remote user on line %1 disabled the encryption. Motparten pÃ¥ linje %1 stängde av krypteringen. Line %1: SAS confirmed. Linje %1: SAS bekräftad. Line %1: SAS confirmation reset. %1, voice mail status failure. %1, kan inte hämta status för röstbrevlÃ¥da. %1, voice mail status rejected. %1, hämtning av status för röstbrevlÃ¥da avvisades. %1, voice mailbox does not exist. %1, röstbrevlÃ¥dan finns inte. %1, voice mail status terminated. %1, hämtning av status för röstbrevlÃ¥da avslutad. Line %1: call rejected. Linje %1: samtal avvisades. Line %1: call redirected. Linje %1: samtal vidarekopplat. Failed to start conference. Kunde inte starta konferens. Failed to create a %1 socket (SIP) on port %2 Misslyckades med att skapa ett %1-uttag (SIP) pÃ¥ port %2 If these are users for different domains, then enable the following option in your user profile (SIP protocol) Use domain name to create a unique contact header Failed to save message attachment: %1 Misslyckades med att spara meddelandebilaga: %1 Accepted by network Accepterad av nätverket Transferred by: %1 Cannot open web browser: %1 Configure your web browser in the system settings. GetAddressForm Twinkle - Select address Twinkle - Välj adress &KAddressBook &KAddressBook Name Namn Type Typ Phone Telefon This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. &Show only SIP addresses &Visa endast SIP-adresser Alt+S Alt+V Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". Kryssa för detta alternativ när du endast vill se kontakter med SIP-adresser, alltsÃ¥ börjar med "<b>sip:</b>". &Reload Upp&datera Alt+R Alt+D Reload the list of addresses from KAddressbook. Uppdatera listan över adresser frÃ¥n KAddressbook. &Local address book &Lokal adressbok Remark Contacts in the local address book of Twinkle. Kontakter i den lokala adressboken för Twinkle. &Add &Lägg till Alt+A Alt+L Add a new contact to the local address book. Lägg till en ny kontakt i den lokala adressboken. &Delete &Ta bort Alt+D Alt+T Delete a contact from the local address book. Ta bort en kontakt frÃ¥n den lokala adressboken. &Edit &Redigera Alt+E Alt+R Edit a contact from the local address book. Redigera en kontakt frÃ¥n den lokala adressboken. &OK &OK Alt+O Alt+O &Cancel &Avbryt Alt+C Alt+A <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> GetProfileNameForm Twinkle - Profile name Twinkle - Profilnamn &OK &OK &Cancel &Avbryt Enter a name for your profile: Ge din profil ett namn: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> <b>Din profils namn</b> <br><br> En profil innehÃ¥ller dina användarinställningar. T.ex. ditt användarnamn och lösenord. Du mÃ¥ste ge varje profil ett namn. <br><br> Om du har flera SIP-konton kan du skapa flera profiler. När du startar Twinkle kommer du se en lista över dina profiler och kunna välja vilken av profilerna du vill använda. <br><br> För att enkelt komma ihÃ¥g dina profiler kan du använda ditt SIP-användarnamn som profilnamn. T.ex. <b>exempel@exempel.com</b> Cannot find .twinkle directory in your home directory. Kan inte hitta katalogen .twinkle i din hemkatalog. Profile already exists. Profilen finns redan. Rename profile '%1' to: Döp om profilen '%1' till: HistoryForm Twinkle - Call History Twinkle - Samtalshistorik Time Tid In/Out In/Ut From/To FrÃ¥n/Till Subject Ämne Status Status Call details Samtalsdetaljer Details of the selected call record. Detaljer för det valda samtalet. View Visa &Incoming calls &Inkommande samtal Alt+I Alt+I Check this option to show incoming calls. Kryssa i denna ruta för att visa inkommande samtal. &Outgoing calls &UtgÃ¥ende samtal Alt+O Alt+U Check this option to show outgoing calls. Kryssa i denna ruta för att visa utgÃ¥ende samtal. &Answered calls &Besvarade samtal Alt+A Alt+B Check this option to show answered calls. Kryssa i denna ruta för att visa besvarade samtal. &Missed calls &Missade samtal Alt+M Alt+M Check this option to show missed calls. Kryssa i denna ruta för att visa missade samtal. Current &user profiles only Enbart aktuell &användarprofil Alt+U Alt+A Check this option to show only calls associated with this user profile. Kryssa i denna ruta för att enbart visa samtal associerade med aktuell användarprofil. C&lear &Töm Alt+L Alt+T <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> <p>Töm hela samtalshistoriken.</p> <p><b>Observera:</b> detta rensar bort <b>alla</b> samtal. Även samtal som inte visas pÃ¥ grund av aktuella visningsalternativ.</p> &Close &Stäng Alt+C Alt+S Close this window. Stäng detta fönster. Call start: Samtal startade: Call answer: Samtal besvarades: Call end: Samtal avslutades: Call duration: Samtalslängd: Direction: Riktning: From: FrÃ¥n: To: Till: Reply to: Svara till: Referred by: Kopplad av: Subject: Ämne: Released by: Avslutat av: Status: Status: Far end device: Enhet pÃ¥ andra sidan: User profile: Användarprofil: conversation konversation Call... Ring upp... Delete Ta bort Re: Sv: Clo&se St&äng Alt+S Alt+Ä &Call &Ring Call selected address. Ring markerad adress. Number of calls: ### Total call duration: InviteForm Twinkle - Call Twinkle - Ring &To: &Till: Optionally you can provide a subject here. This might be shown to the callee. Om du vill kan du ange ämne här. Det kan visas för den du ringer. Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adressen som du vill ringa. Detta kan vara en komplett SIP-adress som <b>sip:exempel@exempel.com</b> eller bara användarnamnet eller telefonnumret i adressen. När du inte anger en komplett adress kommer Twinkle fylla ut adressen med domännamnet frÃ¥n din användarprofil. The user that will make the call. Användare som ringer upp. &Subject: &Ämne: &From: &FrÃ¥n: &Hide identity &Dölj identitet Alt+H Alt+D <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> <p> Med denna inställning kan du be din SIP-leverantör dölja din identitet för den du ringer upp. Detta döljer bara din identitet. D.v.s. din SIP-adress eller telefonnummer. Det döljer <b>inte</b> din IP-adress. </p> <p> <b>Varning:</b> Inte alla SIP-leverantörer stöder dold identitet. </p> &OK &OK &Cancel &Avbryt Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. Inte alla SIP-leverantörer stöder dold identitet. Se till att din SIP-leverantör stöder det om du verkligen behöver det. F10 F10 LogViewForm Twinkle - Log Twinkle - Logg Contents of the current log file (~/.twinkle/twinkle.log) InnehÃ¥ll i nuvarande loggfil (~/.twinkle/twinkle.log) &Close &Stäng Alt+C Alt+S C&lear &Töm Alt+L Alt+T Clear the log window. This does <b>not</b> clear the log file itself. Töm loggfönstret. Detta tömmer <b>inte</b> själva loggfilen. MessageForm Twinkle - Instant message Twinkle - Snabbmeddelande &To: &Till: The user that will send the message. Användaren som ska skicka meddelandet. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. &User profile: &Användarprofil: Conversation Konversation Type your message here and then press "send" to send it. Skriv ditt meddelande här och tryck sedan pÃ¥ "Skicka" för att skicka det. &Send &Skicka Alt+S Alt+S Send the message. Skicka meddelandet. Instant message toolbar Verktygsrad för snabbmeddelanden Send file... Skicka fil... Send file Skicka fil image size is scaled down in preview bildstorleken är nedskalad i förhandsvisning Delivery failure Leverans misslyckades Delivery notification Leveransnotifiering Open with %1... Öppna med %1... Open with... Öppna med... Save attachment as... Spara bilaga som... File already exists. Do you want to overwrite this file? Filen finns redan. Vill du skriva över denna fil? Failed to save attachment. Misslyckades med att spara bilaga. %1 is typing a message. %1 skriver ett meddelande. F10 F10 Size MessageFormView sending message skickar meddelande MphoneForm Twinkle Twinkle &Call: Label in front of combobox to enter address &Ring: The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adressen som du vill ringa. Detta kan vara en komplett SIP-adress som <b>sip:exempel@exempel.com</b> eller bara användarnamnet eller telefonnumret i adressen. När du inte anger en komplett adress kommer Twinkle fylla ut adressen med domännamnet frÃ¥n din användarprofil. Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. Dial Ring Dial the address. Ring till adressen. &User: &Användare: The user that will make the call. Användaren som ska ringa samtalet. Auto answer indication. Call redirect indication. Do not disturb indication. Missed call indication. Registration status. Display Line status Linjestatus Line &1: Linje &1: Alt+1 Alt+1 Click to switch to line 1. Klicka för att växla till linje 1. From: FrÃ¥n: To: Till: Subject: Ämne: Visual indication of line state. idle No need to translate Overksam Call is on hold Voice is muted Conference call Konferenssamtal Transferring call <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> sas No need to translate sas Short authentication string g711a/g711a No need to translate g711a/g711a Audio codec Ljudkodek 0:00:00 0:00:00 Call duration Samtalslängd sip:from No need to translate sip:frÃ¥n sip:to No need to translate sip:till subject No need to translate ämne photo No need to translate foto Line &2: Linje &2: Alt+2 Alt+2 Click to switch to line 2. Klicka för att växla till linje 2. &File &Arkiv &Edit &Redigera C&all &Ring Activate line Aktivera linje &Registration &Registrering &Services &Tjänster &View &Visa &Help &Hjälp Call Toolbar Quit Avsluta &Quit &Avsluta Ctrl+Q Ctrl+A About Twinkle Om Twinkle &About Twinkle &Om Twinkle Call toolbar text Ring &Call... call menu text &Ring... Call someone Ring nÃ¥gon F5 F5 Answer toolbar text Svara &Answer menu text &Svara Answer incoming call Svara inkommande samtal F6 F6 Bye toolbar text Adjö &Bye menu text &Lägg pÃ¥ Release call Esc Esc Reject toolbar text Avvisa &Reject menu text &Avvisa Reject incoming call Avvisa inkommande samtal F8 F8 Hold toolbar text &Hold menu text &Parkera Put a call on hold, or retrieve a held call Pakera ett samtal eller Ã¥teruppta ett parkerat samtal Redirect toolbar text Koppla vidare R&edirect... menu text Koppla vidar&e... Redirect incoming call without answering Koppla vidare inkommande samtal utan att svara Dtmf toolbar text Dtmf &Dtmf... menu text &Dtmf... Open keypad to enter digits for voice menu's Öppna knappsats för att mata in siffror för röstmenyer Register Registrera &Register &Registrera Deregister Avregistrera &Deregister Avre&gistrera Deregister this device Avregistrera denna enhet Show registrations Visa registreringar &Show registrations &Visa registreringar Terminal capabilities TerminalförmÃ¥gor &Terminal capabilities... menu text &TerminalförmÃ¥gor... Request terminal capabilities from someone Begär terminalförmÃ¥gor frÃ¥n nÃ¥gon Do not disturb Stör inte &Do not disturb Stör &inte Call redirection Vidarekoppla samtal Call &redirection... Vidarekoppla sa&mtal... Redial toolbar text Ring igen &Redial menu text Ring &igen Repeat last call Upprepa senaste samtalet F12 F12 About Qt Om Qt About &Qt Om &Qt User profile Användarprofil &User profile... &Användarprofil... Conf toolbar text Konf &Conference menu text &Konferens Join two calls in a 3-way conference Mute toolbar text Tyst &Mute menu text &Tyst Mute a call Stäng av mikrofonen Xfer toolbar text Koppla Trans&fer... menu text Kopp&la... Transfer call Koppla samtal System settings Systeminställningar &System settings... &Systeminställningar... Deregister all Avregistrera alla Deregister &all Avregistrera &alla Deregister all your registered devices Avregistera alla dina registrerade enheter Auto answer Svara automatiskt &Auto answer S&vara automatiskt Log Logg &Log... &Logg... Call history Samtalshistorik Call &history... Samtals&historik... F9 F9 Change user ... Byt användare... &Change user ... &Byt användare... Activate or de-activate users Aktivera eller inaktivera användare What's This? Vad är detta? What's &This? Vad är &detta? Shift+F1 Shift+F1 Line 1 Linje 1 Line 2 Linje 2 idle overksam dialing ringer attempting call, please wait försöker ringa samtal, vänta incoming call inkommande samtal establishing call, please wait etablerar samtal, vänta established etablerat established (waiting for media) etablerat (väntar pÃ¥ media) releasing call, please wait unknown state okänt tillstÃ¥nd Voice is encrypted Röstkanal är krypterad Click to confirm SAS. Klicka för att bekräfta SAS. Click to clear SAS verification. Transfer consultation User: Användare: Call: Ring: Hide identity Dölj identitet Registration status: Registreringsstatus: Registered Registrerad Failed Misslyckades Not registered Inte registrerad Click to show registrations. Klicka för att visa registreringar. No users are registered. Inga användare är registrerade. %1 new, 1 old message %1 nytt, ett gammalt meddelande %1 new, %2 old messages %1 nya, %2 gamla meddelanden 1 new message Ett nytt meddelande %1 new messages %1 nya meddelanden 1 old message Ett gammalt meddelande %1 old messages %1 gamla meddelanden Messages waiting Meddelanden väntar No messages Inga meddelanden <b>Voice mail status:</b> <b>Status för röstbrevlÃ¥da:</b> Failure Misslyckades Unknown Okänt Click to access voice mail. Klicka för att komma Ã¥t röstmeddelanden. Do not disturb active for: Stör inte är aktivt för: Redirection active for: Vidarekoppling är aktivt för: Auto answer active for: Svara automatiskt är aktivt för: Click to activate/deactivate Klicka för att aktivera/inaktivera Click to activate Klicka för att aktivera Do not disturb is not active. Stör inte är inte aktiverat. Redirection is not active. Vidarekoppling är inte aktiverat. Auto answer is not active. Svara automatiskt är inte aktiverat. Click to see call history for details. Klicka för att se samtalshistorik för detaljer. You have no missed calls. Du har inga missade samtal. You missed 1 call. Du missade ett samtal. You missed %1 calls. Du missade %1 samtal. Starting user profiles... Startar användarprofiler... The following profiles are both for user %1 Följande profiler är bÃ¥da för användaren %1 You can only run multiple profiles for different users. Du kan endast köra flera profiler för olika användare. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. not provisioned You must provision your voice mail address in your user profile, before you can access it. The line is busy. Cannot access voice mail. Linjen är upptagen. Kan inte komma Ã¥t röstmeddelanden. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Buddy list Kompislista You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. Message waiting indication. &Message &Meddelande &Display Voice mail RöstbrevlÃ¥da &Voice mail &RöstbrevlÃ¥da Access voice mail F11 F11 Msg Chatt Instant &message... Snabb&meddelande... Instant message Snabbmeddelande &Buddy list &Kompislista &Call... &Ring... &Edit... &Redigera... &Delete &Ta bort O&ffline Fr&Ã¥nkopplad &Online A&nsluten &Change availability &Ändra tillgänglighet &Add buddy... &Lägg till kompis... Failed to save buddy list: %1 Misslyckades med att spara kompislista. %1 F10 F10 Diamondcard Manual &Manual Sign up &Sign up... Recharge... Balance history... Call history... Admin center... Recharge Balance history Admin center NumberConversionForm Twinkle - Number conversion Twinkle - Nummerkonvertering &Match expression: &Matcha uttryck: &Replace: &Ersätt: Perl style format string for the replacement number. Perl style regular expression matching the number format you want to modify. &OK &OK Alt+O Alt+O &Cancel &Avbryt Alt+C Alt+A Match expression may not be empty. Uttryck att matcha mot kan inte vara tomt. Replace value may not be empty. Ersättningsvärde kan inte vara tomt. Invalid regular expression. Ogiltigt reguljärt uttryck. RedirectForm Twinkle - Redirect Twinkle - Koppla vidare Redirect incoming call to Koppla vidare inkommande samtal till You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Du kan ange upp till 3 destinationer att koppla vidare samtalet till. Om första destinationen inte svarar gÃ¥r man vidare till andra destinationen och sÃ¥ vidare. &3rd choice destination: Destination i &tredje hand: &2nd choice destination: Destination i &andra hand: &1st choice destination: Destination i &första hand: Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. &OK &OK &Cancel &Avbryt F10 F10 F12 F12 F11 F11 SelectNicForm Twinkle - Select NIC Twinkle - Välj nätverkskort Select the network interface/IP address that you want to use: Välj nätverkskort/IP-adress som du vill använda: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. Du har flera IP-adresser. Här mÃ¥ste du välja vilken IP-adress som ska användas. Denna IP-adress kommer användas i alla SIP-meddelanden. Set as default &IP Ange som standard-&IP Alt+I Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Gör den valda IP-adressen till standard-IP-adress. Nästa gÃ¥ng som du startar Twinkle kommer denna IP-adress att väljas automatiskt. Set as default &NIC Ange som standard&nätverkskort Alt+N Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. Gör det valda nätverkskortet till standardgränssnitt. Nästa gÃ¥ng som du startar Twinkle kommer detta nätverkskort att väljas automatiskt. &OK &OK Alt+O Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. Om du vill ta bort eller ändra standardvärdet vid ett senare tillfälle sÃ¥ kan du göra det via systeminställningarna. SelectProfileForm Twinkle - Select user profile Twinkle - Välj användarprofil Select user profile(s) to run: Välj användarprofil(er) att köra: User profile Användarprofil Tick the check boxes of the user profiles that you want to run and press run. Kryssa för de användarprofiler som du vill köra och tryck pÃ¥ Kör. &New &Ny Alt+N Alt+N Create a new profile with the profile editor. Skapa en ny profil med profilredigeraren. &Wizard &Guide Alt+W Alt+G Create a new profile with the wizard. Skapa en ny profil med guiden. &Edit &Redigera Alt+E Alt+R Edit the highlighted profile. Redigera markerad profil. &Delete &Ta bort Alt+D Alt+T Delete the highlighted profile. Ta bort markerad profil. Ren&ame Byt &namn Alt+A Alt+N Rename the highlighted profile. Byt namn pÃ¥ markerad profil. &Set as default &Ange som standard Alt+S Alt+A Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. Gör de markerade profilerna till standardprofiler. Nästa gÃ¥ng som du startar Twinkle sÃ¥ kommer dessa profiler att köras automatiskt. &Run &Kör Alt+R Alt+K Run Twinkle with the selected profiles. Kör Twinkle med markerade profiler. S&ystem settings S&ysteminställningar Alt+Y Alt+Y Edit the system settings. Redigera systeminställningarna. &Cancel &Avbryt Alt+C Alt+A <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> <html>Innan du kan använda Twinkle mÃ¥ste du skapa en användarprofil.<br>Klicka OK för att skapa en profil.</html> &Profile editor &Profilredigerare <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> You did not select any user profile to run. Please select a profile. Du valde inte nÃ¥gon användarprofil att köra. Välj en profil. Are you sure you want to delete profile '%1'? Är du säker pÃ¥ att du vill ta bort profilen "%1"? Delete profile Ta bort profil Failed to delete profile. Misslyckades med att ta bort profil. Failed to rename profile. Misslyckades med att byta namn pÃ¥ profil. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> Cannot find .twinkle directory in your home directory. Kan inte hitta katalogen .twinkle i din hemkatalog. Create profile Ed&itor Alt+I Alt+I Dia&mondcard Alt+M Alt+M Modify profile Startup profile &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> SelectUserForm Twinkle - Select user Twinkle - Välj användare &Cancel &Avbryt Alt+C Alt+A &Select all &Välj alla Alt+S Alt+V &OK &OK Alt+O Alt+O C&lear all &Töm alla Alt+L Alt+T purpose No need to translate syfte User Användare Register Registrera Select users that you want to register. Välj användare som du vill registrera. Deregister Avregistrera Select users that you want to deregister. Välj användare som du vill avregistrera. Deregister all devices Avregistrera alla enheter Select users for which you want to deregister all devices. Välj användare för vilka du vill avregistrera alla enheter. Do not disturb Stör inte Select users for which you want to enable 'do not disturb'. Välj användare för vilka du vill aktivera 'stör ej'. Auto answer Svara automatiskt Select users for which you want to enable 'auto answer'. Välj användare för vilka du vill aktivera "svara automatiskt". SendFileForm Twinkle - Send File Twinkle - Skicka fil Select file to send. Välj fil att skicka. &File: &Fil: &Subject: &Ämne: &OK &OK Alt+O Alt+O &Cancel &Avbryt Alt+C Alt+A File does not exist. Filen finns inte. Send file... Skicka fil... SrvRedirectForm Twinkle - Call Redirection User: Användare: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> &Unconditional &Redirect all calls Alt+R Activate the unconditional redirection service. Redirect to You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. Du kan ange upp till 3 destinationer att koppla vidare samtalet till. Om första destinationen inte svarar gÃ¥r man vidare till andra destinationen och sÃ¥ vidare. &3rd choice destination: Destination i &3:e hand: &2nd choice destination: Destination i &2:a hand: &1st choice destination: Destination i &1:a hand: Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. &Busy &Upptagen &Redirect calls when I am busy Activate the redirection when busy service. &No answer &Inget svar &Redirect calls when I do not answer Activate the redirection on no answer service. &OK &OK Alt+O Alt+O Accept and save all changes. Acceptera och spara alla ändringar. &Cancel &Avbryt Alt+C Alt+A Undo your changes and close the window. Ã…ngra dina ändringar och stäng fönstret. You have entered an invalid destination. Du har angivit en ogiltig destination. F10 F10 F11 F11 F12 F12 SysSettingsForm Twinkle - System Settings Twinkle - Systeminställningar General Generellt Audio Ljud Ring tones Ringsignaler Address book Adressbok Network Nätverk Log Logg Select a category for which you want to see or modify the settings. Välj den kategori som du vill titta eller ändra inställningar för. &OK &OK Alt+O Alt+O Accept and save your changes. Acceptera och spara dina ändringar. &Cancel &Avbryt Alt+C Alt+A Undo all your changes and close the window. Ã…ngra alla ändringar och stäng fönstret. Sound Card Ljudkort Select the sound card for playing the ring tone for incoming calls. Välj det ljudkort som ska användas för att spela upp ringsignalen när nÃ¥gon ringer. Select the sound card to which your microphone is connected. Välj det ljudkort som din mikrofon är inkopplad till. Select the sound card for the speaker function during a call. Välj det ljudkort som högtalaren är inkopplad till under samtal. &Speaker: &Högtalare: &Ring tone: &Ringsignal: Other device: Annan enhet: &Microphone: &Mikrofon: &Validate devices before usage &Validera enheterna innan användning Alt+V Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. Reduce &noise from the microphone Reducera &brus frÃ¥n mikrofonen Alt+N Alt+B Advanced Avancerat OSS &fragment size: 16 16 32 32 64 64 128 128 256 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. ALSA &play period size: &ALSA capture period size: The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. &Max log size: &Maximal loggstorlek: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. MB MB Log &debug reports Alt+D Alt+T Indicates if reports marked as "debug" will be logged. Log &SIP reports Logga &SIP-rapporter Alt+S Alt+S Indicates if SIP messages will be logged. Log S&TUN reports Logga S&TUN-rapporter Alt+T Alt+T Indicates if STUN messages will be logged. Log m&emory reports Alt+E Alt+R Indicates if reports concerning memory management will be logged. System tray Aktivitetsfält Create &system tray icon on startup Skapa ikon i a&ktivitetsfält vid uppstart Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. &Hide in system tray when closing main window Alt+H Alt+D Enable this option if you want Twinkle to hide in the system tray when you close the main window. Startup Uppstart S&tartup hidden in system tray Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. Default user profiles Användarprofiler som standard If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. Services Tjänster Call &waiting Samtal &väntar Alt+W Alt+V With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. Hang up &both lines when ending a 3-way conference call. Alt+B Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. &Maximum calls in call history: The maximum number of calls that will be kept in the call history. &Auto show main window on incoming call after Alt+A Alt+B When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Number of seconds after which the main window should be shown. secs s &RTP port: &RTP-port: The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. Ring tone Ringsignal &Play ring tone on incoming call S&pela upp ringsignal vid inkommande samtal Alt+P Alt+P Indicates if a ring tone should be played when a call comes in. Indikerar om en ringsignal ska spelas upp när ett samtal kommer in. &Default ring tone Stan&dardringsignal Play the default ring tone when a call comes in. Spela upp standardringsignalen när ett samtal kommer in. C&ustom ring tone A&npassad ringsignal Alt+U Alt+N Play a custom ring tone when a call comes in. Spela upp en anpassad ringsignal när ett samtal kommer in. Specify the file name of a .wav file that you want to be played as ring tone. Ring back tone P&lay ring back tone when network does not play ring back tone Alt+L Alt+T <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> D&efault ring back tone Play the default ring back tone. Cu&stom ring back tone Play a custom ring back tone. Specify the file name of a .wav file that you want to be played as ring back tone. &Lookup name for incoming call On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. Ove&rride received display name Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. Lookup &photo for incoming call SlÃ¥ upp &foto för inkommande samtal Lookup the photo of a caller in your address book and display it on an incoming call. none This is the 'none' in default IP address combo ingen none This is the 'none' in default network interface combo ingen Ring tones Description of .wav files in file dialog Ringsignaler Choose ring tone Välj ringsignal Ring back tones Description of .wav files in file dialog Choose ring back tone Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. &SIP port: &SIP-port: Max. SIP message size (&TCP): The UDP/TCP port used for sending and receiving SIP messages. Max. SIP message size (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. Select ring tone file. Select ring back tone file. W&eb browser command: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. SysTrayPopup Answer Svara Reject Avvisa Incoming Call TermCapForm Twinkle - Terminal Capabilities Twinkle - TerminalförmÃ¥gor &From: &FrÃ¥n: Get terminal capabilities of Hämta terminalförmÃ¥gor för &To: &Till: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Adressen som du vill frÃ¥ga efter förmÃ¥gor (OPTION-begäran). Detta kan vara en fullständig SIP-adress som <b>sip:exempel@exempel.se</b> eller bara användardelen eller telefonnumret av den fullständiga adressen. När du inte anger en fullständig adress sÃ¥ kommer Twinkle att komplettera adressen genom att använda domänvärdet för din användarprofil. Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. &OK &OK &Cancel &Avbryt F10 F10 TransferForm Twinkle - Transfer Twinkle - Koppla Transfer call to Koppla samtal till &To: &Till: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book Adressbok Select an address from the address book. Välj en adress frÃ¥n adressboken. Type of transfer Typ av koppling &Blind transfer &Blind koppling Alt+B Alt+B Transfer the call to a third party without contacting that third party yourself. T&ransfer with consultation Alt+R Before transferring the call to a third party, first consult the party yourself. Transfer to other &line Alt+L Alt+T Connect the remote party on the active line with the remote party on the other line. &OK &OK Alt+O Alt+O &Cancel &Avbryt F10 F10 TwinkleCore Cannot open file for reading: %1 Kan inte öppna fil för läsning: %1 File system error while reading file %1 . Fel i filsystemet vid läsning frÃ¥n filen %1. Cannot open file for writing: %1 Kan inte öppna fil för skrivning: %1 File system error while writing file %1 . Fel i filsystemet vid skrivning till filen %1. Anonymous Anonym Warning: Varning: Failed to create log file %1 . Kunde inte skapa loggfil %1. Excessive number of socket errors. För stort antal uttagsfel (socket). Built with support for: Byggd med stöd för: Contributions: Bidrag: This software contains the following software from 3rd parties: Den här programmet innehÃ¥ller följande tredjepartsprogramvara: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * GSM codec frÃ¥n Jutta Degener och Carsten Bormann vid Berlins universitet * G.711/G.726 codecs from Sun Microsystems (public domain) * G.711/G.726 kodekar frÃ¥n Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * iLBC implementation frÃ¥n RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * Delar av STUN-projektet frÃ¥n http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ * Delar av libsrv frÃ¥n http://libsrv.sourceforge.net For RTP the following dynamic libraries are linked: För RTP länkas följande dynamiska bibliotek in: Translated to english by <your name> Översatt till svenska av Daniel Nylander Directory %1 does not exist. Katalogen %1 finns inte. Cannot open file %1 . Kan inte öppna filen %1. %1 is not set to your home directory. %1 är inte satt till din hemkatalog. Directory %1 (%2) does not exist. Katalogen %1 (%2) finns inte. Cannot create directory %1 . Kan inte skapa katalogen %1. Lock file %1 already exist, but cannot be opened. LÃ¥sfil %1 finns redan, men kan inte öppnas. %1 is already running. Lock file %2 already exists. %1 körs redan. LÃ¥sfilen %2 finns redan. Cannot create %1 . Kan inte skapa %1. Cannot write to %1 . Kan inte skriva till %1. Syntax error in file %1 . Syntaxfel i filen %1. Failed to backup %1 to %2 Kunde inte kopiera %1 till %2 unknown name (device is busy) okänt namn (enheten är upptagen) Default device Standardenhet Cannot access the ring tone device (%1). Cannot access the speaker (%1). Kan inte komma Ã¥t högtalaren (%1). Cannot access the microphone (%1). Kan inte komma Ã¥t mikrofonen (%1). Call transfer - %1 Sound card cannot be set to full duplex. Ljudkortet kan inte ställas in i full duplex-läge. Cannot set buffer size on sound card. Kan inte ställa in buffertstorlek pÃ¥ ljudkortet. Sound card cannot be set to %1 channels. Ljudkortet kan inte ställas in till %1 kanaler. Cannot set sound card to 16 bits recording. Cannot set sound card to 16 bits playing. Cannot set sound card sample rate to %1 Opening ALSA driver failed Cannot open ALSA driver for PCM playback Cannot resolve STUN server: %1 Kan inte slÃ¥ upp STUN-server: %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. Du är bakom en symmetrisk NAT. STUN kommer inte fungera. Konfigurera en publik IP-adress i användarprofilen och skapa följande statiska bindningar (UDP) i din NAT. public IP: %1 --> private IP: %2 (SIP signaling) publik IP: %1 --> privat IP: %2 (SIP-signalering) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) publik IP: %1-%2 --> privat IP: %3-%4 (RTP/RTCP) Cannot reach the STUN server: %1 Kan inte kontakta STUN-servern: %1 If you are behind a firewall then you need to open the following UDP ports. Om du är bakom en brandvägg behöver du öppna följande UDP-portar. Port %1 (SIP signaling) Port %1 (SIP-signalering) Ports %1-%2 (RTP/RTCP) Portar %1-%2 (RTP/RTCP) NAT type discovery via STUN failed. STUN kunde inte detektera NAT-typ. Failed to create file %1 Misslyckades med att skapa filen %1 Failed to write data to file %1 Misslyckades med att skriva data till filen %1 Cannot receive incoming TCP connections. Kan inte ta emot inkommande TCP-anslutningar. Cannot open ALSA driver for PCM capture Kan inte öppna ALSA-drivrutin för PCM-fÃ¥ngst Failed to send message. Misslyckades med att skicka meddelande. Cannot lock %1 . UserProfileForm Twinkle - User Profile Twinkle - Användarprofil User profile: Användarprofil: Select which profile you want to edit. Välj den profil du vill ändra. User Användare SIP server SIP-server Voice mail RöstbrevlÃ¥da RTP audio RTP-ljud SIP protocol SIP-protokoll NAT NAT Address format Adressformat Timers Ring tones Ringsignaler Scripts Skript Security Säkerhet Select a category for which you want to see or modify the settings. Välj en kategori för vilken du vill se eller ändra inställningar. &OK &OK Alt+O Alt+O Accept and save your changes. Acceptera och spara dina ändringar. &Cancel &Avbryt Alt+C Alt+A Undo all your changes and close the window. Ã…ngra alla dina ändringar och stäng fönstret. SIP account SIP-konto &User name*: &Användarnamn*: &Domain*: &Domän*: Or&ganization: Or&ganisation: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. SIP-användarnamnet som din leverantör levererat till dig. Detta är användardelen av din SIP-adress, <b>användarnamn</b>@domän.se. Detta kan vara ett telefonnummer. <br><br> Detta fält är obligatoriskt. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Domändelen av din SIP-adress, användarnamn@<b>domän.se</b>. Istället för en riktig domän sÃ¥ kan detta även vara värdnamnet eller IP-adressen för din <b>SIP-proxy</b>. Om du vill använda direktkommunikation mellan IP-telefon och IP-telefon sÃ¥ kan du fylla i värdnamnet eller IP-adress för din dator. <br><br> Detta fält är obligatoriskt. You may fill in the name of your organization. When you make a call, this might be shown to the called party. Du kan fylla i namnet för din organisation. När du ringer ett samtal sÃ¥ kan dock detta visas för motparten. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Detta är helt enkelt ditt fullständiga namn, t.ex. Sven Svensson. Det används endast för visning. När du ringer ett samtal kan dock detta namn visas för motparten. &Your name: &Ditt namn: SIP authentication SIP-autentisering &Realm: Authentication &name: &Password: &Lösenord: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ditt SIP-autentiseringsnamn. Ganska ofta är detta samma som ditt SIP-användarnamn. Det kan dock vara ett annat namn. Your password for authentication. Ditt lösenord för autentisering. Registrar &Registrar: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. &Expiry: The registration expiry time that Twinkle will request. seconds sekunder Re&gister at startup Re&gistrera vid uppstart Alt+G Alt+G Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Outbound Proxy UtgÃ¥ende proxy &Use outbound proxy &Använd utgÃ¥ende proxy Alt+U Alt+A Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Outbound &proxy: UtgÃ¥ende &proxy: &Send in-dialog requests to proxy Alt+S Alt+V SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. &Don't send a request to proxy if its destination can be resolved locally. Alt+D Alt+T When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) The hostname, domain name or IP address of your outbound proxy. Värdnamnet, domännamnet eller IP-adressen för din utgÃ¥ende proxy. Co&decs Ko&dekar Codecs Kodekar Available codecs: Tillgängliga kodekar: G.711 A-law G.711 A-law G.711 u-law G.711 u-law GSM GSM speex-nb (8 kHz) speex-nb (8 kHz) speex-wb (16 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) speex-uwb (32 kHz) List of available codecs. Lista över tillgängliga kodekar. Move a codec from the list of available codecs to the list of active codecs. Flytta en kodek frÃ¥n listan för tillgängliga kodekar till listan för aktiva kodekar. Move a codec from the list of active codecs to the list of available codecs. Flytta en kodek frÃ¥n listan för aktiva kodekar till listan för tillgängliga kodekar. Active codecs: Aktiva kodekar: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. &G.711/G.726 payload size: The preferred payload size for the G.711 and G.726 codecs. ms ms &Follow codec preference from far end on incoming calls Alt+F <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. Follow codec &preference from far end on outgoing calls Alt+P Alt+P <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. &iLBC &iLBC iLBC iLBC i&LBC payload type: iLBC &payload size (ms): The dynamic type value (96 or higher) to be used for iLBC. 20 20 30 30 The preferred payload size for iLBC. &Speex &Speex Speex Speex Perceptual &enhancement Alt+E Alt+R Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). &Ultra wide band payload type: &VAD &VAD Alt+V Alt+V &Wide band payload type: V&BR V&BR Alt+B Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. The dynamic type value (96 or higher) to be used for speex wide band. Co&mplexity: DT&X DT&X Alt+X Alt+X Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. The dynamic type value (96 or higher) to be used for speex narrow band. With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. &Narrow band payload type: G.726 G.726 G.726 &40 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 40 kbps. The dynamic type value (96 or higher) to be used for G.726 32 kbps. G.726 &24 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 24 kbps. G.726 &32 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 16 kbps. G.726 &16 kbps payload type: Codeword &packing order: RFC 3551 RFC 3551 ATM AAL2 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. DT&MF DT&MF DTMF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). DTMF vo&lume: The power level of the DTMF tone in dB. The pause after a DTMF tone. DTMF &duration: DTMF payload &type: DTMF &pause: dB dB Duration of a DTMF tone. DTMF t&ransport: DTMF-t&ransport: Auto Auto RFC 2833 RFC 2833 Inband Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> General Allmänt Protocol options Protokollalternativ Call &Hold variant: RFC 2543 RFC 2543 RFC 3264 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. Allow m&issing Contact header in 200 OK on REGISTER Alt+I Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. &Max-Forwards header is mandatory Alt+M Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Put &registration expiry time in contact header Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. &Use compact header names Indicates if compact header names should be used for headers that have a compact form. Allow SDP change during call setup <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> Use domain &name to create a unique contact header value Alt+N <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> &Encode Via, Route, Record-Route as list The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. Redirection &Allow redirection Alt+A Alt+B Indicates if Twinkle should redirect a request if a 3XX response is received. Ask user &permission to redirect Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Max re&directions: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. SIP extensions disabled inaktiverad supported stöds required krävs preferred föredras Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. &100 rel (PRACK): Replaces Ersätter Indicates if the Replaces-extenstion is supported. REFER REFER Call transfer (REFER) Alt+T Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. As&k user permission to transfer Alt+K Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Hold call &with referrer while setting up call to transfer target Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Ho&ld call with referee before sending REFER Alt+L Alt+T Indicates if Twinkle should put the current call on hold when you transfer a call. Auto re&fresh subscription to refer event while call transfer is not finished While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. Attended refer to AoR (Address of Record) An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. Privacy Integritet Privacy options Integritetsalternativ &Send P-Preferred-Identity header when hiding user identity Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. NAT traversal NAT-traversering &NAT traversal not needed Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. &Use statically configured public IP address inside SIP messages Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Choose this option when your SIP provider offers a STUN server for NAT traversal. S&TUN server: S&TUN-server: The hostname, domain name or IP address of the STUN server. Värdnamnet, domännamnet eller IP-adressen för STUN-servern. &Public IP address: &Publik IP-adress: The public IP address of your NAT. Telephone numbers Telefonnummer Only &display user part of URI for telephone number If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. &URI with numerical user part is a telephone number If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. &Remove special symbols from numerical dial strings Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. &Special symbols: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. Number conversion Match expression Replace Ersätt <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> Move the selected number conversion rule upwards in the list. Move the selected number conversion rule downwards in the list. &Add &Lägg till Add a number conversion rule. Re&move Ta &bort Remove the selected number conversion rule. &Edit &Redigera Edit the selected number conversion rule. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. &Test &Testa Test how a number is converted by the number conversion rules. for STUN för STUN When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". NAT &keep alive: &No answer: &Inget svar: Ring &back tone: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> &Ring tone: &Ringsignal: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Call released locall&y: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Outgoing call a&nswered: Incoming call &failed: &Incoming call: &Inkommande samtal: Call released &remotely: Incoming call &answered: O&utgoing call: &UtgÃ¥ende samtal: Out&going call failed: &Enable ZRTP/SRTP encryption &Aktivera ZRTP/SRTP-kryptering When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. ZRTP settings Inställningar för ZRTP O&nly encrypt audio if remote party indicated ZRTP support in SDP A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. &Indicate ZRTP support in SDP Twinkle will indicate ZRTP support during call setup in its signalling. &Popup warning when remote party disables encryption during call A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. &Voice mail address: The SIP address or telephone number to access your voice mail. Unsollicited Sollicited <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> &MWI type: Sollicited MWI Subscription &duration: Mailbox &user name: The hostname, domain name or IP address of your voice mailbox server. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Your user name for accessing your voice mailbox. Mailbox &server: Via outbound &proxy Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. Dynamic payload type %1 is used more than once. You must fill in a user name for your SIP account. Du mÃ¥ste fylla i ett användarnamn för ditt SIP-konto. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Du mÃ¥ste fylla i ett domännamn för ditt SIP-konto. Detta kan vara värdnamnet eller IP-adressen för din dator, om du vill ha direktsamtal, PC till PC. Invalid domain. Ogiltig domän. Invalid user name. Ogiltigt användarnamn. Invalid value for registrar. Invalid value for outbound proxy. You must fill in a mailbox user name. You must fill in a mailbox server Invalid mailbox server. Invalid mailbox user name. Value for public IP address missing. Invalid value for STUN server. Ogiltigt värde för STUN-server. Ring tones Description of .wav files in file dialog Ringsignaler Choose ring tone Välj ringsignal Ring back tones Description of .wav files in file dialog All files Alla filer Choose incoming call script Choose incoming call answered script Choose incoming call failed script Choose outgoing call script Choose outgoing call answered script Choose outgoing call failed script Choose local release script Choose remote release script Instant message Snabbmeddelande Presence Närvaro Transport/NAT Transport/NAT AKA AM&F AKA AM&F A&KA OP: A&KA OP: Authentication management field for AKAv1-MD5 authentication. Operator variant key for AKAv1-MD5 authentication. Add q-value to registration The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. SIP transport SIP-transport UDP UDP TCP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. T&ransport protocol: T&ransportprotokoll: UDP t&hreshold: bytes byte Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. Use &STUN (does not work for incoming TCP) P&ersistent TCP connection Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. Use tel-URI for telephone &number Expand a dialed telephone number to a tel-URI instead of a sip-URI. Select ring back tone file. Select ring tone file. Select script file. &Maximum number of sessions: When you have this number of instant message sessions open, new incoming message sessions will be rejected. &Send composing indications when typing a message. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. Your presence Din närvaro &Publish availability at startup &Publicera tillgänglighet vid uppstart Publish your availability at startup. Publicera din tillgänglighet vid uppstart. Publication &refresh interval (sec): Refresh rate of presence publications. Buddy presence &Subscription refresh interval (sec): Refresh rate of presence subscriptions. %1 converts to %2 %1 konverteras till %2 AKA AM&F: Prepr&ocessing Preprocessing (improves quality at remote end) &Automatic gain control Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Automatic gain control &level: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. &Voice activity detection When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. &Noise reduction The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. Acoustic &Echo Cancellation In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Variable &bit-rate Discontinuous &Transmission &Quality: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. Accept call &transfer request (incoming REFER) Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. bytes Enable NAT &keep alive Send UDP NAT keep alive packets. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. WizardForm Twinkle - Wizard Twinkle - Guide The hostname, domain name or IP address of the STUN server. Värdnamnet, domännamnet eller IP-adressen för STUN-servern. S&TUN server: S&TUN-server: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. SIP-användarnamnet som din leverantör levererat till dig. Detta är användardelen av din SIP-adress, <b>användarnamn</b>@domän.se. Detta kan vara ett telefonnummer. <br><br> Detta fält är obligatoriskt. &Domain*: &Domän*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. Välj din SIP-tjänsteleverantör. Om din SIP-tjänsteleverantör inte finns med i listan sÃ¥ ska du välja <b>Annan</b> och fylla i inställningarna som du fÃ¥tt frÃ¥n din leverantör.<br><br> Om du väljer en av de fördefinierade SIP-tjänsteleverantörerna sÃ¥ behöver du endast fylla i ditt namn, användarnamn, autentiseringsnamn och lösenord. &Authentication name: &Autentiseringsnamn: &Your name: &Ditt namn: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Ditt SIP-autentiseringsnamn. Ganska ofta är detta samma som ditt SIP-användarnamn. Det kan dock skilja sig. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. Domändelen av din SIP-adress, användarnamn@<b>domän.se</b>. Istället för en riktig domän sÃ¥ kan detta även vara värdnamnet eller IP-adressen för din <b>SIP-proxy</b>. Om du vill använda direktkommunikation mellan IP-telefon och IP-telefon sÃ¥ kan du fylla i värdnamnet eller IP-adress för din dator. <br><br> Detta fält är obligatoriskt. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. Detta är helt enkelt ditt fullständiga namn, t.ex. Sven Svensson. Det används endast för visning. När du ringer ett samtal kan dock detta namn visas för motparten. SIP pro&xy: SIP-pro&xy: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. Värdnamnet, domännamnet eller IP-adressen för din SIP-proxy. Om detta är samma värde som för din domän sÃ¥ kan du lämna detta fält tomt. &SIP service provider: &SIP-tjänsteleverantör: &Password: &Lösenord: &User name*: A&nvändarnamn*: Your password for authentication. Ditt lösenord för autentisering. &OK &OK Alt+O Alt+O &Cancel &Avbryt Alt+C Alt+A None (direct IP to IP calls) Ingen (direktsamtal IP till IP) Other Annan User profile wizard: Guide för användarprofil: You must fill in a user name for your SIP account. Du mÃ¥ste fylla i ett användarnamn för ditt SIP-konto. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Du mÃ¥ste fylla i ett domännamn för ditt SIP-konto. Detta kan vara värdnamnet eller IP-adressen för din dator, om du vill ha direktsamtal, PC till PC. Invalid value for SIP proxy. Ogiltigt värde för SIP-proxy. Invalid value for STUN server. Ogiltigt värde för STUN-server. YesNoDialog &Yes &Ja &No &Nej twinkle-1.4.2/src/gui/lang/twinkle_xx.ts0000644000175000001440000063644311151060225015161 00000000000000 AddressCardForm Twinkle - Address Card &Remark: Infix name of contact. First name of contact. &First name: You may place any remark about the contact here. &Phone: &Infix name: Phone number or SIP address of contact. Last name of contact. &Last name: &OK Alt+O &Cancel Alt+C You must fill in a name. You must fill in a phone number or SIP address. AuthenticationForm Twinkle - Authentication user No need to translate The user for which authentication is requested. profile No need to translate The user profile of the user for which authentication is requested. User profile: User: &Password: Your password for authentication. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. &User name: &OK &Cancel Login required for realm: realm No need to translate The realm for which you need to authenticate. BuddyForm Twinkle - Buddy Address book Select an address from the address book. &Phone: Name of your buddy. &Show availability Alt+S Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. &Name: SIP address your buddy. &OK Alt+O &Cancel Alt+C You must fill in a name. Invalid phone. Failed to save buddy list: %1 BuddyList Availability unknown offline online request failed request rejected not published failed to publish Click right to add a buddy. CoreAudio Failed to open sound card Failed to create a UDP socket (RTP) on port %1 Failed to create audio receiver thread. Failed to create audio transmitter thread. CoreCallHistory local user remote user failure unknown in out DeregisterForm Twinkle - Deregister deregister all devices &OK &Cancel DiamondcardProfileForm Twinkle - Diamondcard User Profile Your Diamondcard account ID. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. &Account ID: &PIN code: &Your name: <p align="center"><u>Sign up for a Diamondcard account</u></p> &OK Alt+O &Cancel Alt+C Fill in your account ID. Fill in your PIN code. A user profile with name %1 already exists. Your Diamondcard PIN code. <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> DtmfForm Twinkle - DTMF Keypad 2 3 Over decadic A. Normally not needed. 4 5 6 Over decadic B. Normally not needed. 7 8 9 Over decadic C. Normally not needed. Star (*) 0 Pound (#) Over decadic D. Normally not needed. 1 &Close Alt+C FreeDeskSysTray Show/Hide Quit GUI Failed to create a %1 socket (SIP) on port %2 Override lock file and start anyway? The following profiles are both for user %1 You can only run multiple profiles for different users. If these are users for different domains, then enable the following option in your user profile (SIP protocol) Use domain name to create a unique contact header Cannot find a network interface. Twinkle will use 127.0.0.1 as the local IP address. When you connect to the network you have to restart Twinkle to use the correct IP address. Line %1: incoming call for %2 Call transferred by %1 Line %1: far end cancelled call. Line %1: far end released call. Line %1: SDP answer from far end not supported. Line %1: SDP answer from far end missing. Line %1: Unsupported content type in answer from far end. Line %1: no ACK received, call will be terminated. Line %1: no PRACK received, call will be terminated. Line %1: PRACK failed. Line %1: failed to cancel call. Line %1: far end answered call. Line %1: call failed. The call can be redirected to: Line %1: call released. Line %1: call established. Response on terminal capability request: %1 %2 Terminal capabilities of %1 Accepted body types: unknown Accepted encodings: Accepted languages: Allowed requests: Supported extensions: none End point type: Line %1: call retrieve failed. %1, registration failed: %2 %3 %1, registration succeeded (expires = %2 seconds) %1, registration failed: STUN failure %1, de-registration succeeded: %2 %3 %1, de-registration failed: %2 %3 %1, fetching registrations failed: %2 %3 : you are not registered : you have the following registrations : fetching registrations... Line %1: redirecting request to Redirecting request to: %1 Line %1: DTMF detected: invalid DTMF telephone event (%1) Line %1: send DTMF %2 Line %1: far end does not support DTMF telephone events. Line %1: received notification. Event: %1 State: %1 Reason: %1 Progress: %1 %2 Line %1: call transfer failed. Line %1: call succesfully transferred. Line %1: call transfer still in progress. No further notifications will be received. Line %1: transferring call to %2 Transfer requested by %1 Line %1: Call transfer failed. Retrieving original call. %1, STUN request failed: %2 %3 %1, STUN request failed. Redirecting call User profile: User: Do you allow the call to be redirected to the following destination? If you don't want to be asked this anymore, then you must change the settings in the SIP protocol section of the user profile. Redirecting request Do you allow the %1 request to be redirected to the following destination? Transferring call Request to transfer call received from: Request to transfer call received. Do you allow the call to be transferred to the following destination? Info: Warning: Critical: Firewall / NAT discovery... Abort Line %1 Click the padlock to confirm a correct SAS. The remote user on line %1 disabled the encryption. Line %1: SAS confirmed. Line %1: SAS confirmation reset. %1, voice mail status failure. %1, voice mail status rejected. %1, voice mailbox does not exist. %1, voice mail status terminated. Accepted by network Line %1: call rejected. Line %1: call redirected. Failed to start conference. Failed to save message attachment: %1 Transferred by: %1 Cannot open web browser: %1 Configure your web browser in the system settings. GetAddressForm Twinkle - Select address &KAddressBook Name Type Phone This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. &Show only SIP addresses Alt+S Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". &Reload Alt+R Reload the list of addresses from KAddressbook. &Local address book Remark Contacts in the local address book of Twinkle. &Add Alt+A Add a new contact to the local address book. &Delete Alt+D Delete a contact from the local address book. &Edit Alt+E Edit a contact from the local address book. &OK Alt+O &Cancel Alt+C <p>You seem not to have any contacts with a phone number in <b>KAddressBook</b>, KDE's address book application. Twinkle retrieves all contacts with a phone number from KAddressBook. To manage your contacts you have to use KAddressBook.<p>As an alternative you may use Twinkle's local address book.</p> GetProfileNameForm Twinkle - Profile name &OK &Cancel Enter a name for your profile: <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> Cannot find .twinkle directory in your home directory. Profile already exists. Rename profile '%1' to: HistoryForm Twinkle - Call History Time In/Out From/To Subject Status Call details Details of the selected call record. View &Incoming calls Alt+I Check this option to show incoming calls. &Outgoing calls Alt+O Check this option to show outgoing calls. &Answered calls Alt+A Check this option to show answered calls. &Missed calls Alt+M Check this option to show missed calls. Current &user profiles only Alt+U Check this option to show only calls associated with this user profile. C&lear Alt+L <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> Clo&se Alt+S Close this window. &Call Alt+C Call selected address. Call... Delete Call start: Call answer: Call end: Call duration: Direction: From: To: Reply to: Referred by: Subject: Released by: Status: Far end device: User profile: conversation Re: Number of calls: ### Total call duration: InviteForm Twinkle - Call &To: Optionally you can provide a subject here. This might be shown to the callee. Address book Select an address from the address book. The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. The user that will make the call. &Subject: &From: &Hide identity Alt+H <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> &OK &Cancel Not all SIP providers support identity hiding. Make sure your SIP provider supports it if you really need it. F10 LogViewForm Twinkle - Log Contents of the current log file (~/.twinkle/twinkle.log) &Close Alt+C C&lear Alt+L Clear the log window. This does <b>not</b> clear the log file itself. MessageForm Twinkle - Instant message &To: The user that will send the message. The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book Select an address from the address book. &User profile: Conversation Type your message here and then press "send" to send it. &Send Alt+S Send the message. Delivery failure Delivery notification Instant message toolbar Send file... Send file image size is scaled down in preview Open with %1... Open with... Save attachment as... File already exists. Do you want to overwrite this file? Failed to save attachment. %1 is typing a message. F10 Size MessageFormView sending message MphoneForm Twinkle Buddy list You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. &Call: Label in front of combobox to enter address The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book Select an address from the address book. Dial Dial the address. &User: The user that will make the call. Auto answer indication. Call redirect indication. Do not disturb indication. Message waiting indication. Missed call indication. Registration status. Display Line status Line &1: Alt+1 Click to switch to line 1. From: To: Subject: Visual indication of line state. idle No need to translate Call is on hold Voice is muted Conference call Transferring call <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> sas No need to translate Short authentication string g711a/g711a No need to translate Audio codec 0:00:00 Call duration sip:from No need to translate sip:to No need to translate subject No need to translate photo No need to translate Line &2: Alt+2 Click to switch to line 2. &File &Edit C&all Activate line &Message &Registration &Services &View &Help Call Toolbar Quit &Quit Ctrl+Q About Twinkle &About Twinkle Call toolbar text &Call... call menu text Call someone F5 Answer toolbar text &Answer menu text Answer incoming call F6 Bye toolbar text &Bye menu text Release call Esc Reject toolbar text &Reject menu text Reject incoming call F8 Hold toolbar text &Hold menu text Put a call on hold, or retrieve a held call Redirect toolbar text R&edirect... menu text Redirect incoming call without answering Dtmf toolbar text &Dtmf... menu text Open keypad to enter digits for voice menu's Register &Register Deregister &Deregister Deregister this device Show registrations &Show registrations Terminal capabilities &Terminal capabilities... menu text Request terminal capabilities from someone Do not disturb &Do not disturb Call redirection Call &redirection... Redial toolbar text &Redial menu text Repeat last call F12 About Qt About &Qt User profile &User profile... Conf toolbar text &Conference menu text Join two calls in a 3-way conference Mute toolbar text &Mute menu text Mute a call Xfer toolbar text Trans&fer... menu text Transfer call System settings &System settings... Deregister all Deregister &all Deregister all your registered devices Auto answer &Auto answer Log &Log... Call history Call &history... F9 Change user ... &Change user ... Activate or de-activate users What's This? What's &This? Shift+F1 Line 1 Line 2 &Display Voice mail &Voice mail Access voice mail F11 Msg Instant &message... Instant message &Buddy list &Call... &Edit... &Delete O&ffline &Online &Change availability &Add buddy... idle dialing attempting call, please wait incoming call establishing call, please wait established established (waiting for media) releasing call, please wait unknown state Voice is encrypted Click to confirm SAS. Click to clear SAS verification. Transfer consultation User: Call: Hide identity Registration status: Registered Failed Not registered Click to show registrations. No users are registered. %1 new, 1 old message %1 new, %2 old messages 1 new message %1 new messages 1 old message %1 old messages Messages waiting No messages <b>Voice mail status:</b> Failure Unknown Click to access voice mail. Do not disturb active for: Redirection active for: Auto answer active for: Click to activate/deactivate Click to activate Do not disturb is not active. Redirection is not active. Auto answer is not active. Click to see call history for details. You have no missed calls. You missed 1 call. You missed %1 calls. Starting user profiles... The following profiles are both for user %1 You can only run multiple profiles for different users. You have changed the SIP UDP port. This setting will only become active when you restart Twinkle. not provisioned You must provision your voice mail address in your user profile, before you can access it. The line is busy. Cannot access voice mail. The voice mail address %1 is an invalid address. Please provision a valid address in your user profile. Failed to save buddy list: %1 F10 Diamondcard Manual &Manual Sign up &Sign up... Recharge... Balance history... Call history... Admin center... Recharge Balance history Admin center NumberConversionForm Twinkle - Number conversion &Match expression: &Replace: Perl style format string for the replacement number. Perl style regular expression matching the number format you want to modify. &OK Alt+O &Cancel Alt+C Match expression may not be empty. Replace value may not be empty. Invalid regular expression. RedirectForm Twinkle - Redirect Redirect incoming call to You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. &3rd choice destination: &2nd choice destination: &1st choice destination: Address book Select an address from the address book. &OK &Cancel F10 F12 F11 SelectNicForm Twinkle - Select NIC Select the network interface/IP address that you want to use: You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. Set as default &IP Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. Set as default &NIC Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. &OK Alt+O If you want to remove or change the default at a later time, you can do that via the system settings. SelectProfileForm Twinkle - Select user profile Select user profile(s) to run: User profile Tick the check boxes of the user profiles that you want to run and press run. Create a new profile with the profile editor. &Wizard Alt+W Create a new profile with the wizard. &Edit Alt+E Edit the highlighted profile. &Delete Alt+D Delete the highlighted profile. Ren&ame Alt+A Rename the highlighted profile. &Set as default Alt+S Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. &Run Alt+R Run Twinkle with the selected profiles. S&ystem settings Alt+Y Edit the system settings. &Cancel Alt+C <html>Before you can use Twinkle, you must create a user profile.<br>Click OK to create a profile.</html> &Profile editor <html>Next you may adjust the system settings. You can change these settings always at a later time.<br><br>Click OK to view and adjust the system settings.</html> You did not select any user profile to run. Please select a profile. Are you sure you want to delete profile '%1'? Delete profile Failed to delete profile. Failed to rename profile. <p>If you want to remove or change the default at a later time, you can do that via the system settings.</p> Cannot find .twinkle directory in your home directory. Create profile Ed&itor Alt+I Dia&mondcard Alt+M Modify profile Startup profile &Diamondcard Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. <html>You can use the profile editor to create a profile. With the profile editor you can change many settings to tune the SIP protocol, RTP and many other things.<br><br>Alternatively you can use the wizard to quickly setup a user profile. The wizard asks you only a few essential settings. If you create a user profile with the wizard you can still edit the full profile with the profile editor at a later time.<br><br>You can create a Diamondcard account to make worldwide calls to regular and cell phones and send SMS messages.<br><br>Choose what method you wish to use.</html> SelectUserForm Twinkle - Select user &Cancel Alt+C &Select all Alt+S &OK Alt+O C&lear all Alt+L purpose No need to translate User Register Select users that you want to register. Deregister Select users that you want to deregister. Deregister all devices Select users for which you want to deregister all devices. Do not disturb Select users for which you want to enable 'do not disturb'. Auto answer Select users for which you want to enable 'auto answer'. SendFileForm Twinkle - Send File Select file to send. &File: &Subject: &OK Alt+O &Cancel Alt+C File does not exist. Send file... SrvRedirectForm Twinkle - Call Redirection User: There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> &Unconditional &Redirect all calls Alt+R Activate the unconditional redirection service. Redirect to You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. &3rd choice destination: &2nd choice destination: &1st choice destination: Address book Select an address from the address book. &Busy &Redirect calls when I am busy Activate the redirection when busy service. &No answer &Redirect calls when I do not answer Activate the redirection on no answer service. &OK Alt+O Accept and save all changes. &Cancel Alt+C Undo your changes and close the window. You have entered an invalid destination. F10 F11 F12 SysSettingsForm Twinkle - System Settings General Audio Ring tones Address book Network Log Select a category for which you want to see or modify the settings. &OK Alt+O Accept and save your changes. &Cancel Alt+C Undo all your changes and close the window. Sound Card Select the sound card for playing the ring tone for incoming calls. Select the sound card to which your microphone is connected. Select the sound card for the speaker function during a call. &Speaker: &Ring tone: Other device: &Microphone: &Validate devices before usage Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. Advanced OSS &fragment size: 16 32 64 128 256 The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. ALSA &play period size: &ALSA capture period size: The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. &Max log size: The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. MB Log &debug reports Alt+D Indicates if reports marked as "debug" will be logged. Log &SIP reports Alt+S Indicates if SIP messages will be logged. Log S&TUN reports Alt+T Indicates if STUN messages will be logged. Log m&emory reports Alt+E Indicates if reports concerning memory management will be logged. System tray Create &system tray icon on startup Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. &Hide in system tray when closing main window Alt+H Enable this option if you want Twinkle to hide in the system tray when you close the main window. Startup S&tartup hidden in system tray Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. Default user profiles If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. Services Call &waiting Alt+W With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. Hang up &both lines when ending a 3-way conference call. Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. &Maximum calls in call history: The maximum number of calls that will be kept in the call history. &Auto show main window on incoming call after Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. Number of seconds after which the main window should be shown. secs Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. &SIP port: &RTP port: Max. SIP message size (&TCP): The UDP/TCP port used for sending and receiving SIP messages. Max. SIP message size (&UDP): Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. Ring tone &Play ring tone on incoming call Alt+P Indicates if a ring tone should be played when a call comes in. &Default ring tone Play the default ring tone when a call comes in. C&ustom ring tone Alt+U Play a custom ring tone when a call comes in. Specify the file name of a .wav file that you want to be played as ring tone. Select ring tone file. Ring back tone P&lay ring back tone when network does not play ring back tone Alt+L <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> D&efault ring back tone Play the default ring back tone. Cu&stom ring back tone Play a custom ring back tone. Specify the file name of a .wav file that you want to be played as ring back tone. Select ring back tone file. &Lookup name for incoming call On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. Ove&rride received display name Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. Lookup &photo for incoming call Lookup the photo of a caller in your address book and display it on an incoming call. Ring tones Description of .wav files in file dialog Choose ring tone Ring back tones Description of .wav files in file dialog Choose ring back tone W&eb browser command: Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. SysTrayPopup Answer Reject Incoming Call TermCapForm Twinkle - Terminal Capabilities &From: Get terminal capabilities of &To: The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book Select an address from the address book. &OK &Cancel F10 TransferForm Twinkle - Transfer Transfer call to &To: The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. Address book Select an address from the address book. Type of transfer &Blind transfer Alt+B Transfer the call to a third party without contacting that third party yourself. T&ransfer with consultation Alt+R Before transferring the call to a third party, first consult the party yourself. Transfer to other &line Alt+L Connect the remote party on the active line with the remote party on the other line. &OK Alt+O &Cancel F10 TwinkleCore Anonymous Warning: Failed to create log file %1 . Cannot open file for reading: %1 File system error while reading file %1 . Cannot open file for writing: %1 File system error while writing file %1 . Excessive number of socket errors. Built with support for: Contributions: This software contains the following software from 3rd parties: * GSM codec from Jutta Degener and Carsten Bormann, University of Berlin * G.711/G.726 codecs from Sun Microsystems (public domain) * iLBC implementation from RFC 3951 (www.ilbcfreeware.org) * Parts of the STUN project at http://sourceforge.net/projects/stun * Parts of libsrv at http://libsrv.sourceforge.net/ For RTP the following dynamic libraries are linked: Translated to english by <your name> Directory %1 does not exist. Cannot open file %1 . %1 is not set to your home directory. Directory %1 (%2) does not exist. Cannot create directory %1 . %1 is already running. Lock file %2 already exists. Cannot create %1 . Syntax error in file %1 . Failed to backup %1 to %2 unknown name (device is busy) Default device Cannot access the ring tone device (%1). Cannot access the speaker (%1). Cannot access the microphone (%1). Cannot receive incoming TCP connections. Call transfer - %1 Sound card cannot be set to full duplex. Cannot set buffer size on sound card. Sound card cannot be set to %1 channels. Cannot set sound card to 16 bits recording. Cannot set sound card to 16 bits playing. Cannot set sound card sample rate to %1 Opening ALSA driver failed Cannot open ALSA driver for PCM playback Cannot open ALSA driver for PCM capture Cannot resolve STUN server: %1 You are behind a symmetric NAT. STUN will not work. Configure a public IP address in the user profile and create the following static bindings (UDP) in your NAT. public IP: %1 --> private IP: %2 (SIP signaling) public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP) Cannot reach the STUN server: %1 If you are behind a firewall then you need to open the following UDP ports. Port %1 (SIP signaling) Ports %1-%2 (RTP/RTCP) NAT type discovery via STUN failed. Failed to create file %1 Failed to write data to file %1 Failed to send message. Cannot lock %1 . UserProfileForm Twinkle - User Profile User profile: Select which profile you want to edit. User SIP server Voice mail Instant message Presence RTP audio SIP protocol Transport/NAT Address format Timers Ring tones Scripts Security Select a category for which you want to see or modify the settings. &OK Alt+O Accept and save your changes. &Cancel Alt+C Undo all your changes and close the window. SIP account &User name*: &Domain*: Or&ganization: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. You may fill in the name of your organization. When you make a call, this might be shown to the called party. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. &Your name: SIP authentication &Realm: Authentication &name: &Password: The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. Your password for authentication. Registrar &Registrar: The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. &Expiry: The registration expiry time that Twinkle will request. seconds Re&gister at startup Alt+G Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. Add q-value to registration The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. Outbound Proxy &Use outbound proxy Alt+U Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. Outbound &proxy: &Send in-dialog requests to proxy Alt+S SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. &Don't send a request to proxy if its destination can be resolved locally. Alt+D When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) The hostname, domain name or IP address of your outbound proxy. Co&decs Codecs Available codecs: G.711 A-law G.711 u-law GSM speex-nb (8 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) List of available codecs. Move a codec from the list of available codecs to the list of active codecs. Move a codec from the list of active codecs to the list of available codecs. Active codecs: List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. Move a codec upwards in the list of active codecs, i.e. increase its preference of use. Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. &G.711/G.726 payload size: The preferred payload size for the G.711 and G.726 codecs. ms &Follow codec preference from far end on incoming calls Alt+F <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. Follow codec &preference from far end on outgoing calls Alt+P <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. &iLBC iLBC i&LBC payload type: iLBC &payload size (ms): The dynamic type value (96 or higher) to be used for iLBC. 20 30 The preferred payload size for iLBC. &Speex Speex Perceptual &enhancement Alt+E Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). &Ultra wide band payload type: Alt+V &Wide band payload type: Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. The dynamic type value (96 or higher) to be used for speex wide band. Co&mplexity: Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. The dynamic type value (96 or higher) to be used for speex narrow band. With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. &Narrow band payload type: G.726 G.726 &40 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 40 kbps. The dynamic type value (96 or higher) to be used for G.726 32 kbps. G.726 &24 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 24 kbps. G.726 &32 kbps payload type: The dynamic type value (96 or higher) to be used for G.726 16 kbps. G.726 &16 kbps payload type: Codeword &packing order: RFC 3551 ATM AAL2 There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. DT&MF DTMF The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). DTMF vo&lume: The power level of the DTMF tone in dB. The pause after a DTMF tone. DTMF &duration: DTMF payload &type: DTMF &pause: dB Duration of a DTMF tone. DTMF t&ransport: Auto RFC 2833 Inband Out-of-band (SIP INFO) <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> General Protocol options Call &Hold variant: RFC 2543 RFC 3264 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. Allow m&issing Contact header in 200 OK on REGISTER Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. &Max-Forwards header is mandatory Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. Put &registration expiry time in contact header Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. &Use compact header names Indicates if compact header names should be used for headers that have a compact form. Allow SDP change during call setup <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> Use domain &name to create a unique contact header value Alt+N <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> &Encode Via, Route, Record-Route as list The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. Redirection &Allow redirection Alt+A Indicates if Twinkle should redirect a request if a 3XX response is received. Ask user &permission to redirect Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. Max re&directions: The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. SIP extensions disabled supported required preferred Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. &100 rel (PRACK): Replaces Indicates if the Replaces-extenstion is supported. REFER Call transfer (REFER) Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. As&k user permission to transfer Alt+K Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. Hold call &with referrer while setting up call to transfer target Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. Ho&ld call with referee before sending REFER Alt+L Indicates if Twinkle should put the current call on hold when you transfer a call. Auto re&fresh subscription to refer event while call transfer is not finished While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. Attended refer to AoR (Address of Record) An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. Privacy Privacy options &Send P-Preferred-Identity header when hiding user identity Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. SIP transport UDP TCP Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. T&ransport protocol: UDP t&hreshold: Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. NAT traversal &NAT traversal not needed Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. &Use statically configured public IP address inside SIP messages Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. Use &STUN (does not work for incoming TCP) Choose this option when your SIP provider offers a STUN server for NAT traversal. S&TUN server: The hostname, domain name or IP address of the STUN server. &Public IP address: The public IP address of your NAT. Telephone numbers Only &display user part of URI for telephone number If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. &URI with numerical user part is a telephone number If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. &Remove special symbols from numerical dial strings Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. &Special symbols: The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. Number conversion Match expression Replace <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> Move the selected number conversion rule upwards in the list. Move the selected number conversion rule downwards in the list. &Add Add a number conversion rule. Re&move Remove the selected number conversion rule. &Edit Edit the selected number conversion rule. Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. &Test Test how a number is converted by the number conversion rules. When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". NAT &keep alive: &No answer: Select ring back tone file. Select ring tone file. Ring &back tone: <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> &Ring tone: <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Select script file. <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Call released locall&y: <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. Outgoing call a&nswered: Incoming call &failed: &Incoming call: Call released &remotely: Incoming call &answered: O&utgoing call: Out&going call failed: &Enable ZRTP/SRTP encryption When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. ZRTP settings O&nly encrypt audio if remote party indicated ZRTP support in SDP A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. &Indicate ZRTP support in SDP Twinkle will indicate ZRTP support during call setup in its signalling. &Popup warning when remote party disables encryption during call A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. &Voice mail address: The SIP address or telephone number to access your voice mail. Unsollicited Sollicited <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> &MWI type: Sollicited MWI Subscription &duration: Mailbox &user name: The hostname, domain name or IP address of your voice mailbox server. For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. Your user name for accessing your voice mailbox. Mailbox &server: Via outbound &proxy Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. &Maximum number of sessions: When you have this number of instant message sessions open, new incoming message sessions will be rejected. Your presence &Publish availability at startup Publish your availability at startup. Publication &refresh interval (sec): Refresh rate of presence publications. Buddy presence &Subscription refresh interval (sec): Refresh rate of presence subscriptions. Dynamic payload type %1 is used more than once. You must fill in a user name for your SIP account. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Invalid domain. Invalid user name. Invalid value for registrar. Invalid value for outbound proxy. You must fill in a mailbox user name. You must fill in a mailbox server Invalid mailbox server. Invalid mailbox user name. Value for public IP address missing. Invalid value for STUN server. Ring tones Description of .wav files in file dialog Choose ring tone Ring back tones Description of .wav files in file dialog All files Choose incoming call script Choose incoming call answered script Choose incoming call failed script Choose outgoing call script Choose outgoing call answered script Choose outgoing call failed script Choose local release script Choose remote release script %1 converts to %2 P&ersistent TCP connection Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. &Send composing indications when typing a message. Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. AKA AM&F: A&KA OP: Authentication management field for AKAv1-MD5 authentication. Operator variant key for AKAv1-MD5 authentication. Prepr&ocessing Preprocessing (improves quality at remote end) &Automatic gain control Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. Automatic gain control &level: Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. &Voice activity detection When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. &Noise reduction The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. Acoustic &Echo Cancellation In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. Variable &bit-rate Discontinuous &Transmission &Quality: Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. bytes Use tel-URI for telephone &number Expand a dialed telephone number to a tel-URI instead of a sip-URI. Accept call &transfer request (incoming REFER) Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. Enable NAT &keep alive Send UDP NAT keep alive packets. If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. WizardForm Twinkle - Wizard The hostname, domain name or IP address of the STUN server. S&TUN server: The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. &Domain*: Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. &Authentication name: &Your name: Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. SIP pro&xy: The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. &SIP service provider: &Password: &User name*: Your password for authentication. &OK Alt+O &Cancel Alt+C None (direct IP to IP calls) Other User profile wizard: You must fill in a user name for your SIP account. You must fill in a domain name for your SIP account. This could be the hostname or IP address of your PC if you want direct PC to PC dialing. Invalid value for SIP proxy. Invalid value for STUN server. YesNoDialog &Yes &No twinkle-1.4.2/src/gui/address_finder.cpp0000644000175000001440000000721711130735747015162 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "address_finder.h" #include "gui.h" #include "log.h" t_address_finder *t_address_finder::instance = NULL; t_mutex t_address_finder::mtx_instance; t_address_finder::t_address_finder() { #ifdef HAVE_KDE // Load KAddressbook asynchronously. An LDAP address book // may take a while to load completely. This should not block // an incoming call. For the first call it may happen that an // address cannot be found as loading is still in progress. // This is an inconvenience, but will not harm the call. abook = KABC::StdAddressBook::self(true); connect(abook, SIGNAL(addressBookChanged(AddressBook *)), this, SLOT(invalidate_cache())); log_file->write_report("Preload KAddressbook.", "t_address_finder::t_address_finder"); #endif } void t_address_finder::find_address(t_user *user_config, const t_url &u) { if (u == last_url) return; last_url = u; last_name.clear(); last_photo = QImage(); #ifdef HAVE_KDE for (KABC::AddressBook::Iterator i = abook->begin(); i != abook->end(); i++) { // Normalize url using number conversion rules t_url u_normalized(u); u_normalized.apply_conversion_rules(user_config); KABC::PhoneNumber::List phoneNrs = i->phoneNumbers(); for (KABC::PhoneNumber::List::iterator j = phoneNrs.begin(); j != phoneNrs.end(); j++) { QString phone = (*j).number(); string full_address = ui->expand_destination( user_config, phone.ascii(), u_normalized.get_scheme()); t_url url_phone(full_address); if (!url_phone.is_valid()) continue; if (u_normalized.user_host_match(url_phone, user_config->get_remove_special_phone_symbols(), user_config->get_special_phone_symbols())) { last_name = i->realName().ascii(); last_photo = i->photo().data(); last_photo.detach(); // avoid sharing of QImage with kabc return; } } } #endif } void t_address_finder::preload(void) { // The address book is preloaded on creation of the // singleton instance. (void)t_address_finder::get_instance(); } t_address_finder *t_address_finder::get_instance(void) { mtx_instance.lock(); if (!instance) { instance = new t_address_finder(); // No MEMMAN audit as this instance will only be // cleaned up by process termination. } mtx_instance.unlock(); return instance; } string t_address_finder::find_name(t_user *user_config, const t_url &u) { mtx_finder.lock(); find_address(user_config, u); string name = last_name; mtx_finder.unlock(); return name; } QImage t_address_finder:: find_photo(t_user *user_config, const t_url &u) { mtx_finder.lock(); find_address(user_config, u); QImage photo = last_photo; mtx_finder.unlock(); return photo; } void t_address_finder::invalidate_cache(void) { mtx_finder.lock(); last_url.set_url(""); mtx_finder.unlock(); log_file->write_report("Address finder cache invalidated.", " t_address_finder::invalidate_cache", LOG_NORMAL, LOG_DEBUG); } twinkle-1.4.2/src/gui/termcapform.ui.h0000644000175000001440000000535511127714044014600 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void TermCapForm::init() { getAddressForm = 0; // Set toolbutton icons for disabled options. setDisabledIcon(addressToolButton, "kontact_contacts-disabled.png"); } void TermCapForm::show(t_user *user_config, const QString &dest) { ((t_gui *)ui)->fill_user_combo(fromComboBox); // Select from user if (user_config) { for (int i = 0; i < fromComboBox->count(); i++) { if (fromComboBox->text(i) == user_config->get_profile_name().c_str()) { fromComboBox->setCurrentItem(i); break; } } } partyLineEdit->setText(dest); QDialog::show(); } void TermCapForm::destroy() { if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } } void TermCapForm::validate() { string display, dest_str; t_user *from_user = phone->ref_user_profile( fromComboBox->currentText().ascii()); ui->expand_destination(from_user, partyLineEdit->text().stripWhiteSpace().ascii(), display, dest_str); t_url dest(dest_str); if (dest.is_valid()) { emit destination(from_user, dest); accept(); } else { partyLineEdit->selectAll(); } } void TermCapForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); getAddressForm->show(); } void TermCapForm::selectedAddress(const QString &address) { partyLineEdit->setText(address); } twinkle-1.4.2/src/gui/redirectform.ui0000644000175000001440000003053411131205043014502 00000000000000 RedirectForm RedirectForm 0 0 588 190 5 5 0 0 Twinkle - Redirect unnamed redirectGroupBox Redirect incoming call to unnamed contact3LineEdit You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. contact3TextLabel &3rd choice destination: contact3LineEdit contact2TextLabel &2nd choice destination: contact2LineEdit contact2LineEdit You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. contact1LineEdit You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. contact1TextLabel &1st choice destination: contact1LineEdit address1ToolButton TabFocus F10 kontact_contacts.png Address book Select an address from the address book. address3ToolButton TabFocus F12 kontact_contacts.png Address book Select an address from the address book. address2ToolButton TabFocus F11 kontact_contacts.png Address book Select an address from the address book. spacer14 Vertical Expanding 20 16 layout15 unnamed spacer11 Horizontal Expanding 361 20 okPushButton &OK true cancelPushButton &Cancel cancelPushButton clicked() RedirectForm reject() okPushButton clicked() RedirectForm validate() address1ToolButton clicked() RedirectForm showAddressBook1() address2ToolButton clicked() RedirectForm showAddressBook2() address3ToolButton clicked() RedirectForm showAddressBook3() contact1LineEdit contact2LineEdit contact3LineEdit address1ToolButton address2ToolButton address3ToolButton okPushButton cancelPushButton gui.h audits/memman.h list sockets/url.h getaddressform.h user.h redirectform.ui.h GetAddressForm *getAddressForm; int nrAddressBook; t_user *user_config; destinations(const list<t_display_url> &) show( t_user * user, const list<string> & contacts ) validate() showAddressBook() showAddressBook1() showAddressBook2() showAddressBook3() selectedAddress( const QString & address ) init() destroy() twinkle-1.4.2/src/gui/Makefile0000644000175000001440000012515511151323500013123 00000000000000############################################################################# # Makefile for building: twinkle # Generated by qmake (1.07a) (Qt 3.3.7) on: Wed Feb 25 21:17:04 2009 # Project: twinkle.pro # Template: app # Command: $(QMAKE) -o Makefile twinkle.pro ############################################################################# ####### Compiler, tools and options CC = gcc CXX = g++ LEX = flex YACC = yacc CFLAGS = -pipe -march=i586 -mtune=i686 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -O2 -fno-strict-aliasing -Wall -W -march=i586 -mtune=i686 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -O2 -fno-strict-aliasing -D_REENTRANT -DQT_NO_STL -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED CXXFLAGS = -pipe -march=i586 -mtune=i686 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -O2 -fno-strict-aliasing -Wall -W -march=i586 -mtune=i686 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -O2 -fno-strict-aliasing -D_REENTRANT -DQT_NO_STL -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED LEXFLAGS = YACCFLAGS= -d INCPATH = -I/usr/lib/qt3/mkspecs/default -I. -I.. -I../../src -I/usr/local/include -I/usr/include/libxml2 -I/opt/kde3/include -I/usr/include -I$(QTDIR)/include -I.ui/ -I. -I.moc/ LINK = g++ LFLAGS = LIBS = -L/opt/kde3/lib $(SUBLIBS) -L/usr/lib/ -L$(QTDIR)/lib/ -L/usr/X11R6/lib/ ../libtwinkle.a ../parser/libsipparser.a ../sdp/libsdpparser.a ../sockets/libsocket.a ../threads/libthread.a ../audio/libaudio.a ../audits/libaudits.a ../stun/libstun.a ../mwi/libmwi.a ../im/libim.a ../patterns/libpatterns.a ../presence/libpresence.a ../utils/libutils.a -lsndfile -lmagic -lncurses -lreadline -L/usr/local/lib -lccext2 -pthread -lccrtp1 -lccgnu2 -ldl -lrt -lxml2 -lz -L/opt/kde3/lib -lkdecore -lkdeui -L/lib -lkabc -lresolv ../audio/gsm/libgsm.a -lasound -lspeex -lspeexdsp -lilbc -lzrtpcpp -lboost_regex -lqt-mt -lXext -lX11 -lm -lpthread AR = ar cqs RANLIB = MOC = $(QTDIR)/bin/moc UIC = $(QTDIR)/bin/uic QMAKE = qmake TAR = tar -cf GZIP = gzip -9f COPY = cp -f COPY_FILE= $(COPY) COPY_DIR = $(COPY) -r INSTALL_FILE= $(COPY_FILE) INSTALL_DIR = $(COPY_DIR) DEL_FILE = rm -f SYMLINK = ln -sf DEL_DIR = rmdir MOVE = mv -f CHK_DIR_EXISTS= test -d MKDIR = mkdir -p ####### Output directory OBJECTS_DIR = .obj/ ####### Files HEADERS = gui.h \ historylistview.h \ freedesksystray.h \ twinklesystray.h \ address_finder.h \ qt_translator.h \ core_strings.h \ addresslistviewitem.h \ yesnodialog.h \ command_args.h \ messageformview.h \ buddylistview.h \ textbrowsernoautolink.h \ twinkleapplication.h SOURCES = main.cpp \ gui.cpp \ historylistview.cpp \ freedesksystray.cpp \ twinklesystray.cpp \ address_finder.cpp \ addresslistviewitem.cpp \ yesnodialog.cpp \ messageformview.cpp \ buddylistview.cpp \ twinkleapplication.cpp OBJECTS = .obj/main.o \ .obj/gui.o \ .obj/historylistview.o \ .obj/freedesksystray.o \ .obj/twinklesystray.o \ .obj/address_finder.o \ .obj/addresslistviewitem.o \ .obj/yesnodialog.o \ .obj/messageformview.o \ .obj/buddylistview.o \ .obj/twinkleapplication.o \ .obj/mphoneform.o \ .obj/inviteform.o \ .obj/deregisterform.o \ .obj/redirectform.o \ .obj/termcapform.o \ .obj/dtmfform.o \ .obj/selectnicform.o \ .obj/srvredirectform.o \ .obj/authenticationform.o \ .obj/userprofileform.o \ .obj/selectprofileform.o \ .obj/getprofilenameform.o \ .obj/transferform.o \ .obj/syssettingsform.o \ .obj/logviewform.o \ .obj/wizardform.o \ .obj/getaddressform.o \ .obj/historyform.o \ .obj/selectuserform.o \ .obj/numberconversionform.o \ .obj/addresscardform.o \ .obj/messageform.o \ .obj/buddyform.o \ .obj/sendfileform.o \ .obj/diamondcardprofileform.o \ .obj/qmake_image_collection.o FORMS = mphoneform.ui \ inviteform.ui \ deregisterform.ui \ redirectform.ui \ termcapform.ui \ dtmfform.ui \ selectnicform.ui \ srvredirectform.ui \ authenticationform.ui \ userprofileform.ui \ selectprofileform.ui \ getprofilenameform.ui \ transferform.ui \ syssettingsform.ui \ logviewform.ui \ wizardform.ui \ getaddressform.ui \ historyform.ui \ selectuserform.ui \ numberconversionform.ui \ addresscardform.ui \ messageform.ui \ buddyform.ui \ sendfileform.ui \ diamondcardprofileform.ui UICDECLS = .ui/mphoneform.h \ .ui/inviteform.h \ .ui/deregisterform.h \ .ui/redirectform.h \ .ui/termcapform.h \ .ui/dtmfform.h \ .ui/selectnicform.h \ .ui/srvredirectform.h \ .ui/authenticationform.h \ .ui/userprofileform.h \ .ui/selectprofileform.h \ .ui/getprofilenameform.h \ .ui/transferform.h \ .ui/syssettingsform.h \ .ui/logviewform.h \ .ui/wizardform.h \ .ui/getaddressform.h \ .ui/historyform.h \ .ui/selectuserform.h \ .ui/numberconversionform.h \ .ui/addresscardform.h \ .ui/messageform.h \ .ui/buddyform.h \ .ui/sendfileform.h \ .ui/diamondcardprofileform.h UICIMPLS = .ui/mphoneform.cpp \ .ui/inviteform.cpp \ .ui/deregisterform.cpp \ .ui/redirectform.cpp \ .ui/termcapform.cpp \ .ui/dtmfform.cpp \ .ui/selectnicform.cpp \ .ui/srvredirectform.cpp \ .ui/authenticationform.cpp \ .ui/userprofileform.cpp \ .ui/selectprofileform.cpp \ .ui/getprofilenameform.cpp \ .ui/transferform.cpp \ .ui/syssettingsform.cpp \ .ui/logviewform.cpp \ .ui/wizardform.cpp \ .ui/getaddressform.cpp \ .ui/historyform.cpp \ .ui/selectuserform.cpp \ .ui/numberconversionform.cpp \ .ui/addresscardform.cpp \ .ui/messageform.cpp \ .ui/buddyform.cpp \ .ui/sendfileform.cpp \ .ui/diamondcardprofileform.cpp SRCMOC = .moc/moc_gui.cpp \ .moc/moc_freedesksystray.cpp \ .moc/moc_address_finder.cpp \ .moc/moc_yesnodialog.cpp \ .moc/moc_textbrowsernoautolink.cpp \ .moc/moc_mphoneform.cpp \ .moc/moc_inviteform.cpp \ .moc/moc_deregisterform.cpp \ .moc/moc_redirectform.cpp \ .moc/moc_termcapform.cpp \ .moc/moc_dtmfform.cpp \ .moc/moc_selectnicform.cpp \ .moc/moc_srvredirectform.cpp \ .moc/moc_authenticationform.cpp \ .moc/moc_userprofileform.cpp \ .moc/moc_selectprofileform.cpp \ .moc/moc_getprofilenameform.cpp \ .moc/moc_transferform.cpp \ .moc/moc_syssettingsform.cpp \ .moc/moc_logviewform.cpp \ .moc/moc_wizardform.cpp \ .moc/moc_getaddressform.cpp \ .moc/moc_historyform.cpp \ .moc/moc_selectuserform.cpp \ .moc/moc_numberconversionform.cpp \ .moc/moc_addresscardform.cpp \ .moc/moc_messageform.cpp \ .moc/moc_buddyform.cpp \ .moc/moc_sendfileform.cpp \ .moc/moc_diamondcardprofileform.cpp OBJMOC = .obj/moc_gui.o \ .obj/moc_freedesksystray.o \ .obj/moc_address_finder.o \ .obj/moc_yesnodialog.o \ .obj/moc_textbrowsernoautolink.o \ .obj/moc_mphoneform.o \ .obj/moc_inviteform.o \ .obj/moc_deregisterform.o \ .obj/moc_redirectform.o \ .obj/moc_termcapform.o \ .obj/moc_dtmfform.o \ .obj/moc_selectnicform.o \ .obj/moc_srvredirectform.o \ .obj/moc_authenticationform.o \ .obj/moc_userprofileform.o \ .obj/moc_selectprofileform.o \ .obj/moc_getprofilenameform.o \ .obj/moc_transferform.o \ .obj/moc_syssettingsform.o \ .obj/moc_logviewform.o \ .obj/moc_wizardform.o \ .obj/moc_getaddressform.o \ .obj/moc_historyform.o \ .obj/moc_selectuserform.o \ .obj/moc_numberconversionform.o \ .obj/moc_addresscardform.o \ .obj/moc_messageform.o \ .obj/moc_buddyform.o \ .obj/moc_sendfileform.o \ .obj/moc_diamondcardprofileform.o DIST = ../../qtccxxincl.pro \ twinkle.pro QMAKE_TARGET = twinkle DESTDIR = TARGET = twinkle first: all ####### Implicit rules .SUFFIXES: .c .o .cpp .cc .cxx .C .cpp.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .cc.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .cxx.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .C.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .c.o: $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< ####### Build rules all: Makefile $(TARGET) $(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS) mocables: $(SRCMOC) uicables: $(UICDECLS) $(UICIMPLS) $(MOC): ( cd $(QTDIR)/src/moc && $(MAKE) ) Makefile: twinkle.pro /usr/lib/qt3/mkspecs/default/qmake.conf ../../qtccxxincl.pro \ /usr/lib/qt3/lib/libqt-mt.prl $(QMAKE) -o Makefile twinkle.pro qmake: @$(QMAKE) -o Makefile twinkle.pro dist: @mkdir -p .obj/twinkle && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) .obj/twinkle/ && $(COPY_FILE) --parents lang/twinkle_nl.ts lang/twinkle_de.ts lang/twinkle_cs.ts lang/twinkle_fr.ts lang/twinkle_ru.ts lang/twinkle_sv.ts lang/twinkle_xx.ts .obj/twinkle/ && $(COPY_FILE) --parents images/filenew images/filesave images/print images/undo images/redo images/editcut images/editcopy images/editpaste images/searchfind images/invite.png images/answer.png images/bye.png images/reject.png images/redirect.png images/hold.png images/dtmf.png images/bye-disabled.png images/redial.png images/redial-disabled.png images/invite-disabled.png images/answer-disabled.png images/reject-disabled.png images/redirect-disabled.png images/hold-disabled.png images/dtmf-disabled.png images/penguin.png images/package_network.png images/kmix.png images/package_system.png images/yast_babelfish.png images/clock.png images/yast_PhoneTTOffhook.png images/penguin_big.png images/password.png images/kcmpci.png images/penguin-small.png images/conf.png images/conf-disabled.png images/mute.png images/mute-disabled.png images/twinkle16.png images/twinkle48.png images/twinkle32.png images/transfer-disabled.png images/transfer.png images/log.png images/dtmf-2.png images/dtmf-3.png images/dtmf-5.png images/dtmf-6.png images/dtmf-7.png images/dtmf-8.png images/dtmf-9.png images/dtmf-4.png images/dtmf-1.png images/dtmf-0.png images/dtmf-star.png images/dtmf-pound.png images/dtmf-a.png images/dtmf-b.png images/dtmf-c.png images/dtmf-d.png images/twinkle24.png images/exit.png images/kontact_contacts.png images/ok.png images/cancel.png images/1rightarrow.png images/1leftarrow-yellow.png images/editdelete.png images/kcmpci16.png images/kontact_contacts-disabled.png images/sys_auto_ans.png images/sys_auto_ans_dis.png images/sys_busy_estab.png images/sys_busy_estab_dis.png images/sys_busy_trans.png images/sys_busy_trans_dis.png images/sys_dnd.png images/sys_dnd_dis.png images/sys_idle.png images/sys_idle_dis.png images/sys_redir.png images/sys_redir_dis.png images/sys_services.png images/sys_services_dis.png images/sys_hold.png images/sys_hold_dis.png images/sys_mute.png images/sys_mute_dis.png images/network.png images/knotify.png images/fileopen.png images/fileopen-disabled.png images/cf.png images/auto_answer.png images/auto_answer-disabled.png images/cancel-disabled.png images/cf-disabled.png images/missed-disabled.png images/missed.png images/sys_missed.png images/sys_missed_dis.png images/twinkle16-disabled.png images/gear.png images/reg_failed-disabled.png images/reg_failed.png images/no-indication.png images/contexthelp.png images/settings.png images/reg-query.png images/log_small.png images/qt-logo.png images/1leftarrow.png images/1uparrow.png images/1downarrow.png images/kontact_contacts32.png images/encrypted.png images/sys_encrypted.png images/sys_encrypted_dis.png images/encrypted32.png images/encrypted-disabled.png images/stat_conference.png images/stat_established.png images/stat_outgoing.png images/stat_ringing.png images/stat_mute.png images/stat_established_nomedia.png images/encrypted_verified.png images/sys_encrypted_verified.png images/sys_encrypted_verified_dis.png images/consult-xfer.png images/mwi_new16.png images/mwi_none16.png images/mwi_none16_dis.png images/sys_mwi.png images/sys_mwi_dis.png images/mwi_none.png images/mwi_failure16.png images/presence_offline.png images/presence_online.png images/presence_failed.png images/presence_rejected.png images/presence_unknown.png images/edit16.png images/message.png images/edit.png images/buddy.png images/message32.png images/presence.png images/save_as.png images/attach.png images/mime_application.png images/mime_audio.png images/mime_image.png images/mime_text.png images/mime_video.png .obj/twinkle/ && $(COPY_FILE) --parents mphoneform.ui.h inviteform.ui.h deregisterform.ui.h redirectform.ui.h termcapform.ui.h dtmfform.ui.h selectnicform.ui.h srvredirectform.ui.h authenticationform.ui.h userprofileform.ui.h selectprofileform.ui.h getprofilenameform.ui.h transferform.ui.h syssettingsform.ui.h logviewform.ui.h wizardform.ui.h getaddressform.ui.h historyform.ui.h selectuserform.ui.h numberconversionform.ui.h addresscardform.ui.h messageform.ui.h buddyform.ui.h sendfileform.ui.h diamondcardprofileform.ui.h .obj/twinkle/ && ( cd `dirname .obj/twinkle` && $(TAR) twinkle.tar twinkle && $(GZIP) twinkle.tar ) && $(MOVE) `dirname .obj/twinkle`/twinkle.tar.gz . && $(DEL_FILE) -r .obj/twinkle mocclean: -$(DEL_FILE) $(OBJMOC) -$(DEL_FILE) $(SRCMOC) uiclean: -$(DEL_FILE) $(UICIMPLS) $(UICDECLS) yaccclean: lexclean: clean: mocclean uiclean -$(DEL_FILE) $(OBJECTS) -$(DEL_FILE) .ui/qmake_image_collection.cpp -$(DEL_FILE) *~ core *.core ####### Sub-libraries distclean: clean -$(DEL_FILE) $(TARGET) $(TARGET) FORCE: ####### Compile .obj/main.o: main.cpp .ui/mphoneform.h \ address_finder.h \ twinkleapplication.h \ gui.h \ qt_translator.h \ command_args.h \ .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/main.o main.cpp .obj/gui.o: gui.cpp gui.h \ .ui/authenticationform.h \ .ui/mphoneform.h \ .ui/selectnicform.h \ .ui/selectprofileform.h \ messageformview.h \ twinklesystray.h \ address_finder.h \ yesnodialog.h \ command_args.h \ .ui/messageform.h \ freedesksystray.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/gui.o gui.cpp .obj/historylistview.o: historylistview.cpp historylistview.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/historylistview.o historylistview.cpp .obj/freedesksystray.o: freedesksystray.cpp freedesksystray.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/freedesksystray.o freedesksystray.cpp .obj/twinklesystray.o: twinklesystray.cpp twinklesystray.h \ freedesksystray.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/twinklesystray.o twinklesystray.cpp .obj/address_finder.o: address_finder.cpp address_finder.h \ gui.h \ .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/address_finder.o address_finder.cpp .obj/addresslistviewitem.o: addresslistviewitem.cpp addresslistviewitem.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/addresslistviewitem.o addresslistviewitem.cpp .obj/yesnodialog.o: yesnodialog.cpp yesnodialog.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/yesnodialog.o yesnodialog.cpp .obj/messageformview.o: messageformview.cpp messageformview.h \ gui.h \ .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/messageformview.o messageformview.cpp .obj/buddylistview.o: buddylistview.cpp buddylistview.h \ gui.h \ .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/buddylistview.o buddylistview.cpp .obj/twinkleapplication.o: twinkleapplication.cpp twinkleapplication.h \ gui.h \ .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/twinkleapplication.o twinkleapplication.cpp .ui/mphoneform.h: mphoneform.ui .ui/dtmfform.h \ .ui/inviteform.h \ .ui/redirectform.h \ .ui/termcapform.h \ .ui/srvredirectform.h \ .ui/userprofileform.h \ .ui/transferform.h \ .ui/syssettingsform.h \ .ui/logviewform.h \ .ui/historyform.h \ .ui/selectuserform.h \ .ui/selectprofileform.h \ twinklesystray.h \ messageformview.h \ buddylistview.h \ freedesksystray.h \ .ui/messageform.h $(UIC) mphoneform.ui -o .ui/mphoneform.h .ui/mphoneform.cpp: .ui/mphoneform.h mphoneform.ui mphoneform.ui.h .ui/dtmfform.h \ .ui/inviteform.h \ .ui/redirectform.h \ .ui/termcapform.h \ .ui/srvredirectform.h \ .ui/userprofileform.h \ .ui/transferform.h \ .ui/syssettingsform.h \ .ui/logviewform.h \ .ui/historyform.h \ .ui/selectuserform.h \ .ui/selectprofileform.h \ twinklesystray.h \ messageformview.h \ buddylistview.h \ freedesksystray.h \ .ui/messageform.h $(UIC) mphoneform.ui -i mphoneform.h -o .ui/mphoneform.cpp .ui/inviteform.h: inviteform.ui .ui/getaddressform.h $(UIC) inviteform.ui -o .ui/inviteform.h .ui/inviteform.cpp: .ui/inviteform.h inviteform.ui inviteform.ui.h .ui/getaddressform.h $(UIC) inviteform.ui -i inviteform.h -o .ui/inviteform.cpp .ui/deregisterform.h: deregisterform.ui $(UIC) deregisterform.ui -o .ui/deregisterform.h .ui/deregisterform.cpp: .ui/deregisterform.h deregisterform.ui deregisterform.ui.h $(UIC) deregisterform.ui -i deregisterform.h -o .ui/deregisterform.cpp .ui/redirectform.h: redirectform.ui .ui/getaddressform.h $(UIC) redirectform.ui -o .ui/redirectform.h .ui/redirectform.cpp: .ui/redirectform.h redirectform.ui redirectform.ui.h .ui/getaddressform.h $(UIC) redirectform.ui -i redirectform.h -o .ui/redirectform.cpp .ui/termcapform.h: termcapform.ui .ui/getaddressform.h $(UIC) termcapform.ui -o .ui/termcapform.h .ui/termcapform.cpp: .ui/termcapform.h termcapform.ui termcapform.ui.h .ui/getaddressform.h $(UIC) termcapform.ui -i termcapform.h -o .ui/termcapform.cpp .ui/dtmfform.h: dtmfform.ui $(UIC) dtmfform.ui -o .ui/dtmfform.h .ui/dtmfform.cpp: .ui/dtmfform.h dtmfform.ui dtmfform.ui.h $(UIC) dtmfform.ui -i dtmfform.h -o .ui/dtmfform.cpp .ui/selectnicform.h: selectnicform.ui $(UIC) selectnicform.ui -o .ui/selectnicform.h .ui/selectnicform.cpp: .ui/selectnicform.h selectnicform.ui selectnicform.ui.h $(UIC) selectnicform.ui -i selectnicform.h -o .ui/selectnicform.cpp .ui/srvredirectform.h: srvredirectform.ui .ui/getaddressform.h $(UIC) srvredirectform.ui -o .ui/srvredirectform.h .ui/srvredirectform.cpp: .ui/srvredirectform.h srvredirectform.ui srvredirectform.ui.h .ui/getaddressform.h $(UIC) srvredirectform.ui -i srvredirectform.h -o .ui/srvredirectform.cpp .ui/authenticationform.h: authenticationform.ui $(UIC) authenticationform.ui -o .ui/authenticationform.h .ui/authenticationform.cpp: .ui/authenticationform.h authenticationform.ui authenticationform.ui.h $(UIC) authenticationform.ui -i authenticationform.h -o .ui/authenticationform.cpp .ui/userprofileform.h: userprofileform.ui $(UIC) userprofileform.ui -o .ui/userprofileform.h .ui/userprofileform.cpp: .ui/userprofileform.h userprofileform.ui userprofileform.ui.h $(UIC) userprofileform.ui -i userprofileform.h -o .ui/userprofileform.cpp .ui/selectprofileform.h: selectprofileform.ui $(UIC) selectprofileform.ui -o .ui/selectprofileform.h .ui/selectprofileform.cpp: .ui/selectprofileform.h selectprofileform.ui selectprofileform.ui.h $(UIC) selectprofileform.ui -i selectprofileform.h -o .ui/selectprofileform.cpp .ui/getprofilenameform.h: getprofilenameform.ui $(UIC) getprofilenameform.ui -o .ui/getprofilenameform.h .ui/getprofilenameform.cpp: .ui/getprofilenameform.h getprofilenameform.ui getprofilenameform.ui.h $(UIC) getprofilenameform.ui -i getprofilenameform.h -o .ui/getprofilenameform.cpp .ui/transferform.h: transferform.ui .ui/getaddressform.h $(UIC) transferform.ui -o .ui/transferform.h .ui/transferform.cpp: .ui/transferform.h transferform.ui transferform.ui.h .ui/getaddressform.h $(UIC) transferform.ui -i transferform.h -o .ui/transferform.cpp .ui/syssettingsform.h: syssettingsform.ui $(UIC) syssettingsform.ui -o .ui/syssettingsform.h .ui/syssettingsform.cpp: .ui/syssettingsform.h syssettingsform.ui syssettingsform.ui.h $(UIC) syssettingsform.ui -i syssettingsform.h -o .ui/syssettingsform.cpp .ui/logviewform.h: logviewform.ui $(UIC) logviewform.ui -o .ui/logviewform.h .ui/logviewform.cpp: .ui/logviewform.h logviewform.ui logviewform.ui.h $(UIC) logviewform.ui -i logviewform.h -o .ui/logviewform.cpp .ui/wizardform.h: wizardform.ui $(UIC) wizardform.ui -o .ui/wizardform.h .ui/wizardform.cpp: .ui/wizardform.h wizardform.ui wizardform.ui.h $(UIC) wizardform.ui -i wizardform.h -o .ui/wizardform.cpp .ui/getaddressform.h: getaddressform.ui $(UIC) getaddressform.ui -o .ui/getaddressform.h .ui/getaddressform.cpp: .ui/getaddressform.h getaddressform.ui getaddressform.ui.h $(UIC) getaddressform.ui -i getaddressform.h -o .ui/getaddressform.cpp .ui/historyform.h: historyform.ui $(UIC) historyform.ui -o .ui/historyform.h .ui/historyform.cpp: .ui/historyform.h historyform.ui historyform.ui.h $(UIC) historyform.ui -i historyform.h -o .ui/historyform.cpp .ui/selectuserform.h: selectuserform.ui gui.h \ .ui/messageform.h $(UIC) selectuserform.ui -o .ui/selectuserform.h .ui/selectuserform.cpp: .ui/selectuserform.h selectuserform.ui selectuserform.ui.h gui.h \ .ui/messageform.h $(UIC) selectuserform.ui -i selectuserform.h -o .ui/selectuserform.cpp .ui/numberconversionform.h: numberconversionform.ui $(UIC) numberconversionform.ui -o .ui/numberconversionform.h .ui/numberconversionform.cpp: .ui/numberconversionform.h numberconversionform.ui numberconversionform.ui.h $(UIC) numberconversionform.ui -i numberconversionform.h -o .ui/numberconversionform.cpp .ui/addresscardform.h: addresscardform.ui $(UIC) addresscardform.ui -o .ui/addresscardform.h .ui/addresscardform.cpp: .ui/addresscardform.h addresscardform.ui addresscardform.ui.h $(UIC) addresscardform.ui -i addresscardform.h -o .ui/addresscardform.cpp .ui/messageform.h: messageform.ui textbrowsernoautolink.h \ .ui/getaddressform.h $(UIC) messageform.ui -o .ui/messageform.h .ui/messageform.cpp: .ui/messageform.h messageform.ui messageform.ui.h textbrowsernoautolink.h \ .ui/getaddressform.h $(UIC) messageform.ui -i messageform.h -o .ui/messageform.cpp .ui/buddyform.h: buddyform.ui .ui/getaddressform.h $(UIC) buddyform.ui -o .ui/buddyform.h .ui/buddyform.cpp: .ui/buddyform.h buddyform.ui buddyform.ui.h .ui/getaddressform.h $(UIC) buddyform.ui -i buddyform.h -o .ui/buddyform.cpp .ui/sendfileform.h: sendfileform.ui $(UIC) sendfileform.ui -o .ui/sendfileform.h .ui/sendfileform.cpp: .ui/sendfileform.h sendfileform.ui sendfileform.ui.h $(UIC) sendfileform.ui -i sendfileform.h -o .ui/sendfileform.cpp .ui/diamondcardprofileform.h: diamondcardprofileform.ui $(UIC) diamondcardprofileform.ui -o .ui/diamondcardprofileform.h .ui/diamondcardprofileform.cpp: .ui/diamondcardprofileform.h diamondcardprofileform.ui diamondcardprofileform.ui.h $(UIC) diamondcardprofileform.ui -i diamondcardprofileform.h -o .ui/diamondcardprofileform.cpp .obj/mphoneform.o: .ui/mphoneform.cpp gui.h \ .ui/buddyform.h \ .ui/diamondcardprofileform.h \ mphoneform.ui.h \ .ui/mphoneform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/mphoneform.o .ui/mphoneform.cpp .obj/inviteform.o: .ui/inviteform.cpp gui.h \ inviteform.ui.h \ .ui/inviteform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/inviteform.o .ui/inviteform.cpp .obj/deregisterform.o: .ui/deregisterform.cpp deregisterform.ui.h \ .ui/deregisterform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/deregisterform.o .ui/deregisterform.cpp .obj/redirectform.o: .ui/redirectform.cpp gui.h \ redirectform.ui.h \ .ui/redirectform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/redirectform.o .ui/redirectform.cpp .obj/termcapform.o: .ui/termcapform.cpp gui.h \ termcapform.ui.h \ .ui/termcapform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/termcapform.o .ui/termcapform.cpp .obj/dtmfform.o: .ui/dtmfform.cpp dtmfform.ui.h \ .ui/dtmfform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/dtmfform.o .ui/dtmfform.cpp .obj/selectnicform.o: .ui/selectnicform.cpp gui.h \ selectnicform.ui.h \ .ui/selectnicform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/selectnicform.o .ui/selectnicform.cpp .obj/srvredirectform.o: .ui/srvredirectform.cpp gui.h \ srvredirectform.ui.h \ .ui/srvredirectform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/srvredirectform.o .ui/srvredirectform.cpp .obj/authenticationform.o: .ui/authenticationform.cpp authenticationform.ui.h \ .ui/authenticationform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/authenticationform.o .ui/authenticationform.cpp .obj/userprofileform.o: .ui/userprofileform.cpp gui.h \ .ui/numberconversionform.h \ userprofileform.ui.h \ .ui/userprofileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/userprofileform.o .ui/userprofileform.cpp .obj/selectprofileform.o: .ui/selectprofileform.cpp gui.h \ .ui/userprofileform.h \ .ui/getprofilenameform.h \ .ui/wizardform.h \ .ui/syssettingsform.h \ .ui/diamondcardprofileform.h \ selectprofileform.ui.h \ .ui/selectprofileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/selectprofileform.o .ui/selectprofileform.cpp .obj/getprofilenameform.o: .ui/getprofilenameform.cpp getprofilenameform.ui.h \ .ui/getprofilenameform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/getprofilenameform.o .ui/getprofilenameform.cpp .obj/transferform.o: .ui/transferform.cpp gui.h \ transferform.ui.h \ .ui/transferform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/transferform.o .ui/transferform.cpp .obj/syssettingsform.o: .ui/syssettingsform.cpp gui.h \ .ui/selectprofileform.h \ syssettingsform.ui.h \ .ui/syssettingsform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/syssettingsform.o .ui/syssettingsform.cpp .obj/logviewform.o: .ui/logviewform.cpp logviewform.ui.h \ .ui/logviewform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/logviewform.o .ui/logviewform.cpp .obj/wizardform.o: .ui/wizardform.cpp gui.h \ wizardform.ui.h \ .ui/wizardform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/wizardform.o .ui/wizardform.cpp .obj/getaddressform.o: .ui/getaddressform.cpp gui.h \ addresslistviewitem.h \ .ui/addresscardform.h \ getaddressform.ui.h \ .ui/getaddressform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/getaddressform.o .ui/getaddressform.cpp .obj/historyform.o: .ui/historyform.cpp gui.h \ historylistview.h \ historyform.ui.h \ .ui/historyform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/historyform.o .ui/historyform.cpp .obj/selectuserform.o: .ui/selectuserform.cpp selectuserform.ui.h \ .ui/selectuserform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/selectuserform.o .ui/selectuserform.cpp .obj/numberconversionform.o: .ui/numberconversionform.cpp gui.h \ numberconversionform.ui.h \ .ui/numberconversionform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/numberconversionform.o .ui/numberconversionform.cpp .obj/addresscardform.o: .ui/addresscardform.cpp gui.h \ addresscardform.ui.h \ .ui/addresscardform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/addresscardform.o .ui/addresscardform.cpp .obj/messageform.o: .ui/messageform.cpp gui.h \ .ui/sendfileform.h \ messageform.ui.h \ .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/messageform.o .ui/messageform.cpp .obj/buddyform.o: .ui/buddyform.cpp gui.h \ buddylistview.h \ buddyform.ui.h \ .ui/buddyform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/buddyform.o .ui/buddyform.cpp .obj/sendfileform.o: .ui/sendfileform.cpp gui.h \ sendfileform.ui.h \ .ui/sendfileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/sendfileform.o .ui/sendfileform.cpp .obj/diamondcardprofileform.o: .ui/diamondcardprofileform.cpp gui.h \ .ui/getprofilenameform.h \ diamondcardprofileform.ui.h \ .ui/diamondcardprofileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/diamondcardprofileform.o .ui/diamondcardprofileform.cpp .obj/moc_gui.o: .moc/moc_gui.cpp gui.h .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_gui.o .moc/moc_gui.cpp .obj/moc_freedesksystray.o: .moc/moc_freedesksystray.cpp freedesksystray.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_freedesksystray.o .moc/moc_freedesksystray.cpp .obj/moc_address_finder.o: .moc/moc_address_finder.cpp address_finder.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_address_finder.o .moc/moc_address_finder.cpp .obj/moc_yesnodialog.o: .moc/moc_yesnodialog.cpp yesnodialog.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_yesnodialog.o .moc/moc_yesnodialog.cpp .obj/moc_textbrowsernoautolink.o: .moc/moc_textbrowsernoautolink.cpp textbrowsernoautolink.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_textbrowsernoautolink.o .moc/moc_textbrowsernoautolink.cpp .obj/moc_mphoneform.o: .moc/moc_mphoneform.cpp .ui/mphoneform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_mphoneform.o .moc/moc_mphoneform.cpp .obj/moc_inviteform.o: .moc/moc_inviteform.cpp .ui/inviteform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_inviteform.o .moc/moc_inviteform.cpp .obj/moc_deregisterform.o: .moc/moc_deregisterform.cpp .ui/deregisterform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_deregisterform.o .moc/moc_deregisterform.cpp .obj/moc_redirectform.o: .moc/moc_redirectform.cpp .ui/redirectform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_redirectform.o .moc/moc_redirectform.cpp .obj/moc_termcapform.o: .moc/moc_termcapform.cpp .ui/termcapform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_termcapform.o .moc/moc_termcapform.cpp .obj/moc_dtmfform.o: .moc/moc_dtmfform.cpp .ui/dtmfform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_dtmfform.o .moc/moc_dtmfform.cpp .obj/moc_selectnicform.o: .moc/moc_selectnicform.cpp .ui/selectnicform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_selectnicform.o .moc/moc_selectnicform.cpp .obj/moc_srvredirectform.o: .moc/moc_srvredirectform.cpp .ui/srvredirectform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_srvredirectform.o .moc/moc_srvredirectform.cpp .obj/moc_authenticationform.o: .moc/moc_authenticationform.cpp .ui/authenticationform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_authenticationform.o .moc/moc_authenticationform.cpp .obj/moc_userprofileform.o: .moc/moc_userprofileform.cpp .ui/userprofileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_userprofileform.o .moc/moc_userprofileform.cpp .obj/moc_selectprofileform.o: .moc/moc_selectprofileform.cpp .ui/selectprofileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_selectprofileform.o .moc/moc_selectprofileform.cpp .obj/moc_getprofilenameform.o: .moc/moc_getprofilenameform.cpp .ui/getprofilenameform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_getprofilenameform.o .moc/moc_getprofilenameform.cpp .obj/moc_transferform.o: .moc/moc_transferform.cpp .ui/transferform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_transferform.o .moc/moc_transferform.cpp .obj/moc_syssettingsform.o: .moc/moc_syssettingsform.cpp .ui/syssettingsform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_syssettingsform.o .moc/moc_syssettingsform.cpp .obj/moc_logviewform.o: .moc/moc_logviewform.cpp .ui/logviewform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_logviewform.o .moc/moc_logviewform.cpp .obj/moc_wizardform.o: .moc/moc_wizardform.cpp .ui/wizardform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_wizardform.o .moc/moc_wizardform.cpp .obj/moc_getaddressform.o: .moc/moc_getaddressform.cpp .ui/getaddressform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_getaddressform.o .moc/moc_getaddressform.cpp .obj/moc_historyform.o: .moc/moc_historyform.cpp .ui/historyform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_historyform.o .moc/moc_historyform.cpp .obj/moc_selectuserform.o: .moc/moc_selectuserform.cpp .ui/selectuserform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_selectuserform.o .moc/moc_selectuserform.cpp .obj/moc_numberconversionform.o: .moc/moc_numberconversionform.cpp .ui/numberconversionform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_numberconversionform.o .moc/moc_numberconversionform.cpp .obj/moc_addresscardform.o: .moc/moc_addresscardform.cpp .ui/addresscardform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_addresscardform.o .moc/moc_addresscardform.cpp .obj/moc_messageform.o: .moc/moc_messageform.cpp .ui/messageform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_messageform.o .moc/moc_messageform.cpp .obj/moc_buddyform.o: .moc/moc_buddyform.cpp .ui/buddyform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_buddyform.o .moc/moc_buddyform.cpp .obj/moc_sendfileform.o: .moc/moc_sendfileform.cpp .ui/sendfileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_sendfileform.o .moc/moc_sendfileform.cpp .obj/moc_diamondcardprofileform.o: .moc/moc_diamondcardprofileform.cpp .ui/diamondcardprofileform.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/moc_diamondcardprofileform.o .moc/moc_diamondcardprofileform.cpp .moc/moc_gui.cpp: $(MOC) gui.h $(MOC) gui.h -o .moc/moc_gui.cpp .moc/moc_freedesksystray.cpp: $(MOC) freedesksystray.h $(MOC) freedesksystray.h -o .moc/moc_freedesksystray.cpp .moc/moc_address_finder.cpp: $(MOC) address_finder.h $(MOC) address_finder.h -o .moc/moc_address_finder.cpp .moc/moc_yesnodialog.cpp: $(MOC) yesnodialog.h $(MOC) yesnodialog.h -o .moc/moc_yesnodialog.cpp .moc/moc_textbrowsernoautolink.cpp: $(MOC) textbrowsernoautolink.h $(MOC) textbrowsernoautolink.h -o .moc/moc_textbrowsernoautolink.cpp .moc/moc_mphoneform.cpp: $(MOC) .ui/mphoneform.h $(MOC) .ui/mphoneform.h -o .moc/moc_mphoneform.cpp .moc/moc_inviteform.cpp: $(MOC) .ui/inviteform.h $(MOC) .ui/inviteform.h -o .moc/moc_inviteform.cpp .moc/moc_deregisterform.cpp: $(MOC) .ui/deregisterform.h $(MOC) .ui/deregisterform.h -o .moc/moc_deregisterform.cpp .moc/moc_redirectform.cpp: $(MOC) .ui/redirectform.h $(MOC) .ui/redirectform.h -o .moc/moc_redirectform.cpp .moc/moc_termcapform.cpp: $(MOC) .ui/termcapform.h $(MOC) .ui/termcapform.h -o .moc/moc_termcapform.cpp .moc/moc_dtmfform.cpp: $(MOC) .ui/dtmfform.h $(MOC) .ui/dtmfform.h -o .moc/moc_dtmfform.cpp .moc/moc_selectnicform.cpp: $(MOC) .ui/selectnicform.h $(MOC) .ui/selectnicform.h -o .moc/moc_selectnicform.cpp .moc/moc_srvredirectform.cpp: $(MOC) .ui/srvredirectform.h $(MOC) .ui/srvredirectform.h -o .moc/moc_srvredirectform.cpp .moc/moc_authenticationform.cpp: $(MOC) .ui/authenticationform.h $(MOC) .ui/authenticationform.h -o .moc/moc_authenticationform.cpp .moc/moc_userprofileform.cpp: $(MOC) .ui/userprofileform.h $(MOC) .ui/userprofileform.h -o .moc/moc_userprofileform.cpp .moc/moc_selectprofileform.cpp: $(MOC) .ui/selectprofileform.h $(MOC) .ui/selectprofileform.h -o .moc/moc_selectprofileform.cpp .moc/moc_getprofilenameform.cpp: $(MOC) .ui/getprofilenameform.h $(MOC) .ui/getprofilenameform.h -o .moc/moc_getprofilenameform.cpp .moc/moc_transferform.cpp: $(MOC) .ui/transferform.h $(MOC) .ui/transferform.h -o .moc/moc_transferform.cpp .moc/moc_syssettingsform.cpp: $(MOC) .ui/syssettingsform.h $(MOC) .ui/syssettingsform.h -o .moc/moc_syssettingsform.cpp .moc/moc_logviewform.cpp: $(MOC) .ui/logviewform.h $(MOC) .ui/logviewform.h -o .moc/moc_logviewform.cpp .moc/moc_wizardform.cpp: $(MOC) .ui/wizardform.h $(MOC) .ui/wizardform.h -o .moc/moc_wizardform.cpp .moc/moc_getaddressform.cpp: $(MOC) .ui/getaddressform.h $(MOC) .ui/getaddressform.h -o .moc/moc_getaddressform.cpp .moc/moc_historyform.cpp: $(MOC) .ui/historyform.h $(MOC) .ui/historyform.h -o .moc/moc_historyform.cpp .moc/moc_selectuserform.cpp: $(MOC) .ui/selectuserform.h $(MOC) .ui/selectuserform.h -o .moc/moc_selectuserform.cpp .moc/moc_numberconversionform.cpp: $(MOC) .ui/numberconversionform.h $(MOC) .ui/numberconversionform.h -o .moc/moc_numberconversionform.cpp .moc/moc_addresscardform.cpp: $(MOC) .ui/addresscardform.h $(MOC) .ui/addresscardform.h -o .moc/moc_addresscardform.cpp .moc/moc_messageform.cpp: $(MOC) .ui/messageform.h $(MOC) .ui/messageform.h -o .moc/moc_messageform.cpp .moc/moc_buddyform.cpp: $(MOC) .ui/buddyform.h $(MOC) .ui/buddyform.h -o .moc/moc_buddyform.cpp .moc/moc_sendfileform.cpp: $(MOC) .ui/sendfileform.h $(MOC) .ui/sendfileform.h -o .moc/moc_sendfileform.cpp .moc/moc_diamondcardprofileform.cpp: $(MOC) .ui/diamondcardprofileform.h $(MOC) .ui/diamondcardprofileform.h -o .moc/moc_diamondcardprofileform.cpp .obj/qmake_image_collection.o: .ui/qmake_image_collection.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/qmake_image_collection.o .ui/qmake_image_collection.cpp .ui/qmake_image_collection.cpp: images/filenew \ images/filesave \ images/print \ images/undo \ images/redo \ images/editcut \ images/editcopy \ images/editpaste \ images/searchfind \ images/invite.png \ images/answer.png \ images/bye.png \ images/reject.png \ images/redirect.png \ images/hold.png \ images/dtmf.png \ images/bye-disabled.png \ images/redial.png \ images/redial-disabled.png \ images/invite-disabled.png \ images/answer-disabled.png \ images/reject-disabled.png \ images/redirect-disabled.png \ images/hold-disabled.png \ images/dtmf-disabled.png \ images/penguin.png \ images/package_network.png \ images/kmix.png \ images/package_system.png \ images/yast_babelfish.png \ images/clock.png \ images/yast_PhoneTTOffhook.png \ images/penguin_big.png \ images/password.png \ images/kcmpci.png \ images/penguin-small.png \ images/conf.png \ images/conf-disabled.png \ images/mute.png \ images/mute-disabled.png \ images/twinkle16.png \ images/twinkle48.png \ images/twinkle32.png \ images/transfer-disabled.png \ images/transfer.png \ images/log.png \ images/dtmf-2.png \ images/dtmf-3.png \ images/dtmf-5.png \ images/dtmf-6.png \ images/dtmf-7.png \ images/dtmf-8.png \ images/dtmf-9.png \ images/dtmf-4.png \ images/dtmf-1.png \ images/dtmf-0.png \ images/dtmf-star.png \ images/dtmf-pound.png \ images/dtmf-a.png \ images/dtmf-b.png \ images/dtmf-c.png \ images/dtmf-d.png \ images/twinkle24.png \ images/exit.png \ images/kontact_contacts.png \ images/ok.png \ images/cancel.png \ images/1rightarrow.png \ images/1leftarrow-yellow.png \ images/editdelete.png \ images/kcmpci16.png \ images/kontact_contacts-disabled.png \ images/sys_auto_ans.png \ images/sys_auto_ans_dis.png \ images/sys_busy_estab.png \ images/sys_busy_estab_dis.png \ images/sys_busy_trans.png \ images/sys_busy_trans_dis.png \ images/sys_dnd.png \ images/sys_dnd_dis.png \ images/sys_idle.png \ images/sys_idle_dis.png \ images/sys_redir.png \ images/sys_redir_dis.png \ images/sys_services.png \ images/sys_services_dis.png \ images/sys_hold.png \ images/sys_hold_dis.png \ images/sys_mute.png \ images/sys_mute_dis.png \ images/network.png \ images/knotify.png \ images/fileopen.png \ images/fileopen-disabled.png \ images/cf.png \ images/auto_answer.png \ images/auto_answer-disabled.png \ images/cancel-disabled.png \ images/cf-disabled.png \ images/missed-disabled.png \ images/missed.png \ images/sys_missed.png \ images/sys_missed_dis.png \ images/twinkle16-disabled.png \ images/gear.png \ images/reg_failed-disabled.png \ images/reg_failed.png \ images/no-indication.png \ images/contexthelp.png \ images/settings.png \ images/reg-query.png \ images/log_small.png \ images/qt-logo.png \ images/1leftarrow.png \ images/1uparrow.png \ images/1downarrow.png \ images/kontact_contacts32.png \ images/encrypted.png \ images/sys_encrypted.png \ images/sys_encrypted_dis.png \ images/encrypted32.png \ images/encrypted-disabled.png \ images/stat_conference.png \ images/stat_established.png \ images/stat_outgoing.png \ images/stat_ringing.png \ images/stat_mute.png \ images/stat_established_nomedia.png \ images/encrypted_verified.png \ images/sys_encrypted_verified.png \ images/sys_encrypted_verified_dis.png \ images/consult-xfer.png \ images/mwi_new16.png \ images/mwi_none16.png \ images/mwi_none16_dis.png \ images/sys_mwi.png \ images/sys_mwi_dis.png \ images/mwi_none.png \ images/mwi_failure16.png \ images/presence_offline.png \ images/presence_online.png \ images/presence_failed.png \ images/presence_rejected.png \ images/presence_unknown.png \ images/edit16.png \ images/message.png \ images/edit.png \ images/buddy.png \ images/message32.png \ images/presence.png \ images/save_as.png \ images/attach.png \ images/mime_application.png \ images/mime_audio.png \ images/mime_image.png \ images/mime_text.png \ images/mime_video.png $(UIC) -embed twinkle images/filenew images/filesave images/print images/undo images/redo images/editcut images/editcopy images/editpaste images/searchfind images/invite.png images/answer.png images/bye.png images/reject.png images/redirect.png images/hold.png images/dtmf.png images/bye-disabled.png images/redial.png images/redial-disabled.png images/invite-disabled.png images/answer-disabled.png images/reject-disabled.png images/redirect-disabled.png images/hold-disabled.png images/dtmf-disabled.png images/penguin.png images/package_network.png images/kmix.png images/package_system.png images/yast_babelfish.png images/clock.png images/yast_PhoneTTOffhook.png images/penguin_big.png images/password.png images/kcmpci.png images/penguin-small.png images/conf.png images/conf-disabled.png images/mute.png images/mute-disabled.png images/twinkle16.png images/twinkle48.png images/twinkle32.png images/transfer-disabled.png images/transfer.png images/log.png images/dtmf-2.png images/dtmf-3.png images/dtmf-5.png images/dtmf-6.png images/dtmf-7.png images/dtmf-8.png images/dtmf-9.png images/dtmf-4.png images/dtmf-1.png images/dtmf-0.png images/dtmf-star.png images/dtmf-pound.png images/dtmf-a.png images/dtmf-b.png images/dtmf-c.png images/dtmf-d.png images/twinkle24.png images/exit.png images/kontact_contacts.png images/ok.png images/cancel.png images/1rightarrow.png images/1leftarrow-yellow.png images/editdelete.png images/kcmpci16.png images/kontact_contacts-disabled.png images/sys_auto_ans.png images/sys_auto_ans_dis.png images/sys_busy_estab.png images/sys_busy_estab_dis.png images/sys_busy_trans.png images/sys_busy_trans_dis.png images/sys_dnd.png images/sys_dnd_dis.png images/sys_idle.png images/sys_idle_dis.png images/sys_redir.png images/sys_redir_dis.png images/sys_services.png images/sys_services_dis.png images/sys_hold.png images/sys_hold_dis.png images/sys_mute.png images/sys_mute_dis.png images/network.png images/knotify.png images/fileopen.png images/fileopen-disabled.png images/cf.png images/auto_answer.png images/auto_answer-disabled.png images/cancel-disabled.png images/cf-disabled.png images/missed-disabled.png images/missed.png images/sys_missed.png images/sys_missed_dis.png images/twinkle16-disabled.png images/gear.png images/reg_failed-disabled.png images/reg_failed.png images/no-indication.png images/contexthelp.png images/settings.png images/reg-query.png images/log_small.png images/qt-logo.png images/1leftarrow.png images/1uparrow.png images/1downarrow.png images/kontact_contacts32.png images/encrypted.png images/sys_encrypted.png images/sys_encrypted_dis.png images/encrypted32.png images/encrypted-disabled.png images/stat_conference.png images/stat_established.png images/stat_outgoing.png images/stat_ringing.png images/stat_mute.png images/stat_established_nomedia.png images/encrypted_verified.png images/sys_encrypted_verified.png images/sys_encrypted_verified_dis.png images/consult-xfer.png images/mwi_new16.png images/mwi_none16.png images/mwi_none16_dis.png images/sys_mwi.png images/sys_mwi_dis.png images/mwi_none.png images/mwi_failure16.png images/presence_offline.png images/presence_online.png images/presence_failed.png images/presence_rejected.png images/presence_unknown.png images/edit16.png images/message.png images/edit.png images/buddy.png images/message32.png images/presence.png images/save_as.png images/attach.png images/mime_application.png images/mime_audio.png images/mime_image.png images/mime_text.png images/mime_video.png -o .ui/qmake_image_collection.cpp ####### Install install: uninstall: distdir: check: twinkle-1.4.2/src/gui/selectprofileform.ui0000644000175000001440000004327711151060043015552 00000000000000 SelectProfileForm SelectProfileForm 0 0 501 513 Twinkle - Select user profile unnamed selectTextLabel 5 0 0 0 Select user profile(s) to run: WordBreak|AlignVCenter User profile true true profileListView LastColumn Tick the check boxes of the user profiles that you want to run and press run. layout78 unnamed spacer17 Vertical Expanding 20 20 newProfileGroupBox Create profile unnamed newPushButton Ed&itor Alt+I Create a new profile with the profile editor. wizardPushButton &Wizard Alt+W Create a new profile with the wizard. diamondcardPushButton Dia&mondcard Alt+M Create a profile for a Diamondcard account. With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. modifyProfileGroupBox Modify profile unnamed editPushButton &Edit Alt+E Edit the highlighted profile. deletePushButton &Delete Alt+D Delete the highlighted profile. renamePushButton Ren&ame Alt+A Rename the highlighted profile. startupProfileGroupBox Startup profile unnamed defaultPushButton &Set as default Alt+S Make the selected profiles the default profiles. The next time you start Twinkle, these profiles will be automatically run. runPushButton &Run Alt+R true Run Twinkle with the selected profiles. sysPushButton S&ystem settings Alt+Y Edit the system settings. cancelPushButton &Cancel Alt+C cancelPushButton clicked() SelectProfileForm reject() runPushButton clicked() SelectProfileForm runProfile() editPushButton clicked() SelectProfileForm editProfile() newPushButton clicked() SelectProfileForm newProfile() deletePushButton clicked() SelectProfileForm deleteProfile() renamePushButton clicked() SelectProfileForm renameProfile() wizardPushButton clicked() SelectProfileForm wizardProfile() defaultPushButton clicked() SelectProfileForm setAsDefault() sysPushButton clicked() SelectProfileForm sysSettings() profileListView doubleClicked(QListViewItem*) SelectProfileForm toggleItem(QListViewItem*) diamondcardPushButton clicked() SelectProfileForm diamondcardProfile() profileListView newPushButton wizardPushButton diamondcardPushButton editPushButton deletePushButton renamePushButton defaultPushButton runPushButton sysPushButton cancelPushButton list string phone.h qmainwindow.h qdir.h user.h qstringlist.h qmessagebox.h protocol.h gui.h userprofileform.h getprofilenameform.h audits/memman.h wizardform.h syssettingsform.h qlistview.h cstring service.h presence/buddy.h diamondcardprofileform.h selectprofileform.ui.h extern t_phone *phone; std::list<std::string> selectedProfiles; bool defaultSet; t_user *user_config; QMainWindow *mainWindow; selection(const list<string> &) profileRenamed() showForm( QMainWindow * _mainWindow ) runProfile() editProfile() newProfile() newProfile( bool exec_mode ) newProfileCreated() deleteProfile() renameProfile() setAsDefault() wizardProfile() wizardProfile( bool exec_mode ) diamondcardProfile() diamondcardProfile( bool exec_mode ) sysSettings() fillProfileListView( const QStringList & profiles ) toggleItem( QListViewItem * item ) init() destroy() execForm() getUserProfiles( QStringList & profiles, QString & error ) twinkle-1.4.2/src/gui/srvredirectform.ui0000644000175000001440000011773511131206163015252 00000000000000 SrvRedirectForm SrvRedirectForm 0 0 648 315 Twinkle - Call Redirection unnamed layout114 unnamed userTextLabel User: userComboBox userComboBox 7 0 0 0 cfTabWidget true There are 3 redirect services:<p> <b>Unconditional:</b> redirect all calls </p> <p> <b>Busy:</b> redirect a call if both lines are busy </p> <p> <b>No answer:</b> redirect a call when the no-answer timer expires </p> tab &Unconditional unnamed cfAlwaysCheckBox &Redirect all calls Alt+R Activate the unconditional redirection service. cfAlwaysGroupBox true Redirect to unnamed cfAlwaysDst1LineEdit true LineEditPanel Sunken You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfAlwaysDst2LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfAlwaysDst3TextLabel true &3rd choice destination: cfAlwaysDst3LineEdit cfAlwaysDst3LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfAlwaysDst2TextLabel &2nd choice destination: cfAlwaysDst2LineEdit cfAlwaysDst1TextLabel &1st choice destination: cfAlwaysDst1LineEdit addrAlways1ToolButton TabFocus F10 kontact_contacts.png Address book addrAlways2ToolButton TabFocus F11 kontact_contacts.png Address book Select an address from the address book. addrAlways3ToolButton TabFocus F12 kontact_contacts.png Address book Select an address from the address book. tab &Busy unnamed cfBusyCheckBox &Redirect calls when I am busy Alt+R Activate the redirection when busy service. cfBusyGroupBox true Redirect to unnamed cfBusyDst2LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfBusyDst3TextLabel &3rd choice destination: cfAlwaysDst3LineEdit cfBusyDst3LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfBusyDst2TextLabel &2nd choice destination: cfAlwaysDst2LineEdit cfBusyDst1TextLabel &1st choice destination: cfAlwaysDst1LineEdit cfBusyDst1LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. addrBusy1ToolButton kontact_contacts.png Address book Select an address from the address book. addrBusy2ToolButton kontact_contacts.png Address book Select an address from the address book. addrBusy3ToolButton kontact_contacts.png Address book Select an address from the address book. tab &No answer unnamed cfNoanswerCheckBox &Redirect calls when I do not answer Alt+R Activate the redirection on no answer service. cfNoanswerGroupBox true Redirect to unnamed cfNoanswerDst2LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfNoanswerDst3TextLabel &3rd choice destination: cfAlwaysDst3LineEdit cfNoanswerDst2TextLabel &2nd choice destination: cfAlwaysDst2LineEdit cfNoanswerDst1TextLabel &1st choice destination: cfAlwaysDst1LineEdit cfNoanswerDst1LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. cfNoanswerDst3LineEdit true You can specify up to 3 destinations to which you want to redirect the call. If the first destination does not answer the call, the second destination will be tried and so on. addrNoanswer1ToolButton kontact_contacts.png Address book Select an address from the address book. addrNoanswer2ToolButton kontact_contacts.png Address book Select an address from the address book. addrNoanswer3ToolButton kontact_contacts.png Address book Select an address from the address book. spacer14 Vertical Expanding 20 16 layout23 unnamed spacer13 Horizontal Expanding 261 20 okPushButton &OK Alt+O true Accept and save all changes. cancelPushButton &Cancel Alt+C Undo your changes and close the window. cancelPushButton clicked() SrvRedirectForm reject() okPushButton clicked() SrvRedirectForm validate() cfAlwaysCheckBox toggled(bool) SrvRedirectForm toggleAlways(bool) cfBusyCheckBox toggled(bool) SrvRedirectForm toggleBusy(bool) cfNoanswerCheckBox toggled(bool) SrvRedirectForm toggleNoanswer(bool) addrAlways1ToolButton clicked() SrvRedirectForm showAddressBook1() addrAlways2ToolButton clicked() SrvRedirectForm showAddressBook2() addrAlways3ToolButton clicked() SrvRedirectForm showAddressBook3() addrBusy1ToolButton clicked() SrvRedirectForm showAddressBook4() addrBusy2ToolButton clicked() SrvRedirectForm showAddressBook5() addrBusy3ToolButton clicked() SrvRedirectForm showAddressBook6() addrNoanswer1ToolButton clicked() SrvRedirectForm showAddressBook7() addrNoanswer2ToolButton clicked() SrvRedirectForm showAddressBook8() addrNoanswer3ToolButton clicked() SrvRedirectForm showAddressBook9() userComboBox activated(const QString&) SrvRedirectForm changedUser(const QString&) cfTabWidget cfAlwaysCheckBox cfAlwaysDst1LineEdit cfAlwaysDst2LineEdit cfAlwaysDst3LineEdit cfBusyCheckBox cfBusyDst1LineEdit cfBusyDst2LineEdit cfBusyDst3LineEdit cfNoanswerCheckBox cfNoanswerDst1LineEdit cfNoanswerDst2LineEdit cfNoanswerDst3LineEdit okPushButton cancelPushButton phone.h qgroupbox.h qcheckbox.h gui.h audits/memman.h sockets/url.h list qlineedit.h getaddressform.h user.h phone.h srvredirectform.ui.h extern t_phone *phone; int nrAddressBook; GetAddressForm *getAddressForm; t_user *current_user; int current_user_idx; destinations(t_user *, const list<t_display_url> &always, const list<t_display_url> &busy, const list<t_display_url> &noanswer) show() populate() validate() toggleAlways( bool on ) toggleBusy( bool on ) toggleNoanswer( bool on ) changedUser( const QString & user_display_uri ) showAddressBook() showAddressBook1() showAddressBook2() showAddressBook3() showAddressBook4() showAddressBook5() showAddressBook6() showAddressBook7() showAddressBook8() showAddressBook9() selectedAddress( const QString & address ) init() destroy() validateValues() validate( bool cf_active, QLineEdit * dst1, QLineEdit * dst2, QLineEdit * dst3, list<t_display_url> & dest_list ) twinkle-1.4.2/src/gui/buddylistview.cpp0000644000175000001440000001721111127714053015070 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "buddylistview.h" #include "gui.h" #include "qapplication.h" #include "qfont.h" #include "qheader.h" #include "qpixmap.h" #include "qrect.h" #include "qsize.h" #include "qstylesheet.h" void AbstractBLVItem::set_icon(t_presence_state::t_basic_state state) { switch (state) { case t_presence_state::ST_BASIC_UNKNOWN: setPixmap(0, QPixmap::fromMimeSource("presence_unknown.png")); break; case t_presence_state::ST_BASIC_CLOSED: setPixmap(0, QPixmap::fromMimeSource("presence_offline.png")); break; case t_presence_state::ST_BASIC_OPEN: setPixmap(0, QPixmap::fromMimeSource("presence_online.png")); break; case t_presence_state::ST_BASIC_FAILED: setPixmap(0, QPixmap::fromMimeSource("presence_failed.png")); break; case t_presence_state::ST_BASIC_REJECTED: setPixmap(0, QPixmap::fromMimeSource("presence_rejected.png")); break; default: setPixmap(0, QPixmap::fromMimeSource("presence_unknown.png")); break; } } AbstractBLVItem::AbstractBLVItem(QListViewItem *parent, const QString &text) : QListViewItem(parent, text) {} AbstractBLVItem::AbstractBLVItem(QListView *parent, const QString &text) : QListViewItem(parent, text) {} AbstractBLVItem::~AbstractBLVItem() {} QString AbstractBLVItem::get_tip(void) { return tip; } void BuddyListViewItem::set_icon(void) { t_user *user_config = buddy->get_user_profile(); string url_str = ui->expand_destination(user_config, buddy->get_sip_address()); tip = ""; tip += QStyleSheet::escape(ui->format_sip_address(user_config, buddy->get_name(), t_url(url_str)).c_str()).replace(' ', " "); if (!buddy->get_may_subscribe_presence()) { setPixmap(0, QPixmap::fromMimeSource("buddy.png")); } else { QString failure; t_presence_state::t_basic_state basic_state = buddy-> get_presence_state()->get_basic_state(); AbstractBLVItem::set_icon(basic_state); tip += "
"; tip += ""; tip += qApp->translate("BuddyList", "Availability"); tip += ": "; switch (basic_state) { case t_presence_state::ST_BASIC_UNKNOWN: tip += qApp->translate("BuddyList", "unknown"); break; case t_presence_state::ST_BASIC_CLOSED: tip += qApp->translate("BuddyList", "offline"); break; case t_presence_state::ST_BASIC_OPEN: tip += qApp->translate("BuddyList", "online"); break; case t_presence_state::ST_BASIC_FAILED: tip += qApp->translate("BuddyList", "request failed"); failure = buddy->get_presence_state()->get_failure_msg().c_str(); if (!failure.isEmpty()) { tip += QString(" (%1)").arg(failure); } break; case t_presence_state::ST_BASIC_REJECTED: tip += qApp->translate("BuddyList", "request rejected"); break; default: tip += qApp->translate("BuddyList", "unknown"); break; } } tip += ""; tip = tip.replace(' ', " "); } BuddyListViewItem::BuddyListViewItem(QListViewItem *parent, t_buddy *_buddy) : AbstractBLVItem(parent, _buddy->get_name().c_str()), buddy(_buddy) { set_icon(); buddy->attach(this); } BuddyListViewItem::~BuddyListViewItem() { buddy->detach(this); } void BuddyListViewItem::update(void) { // This method is called directly from the core, so lock the GUI ui->lock(); set_icon(); if (buddy->get_name().c_str() != text(0)) { setText(0, buddy->get_name().c_str()); QListViewItem::parent()->sort(); } ui->unlock(); } void BuddyListViewItem::subject_destroyed(void) { delete this; } t_buddy *BuddyListViewItem::get_buddy(void) { return buddy; } void BLViewUserItem::set_icon(void) { t_presence_state::t_basic_state basic_state; QString failure; QString profile_name = presence_epa->get_user_profile()->get_profile_name().c_str(); tip = ""; tip += QStyleSheet::escape(profile_name); tip += "
"; tip += ""; tip += qApp->translate("BuddyList", "Availability"); tip += ": "; switch (presence_epa->get_epa_state()) { case t_presence_epa::EPA_UNPUBLISHED: tip += qApp->translate("BuddyList", "not published"); setPixmap(0, QPixmap::fromMimeSource("penguin-small.png")); break; case t_presence_epa::EPA_FAILED: tip += qApp->translate("BuddyList", "failed to publish"); failure = presence_epa->get_failure_msg().c_str(); if (!failure.isEmpty()) { tip += QString(" (%1)").arg(failure); } setPixmap(0, QPixmap::fromMimeSource("presence_failed.png")); break; case t_presence_epa::EPA_PUBLISHED: basic_state = presence_epa->get_basic_state(); AbstractBLVItem::set_icon(basic_state); switch (presence_epa->get_basic_state()) { case t_presence_state::ST_BASIC_CLOSED: tip += qApp->translate("BuddyList", "offline"); break; case t_presence_state::ST_BASIC_OPEN: tip += qApp->translate("BuddyList", "online"); break; default: tip += qApp->translate("BuddyList", "unknown"); break; } break; default: tip += qApp->translate("BuddyList", "unknown"); break; } tip += "

"; tip += qApp->translate("BuddyList", "Click right to add a buddy."); tip += ""; tip = tip.replace(' ', " "); } BLViewUserItem::BLViewUserItem(QListView *parent, t_presence_epa *_presence_epa) : AbstractBLVItem(parent, _presence_epa->get_user_profile()->get_profile_name().c_str()), presence_epa(_presence_epa) { set_icon(); presence_epa->attach(this); } BLViewUserItem::~BLViewUserItem() { presence_epa->detach(this); } void BLViewUserItem::paintCell(QPainter *painter, const QColorGroup &cg, int column, int width, int align) { painter->save(); QFont font = painter->font(); font.setBold(true); painter->setFont(font); QListViewItem::paintCell(painter, cg, column, width, align); painter->restore(); } void BLViewUserItem::update(void) { // This method is called directly from the core, so lock the GUI ui->lock(); set_icon(); if (presence_epa->get_user_profile()->get_profile_name().c_str() == text(0)) { setText(0, presence_epa->get_user_profile()->get_profile_name().c_str()); QListViewItem::listView()->sort(); } ui->unlock(); } void BLViewUserItem::subject_destroyed(void) { delete this; } t_presence_epa *BLViewUserItem::get_presence_epa(void) { return presence_epa; } BuddyListViewTip::BuddyListViewTip(QListView *parent) : QToolTip(parent->viewport()), parentListView(parent) {} void BuddyListViewTip::maybeTip ( const QPoint & p ) { QListView *listView = parentListView; QListViewItem *item = listView->itemAt(p); if (!item) return; AbstractBLVItem *bitem = dynamic_cast(item); if (!bitem) return; int x = listView->header()->sectionPos( listView->header()->mapToIndex( 0 ) ) + listView->treeStepSize() * ( item->depth() + ( listView->rootIsDecorated() ? 1 : 0) ) + listView->itemMargin(); if ( p.x() > x || p.x() < listView->header()->sectionPos( listView->header()->mapToIndex( 0 ) ) ) { // p is not on root decoration QRect tipRect = listView->itemRect(item); // Shrink rect to exclude root decoration tipRect.setX(x); tip(tipRect, bitem->get_tip()); } } twinkle-1.4.2/src/gui/freedesksystray.h0000644000175000001440000000542511127714044015072 00000000000000/*************************************************************************** * Copyright (C) 2004 by Emil Stoyanov * * emosto@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ // 2006 Modified by Michel de Boer #ifndef FREEDESKSYSTEMTRAY_H #define FREEDESKTSYSTEMTRAY_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // System Tray Protocol Specification opcodes. #define SYSTEM_TRAY_REQUEST_DOCK 0 #define SYSTEM_TRAY_BEGIN_MESSAGE 1 #define SYSTEM_TRAY_CANCEL_MESSAGE 2 class FreeDeskSysTray : public QLabel { Q_OBJECT public: FreeDeskSysTray(QWidget *pParent = 0, const char *pszName = 0); ~FreeDeskSysTray(); void setPixmapOverlay(const QPixmap& pmOverlay); void showContextMenu(const QPoint& position); void dock (); void undock (); QPopupMenu *contextMenu(); void setPixmap(const QPixmap& pixmap); public: QWidget * mainWindow; QPopupMenu * trayMenu; protected: void mousePressEvent(QMouseEvent *); public slots: void slotMenuItemShow(); void slotMenuItemQuit(); signals: void quitSelected(); private: QRect mainWindowGeometry; QPoint windowPos; }; // ifndef FREEDESKSYSTEMTRAY_H #endif twinkle-1.4.2/src/gui/command_args.h0000644000175000001440000000350711127714044014274 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _COMMAND_ARGS_H #define _COMMAND_ARGS_H #include "twinkle_config.h" /** Command arguments. */ struct t_command_args { /** SIP URI to be called passed via the --call command line parameter. */ QString callto_destination; /** CLI command passed via the --cmd command line parameter. */ QString cli_command; /** Indicates if the --call or --cmd must be performed immediately. */ bool cmd_immediate_mode; /** Indicates the profile that should be made active before performing * --call or --cmd */ QString cmd_set_profile; /** Indicates if the --show option was given. */ bool cmd_show; /** Indicates if the --hide option was given. */ bool cmd_hide; /** If a port number is passed by the user on the command line, then * that port number overrides the port from the system settings. */ unsigned short override_sip_port; unsigned short override_rtp_port; t_command_args() : cmd_immediate_mode(false), cmd_show(false), cmd_hide(false), override_sip_port(0), override_rtp_port(0) {} }; #endif twinkle-1.4.2/src/gui/core_strings.h0000644000175000001440000001436111151045005014332 00000000000000// This file is generated by translator.py // It contains all strings that need translation from the // core of Twinkle. #define _ZAP(s) // userintf.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Anonymous")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Warning:")) // log.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Failed to create log file %1 .")) // call_history.cpp _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "local user")) _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "remote user")) _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "failure")) _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "unknown")) _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "in")) _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "out")) _ZAP(QT_TRANSLATE_NOOP("CoreCallHistory", "unknown")) // sender.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Excessive number of socket errors.")) // sys_settings.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Built with support for:")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Contributions:")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "This software contains the following software from 3rd parties:")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "* GSM codec from Jutta Degener and Carsten Bormann, University of Berlin")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "* G.711/G.726 codecs from Sun Microsystems (public domain)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "* iLBC implementation from RFC 3951 (www.ilbcfreeware.org)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "* Parts of the STUN project at http://sourceforge.net/projects/stun")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "* Parts of libsrv at http://libsrv.sourceforge.net/")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "For RTP the following dynamic libraries are linked:")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Translated to english by ")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Directory %1 does not exist.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open file %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open file %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "%1 is not set to your home directory.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Directory %1 (%2) does not exist.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot create directory %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot create directory %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Failed to create file %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Failed to write data to file %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot create %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "%1 is already running.\nLock file %2 already exists.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot lock %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open file for reading: %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "File system error while reading file %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Syntax error in file %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Failed to backup %1 to %2")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open file for writing: %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "File system error while writing file %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "unknown name (device is busy)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Default device")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot access the ring tone device (%1).")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot access the speaker (%1).")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot access the microphone (%1).")) // listener.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Excessive number of socket errors.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot receive incoming TCP connections.")) // phone.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Call transfer - %1")) // audio_session.cpp _ZAP(QT_TRANSLATE_NOOP("CoreAudio", "Failed to open sound card")) _ZAP(QT_TRANSLATE_NOOP("CoreAudio", "Failed to open sound card")) _ZAP(QT_TRANSLATE_NOOP("CoreAudio", "Failed to open sound card")) _ZAP(QT_TRANSLATE_NOOP("CoreAudio", "Failed to create a UDP socket (RTP) on port %1")) _ZAP(QT_TRANSLATE_NOOP("CoreAudio", "Failed to create audio receiver thread.")) _ZAP(QT_TRANSLATE_NOOP("CoreAudio", "Failed to create audio transmitter thread.")) // audio_device.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Sound card cannot be set to full duplex.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot set buffer size on sound card.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Sound card cannot be set to %1 channels.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Sound card cannot be set to %1 channels.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot set sound card to 16 bits recording.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot set sound card to 16 bits playing.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot set sound card sample rate to %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Opening ALSA driver failed")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open ALSA driver for PCM playback")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open ALSA driver for PCM capture")) // msg_session.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Failed to send message.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Failed to send message.")) // stun_transaction.cpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot resolve STUN server: %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "You are behind a symmetric NAT.\nSTUN will not work.\nConfigure a public IP address in the user profile\nand create the following static bindings (UDP) in your NAT.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "public IP: %1 --> private IP: %2 (SIP signaling)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot reach the STUN server: %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "If you are behind a firewall then you need to open the following UDP ports.")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Port %1 (SIP signaling)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Ports %1-%2 (RTP/RTCP)")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "NAT type discovery via STUN failed.")) // record_file.hpp _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open file for reading: %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "File system error while reading file %1 .")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "Cannot open file for writing: %1")) _ZAP(QT_TRANSLATE_NOOP("TwinkleCore", "File system error while writing file %1 .")) twinkle-1.4.2/src/gui/logviewform.ui0000644000175000001440000001021510514240440014353 00000000000000 LogViewForm LogViewForm 0 0 599 472 Twinkle - Log unnamed logTextEdit PlainText NoWrap true Contents of the current log file (~/.twinkle/twinkle.log) closePushButton &Close Alt+C spacer23 Horizontal Expanding 360 20 clearPushButton C&lear Alt+L Clear the log window. This does <b>not</b> clear the log file itself. closePushButton clicked() LogViewForm close() clearPushButton clicked() LogViewForm clear() logTextEdit clearPushButton closePushButton qfile.h qtextstream.h log.h qdialog.h qstring.h audits/memman.h logviewform.ui.h QFile *logfile; QTextStream *logstream; show() closeEvent( QCloseEvent * ev ) update( bool log_zapped ) clear() twinkle-1.4.2/src/gui/syssettingsform.ui0000644000175000001440000026643011143565012015316 00000000000000 SysSettingsForm SysSettingsForm 0 0 765 624 Twinkle - System Settings unnamed General twinkle32.png Audio kmix.png Ring tones knotify.png Address book kontact_contacts32.png Network network.png Log log.png categoryListBox 1 7 0 0 Select a category for which you want to see or modify the settings. layout38 unnamed spacer98 Horizontal Expanding 321 20 okPushButton &OK Alt+O true Accept and save your changes. cancelPushButton &Cancel Alt+C Undo all your changes and close the window. settingsWidgetStack 7 5 0 0 Box pageAudio 0 unnamed audioTitleTextLabel 150 150 150 21 Box Audio 10 soundcardGroupBox Sound Card unnamed ringtoneComboBox 7 0 0 0 Select the sound card for playing the ring tone for incoming calls. micComboBox 7 0 0 0 Select the sound card to which your microphone is connected. speakerComboBox 7 0 0 0 Select the sound card for the speaker function during a call. speakerTextLabel &Speaker: speakerComboBox ringtoneTextLabel &Ring tone: ringtoneComboBox otherRingtoneTextLabel Other device: otherRingtoneLineEdit otherSpeakerTextLabel Other device: otherSpeakerLineEdit otherMicTextLabel Other device: otherMicLineEdit micTextLabel &Microphone: micComboBox otherRingtoneLineEdit otherMicLineEdit otherSpeakerLineEdit validateAudioCheckBox &Validate devices before usage Alt+V <p> Twinkle validates the audio devices before usage to avoid an established call without an audio channel. <p> On startup of Twinkle a warning is given if an audio device is inaccessible. <p> If before making a call, the microphone or speaker appears to be invalid, a warning is given and no call can be made. <p> If before answering a call, the microphone or speaker appears to be invalid, a warning is given and the call will not be answered. advancedSoundGroupBox Advanced unnamed layout31 unnamed ossFragmnetTextLabel OSS &fragment size: ossFragmentComboBox 16 32 64 128 256 alsaPlayPeriodComboBox The ALSA play period size influences the real time behaviour of your soundcard for playing sound. If your sound frequently drops while using ALSA, you might try a different value here. alsaPlayPeriodTextLabel ALSA &play period size: alsaPlayPeriodComboBox alsaCapturePeriosTextLabel &ALSA capture period size: alsaCapturePeriodComboBox 16 32 64 128 256 ossFragmentComboBox The OSS fragment size influences the real time behaviour of your soundcard. If your sound frequently drops while using OSS, you might try a different value here. 16 32 64 128 256 alsaCapturePeriodComboBox The ALSA capture period size influences the real time behaviour of your soundcard for capturing sound. If the other side of your call complains about frequently dropping sound, you might try a different value here. spacer27 Horizontal Expanding 121 20 spacer97 Vertical Expanding 20 20 pageLog 1 unnamed logTitleTextLabel 150 150 150 21 Box Log 10 layout8 unnamed logMaxSizeTextLabel &Max log size: logMaxSizeSpinBox logMaxSizeSpinBox 100 1 5 5 The maximum size of a log file in MB. When the log file exceeds this size, a backup of the log file is created and the current log file is zapped. Only one backup log file will be kept. logSizeMbTextLabel MB spacer7 Horizontal Expanding 211 20 logDebugCheckBox Log &debug reports Alt+D Indicates if reports marked as "debug" will be logged. logSipCheckBox Log &SIP reports Alt+S Indicates if SIP messages will be logged. logStunCheckBox Log S&TUN reports Alt+T Indicates if STUN messages will be logged. logMemoryCheckBox Log m&emory reports Alt+E Indicates if reports concerning memory management will be logged. spacer6 Vertical Expanding 20 61 pageGeneral 2 unnamed generalTitleTextLabel 150 150 150 21 Box General 10 systrayGroupBox System tray unnamed guiUseSystrayCheckBox Create &system tray icon on startup Alt+S Enable this option if you want a system tray icon for Twinkle. The system tray icon is created when you start Twinkle. guiHideCheckBox &Hide in system tray when closing main window Alt+H Enable this option if you want Twinkle to hide in the system tray when you close the main window. startupGroupBox Startup unnamed startHiddenCheckBox S&tartup hidden in system tray Alt+T Next time you start Twinkle it will immediately hide in the system tray. This works best when you also select a default user profile. Default user profiles true true profileListView NoSelection LastColumn If you always use the same profile(s), then you can mark these profiles as default here. The next time you start Twinkle, you will not be asked to select which profiles to run. The default profiles will automatically run. srvGroupBox Services unnamed callWaitingCheckBox Call &waiting Alt+W With call waiting an incoming call is accepted when only one line is busy. When you disable call waiting an incoming call will be rejected when one line is busy. hangupBothCheckBox Hang up &both lines when ending a 3-way conference call. Alt+B Hang up both lines when you press bye to end a 3-way conference call. When this option is disabled, only the active line will be hung up and you can continue talking with the party on the other line. layout23 unnamed histSizeTextLabel &Maximum calls in call history: histSizeSpinBox histSizeSpinBox 1000 10 The maximum number of calls that will be kept in the call history. spacer73 Horizontal Expanding 191 20 layout21 unnamed autoShowCheckBox &Auto show main window on incoming call after Alt+A When the main window is hidden, it will be automatically shown on an incoming call after the number of specified seconds. autoShowTimeoutSpinBox 60 Number of seconds after which the main window should be shown. secAutoShowTextLabel secs spacer14 Horizontal Expanding 29 20 layout34 unnamed browserTextLabel W&eb browser command: browserLineEdit browserLineEdit Command to start your web browser. If you leave this field empty Twinkle will try to figure out your default web browser. pageNetwork 3 unnamed networkTitleTextLabel 150 150 150 21 Box Network 10 spacer9 Vertical Expanding 20 230 spacer8 Horizontal Expanding 314 20 maxUdpSizeLineEdit Maximum allowed size (0-65535) in bytes of an incoming SIP message over UDP. sipUdpPortTextLabel &SIP port: sipUdpPortSpinBox rtpPortTextLabel &RTP port: rtpPortSpinBox maxTcpSizeTextLabel Max. SIP message size (&TCP): maxTcpSizeLineEdit spacer7_2 Horizontal Expanding 314 20 sipUdpPortSpinBox 65535 1025 5060 The UDP/TCP port used for sending and receiving SIP messages. maxUdpSizeTextLabel Max. SIP message size (&UDP): maxUdpSizeLineEdit maxTcpSizeLineEdit Maximum allowed size (0-4294967295) in bytes of an incoming SIP message over TCP. rtpPortSpinBox 65535 1025 2 8000 The UDP port used for sending and receiving RTP for the first line. The UDP port for the second line is 2 higher. E.g. if port 8000 is used for the first line, then the second line uses port 8002. When you use call transfer then the next even port (eg. 8004) is also used. pageRingtones 4 unnamed ringtonesTitleTextLabel 150 150 150 21 Box Ring tones 10 ringtoneButtonGroup Ring tone unnamed playRingtoneCheckBox &Play ring tone on incoming call Alt+P Indicates if a ring tone should be played when a call comes in. defaultRingtoneRadioButton &Default ring tone Alt+D true Play the default ring tone when a call comes in. customRingtoneRadioButton C&ustom ring tone Alt+U Play a custom ring tone when a call comes in. layout16 unnamed spacer21 Horizontal Fixed 20 20 ringtoneLineEdit Specify the file name of a .wav file that you want to be played as ring tone. openRingtoneToolButton TabFocus fileopen.png Select ring tone file. ringbackButtonGroup Ring back tone unnamed playRingbackCheckBox P&lay ring back tone when network does not play ring back tone Alt+L <p> Play ring back tone while you are waiting for the far-end to answer your call. </p> <p> Depending on your SIP provider the network might provide ring back tone or an announcement. </p> defaultRingbackRadioButton D&efault ring back tone Alt+E true Play the default ring back tone. customRingbackRadioButton Cu&stom ring back tone Alt+S Play a custom ring back tone. layout16_2 unnamed spacer21_2 Horizontal Fixed 20 20 ringbackLineEdit Specify the file name of a .wav file that you want to be played as ring back tone. openRingbackToolButton TabFocus fileopen.png Select ring back tone file. spacer23 Vertical Expanding 20 20 pageAddressBook 5 unnamed ringtonesTitleTextLabel_2 150 150 150 21 Box Address book 10 abLookupNameCheckBox &Lookup name for incoming call Alt+L On an incoming call, Twinkle will try to find the name belonging to the incoming SIP address in your address book. This name will be displayed. abOverrideDisplayCheckBox Ove&rride received display name Alt+R The caller may have provided a display name already. Tick this box if you want to override that name with the name you have in your address book. abLookupPhotoCheckBox Lookup &photo for incoming call Alt+P Lookup the photo of a caller in your address book and display it on an incoming call. spacer61 Vertical Expanding 20 121 okPushButton clicked() SysSettingsForm validate() cancelPushButton clicked() SysSettingsForm reject() categoryListBox highlighted(int) SysSettingsForm showCategory(int) guiUseSystrayCheckBox toggled(bool) guiHideCheckBox setEnabled(bool) guiUseSystrayCheckBox toggled(bool) guiHideCheckBox setChecked(bool) guiUseSystrayCheckBox toggled(bool) startHiddenCheckBox setEnabled(bool) playRingtoneCheckBox toggled(bool) customRingtoneRadioButton setEnabled(bool) playRingtoneCheckBox toggled(bool) defaultRingtoneRadioButton setEnabled(bool) playRingtoneCheckBox toggled(bool) SysSettingsForm playRingToneCheckBoxToggles(bool) playRingtoneCheckBox toggled(bool) openRingtoneToolButton setEnabled(bool) playRingbackCheckBox toggled(bool) customRingbackRadioButton setEnabled(bool) playRingbackCheckBox toggled(bool) defaultRingbackRadioButton setEnabled(bool) playRingbackCheckBox toggled(bool) SysSettingsForm playRingBackToneCheckBoxToggles(bool) playRingbackCheckBox toggled(bool) openRingbackToolButton setEnabled(bool) openRingtoneToolButton clicked() SysSettingsForm chooseRingtone() openRingbackToolButton clicked() SysSettingsForm chooseRingback() customRingtoneRadioButton toggled(bool) ringtoneLineEdit setEnabled(bool) customRingtoneRadioButton toggled(bool) openRingtoneToolButton setEnabled(bool) customRingbackRadioButton toggled(bool) ringbackLineEdit setEnabled(bool) customRingbackRadioButton toggled(bool) openRingbackToolButton setEnabled(bool) abLookupNameCheckBox toggled(bool) abOverrideDisplayCheckBox setEnabled(bool) ringtoneComboBox activated(int) SysSettingsForm devRingtoneSelected(int) speakerComboBox activated(int) SysSettingsForm devSpeakerSelected(int) micComboBox activated(int) SysSettingsForm devMicSelected(int) categoryListBox guiUseSystrayCheckBox guiHideCheckBox startHiddenCheckBox profileListView callWaitingCheckBox hangupBothCheckBox histSizeSpinBox autoShowCheckBox autoShowTimeoutSpinBox ringtoneComboBox otherRingtoneLineEdit speakerComboBox otherSpeakerLineEdit micComboBox otherMicLineEdit validateAudioCheckBox ossFragmentComboBox alsaPlayPeriodComboBox alsaCapturePeriodComboBox playRingtoneCheckBox defaultRingtoneRadioButton ringtoneLineEdit openRingtoneToolButton playRingbackCheckBox defaultRingbackRadioButton ringbackLineEdit openRingbackToolButton abLookupNameCheckBox abOverrideDisplayCheckBox abLookupPhotoCheckBox sipUdpPortSpinBox rtpPortSpinBox maxUdpSizeLineEdit maxTcpSizeLineEdit logMaxSizeSpinBox logDebugCheckBox logSipCheckBox logStunCheckBox logMemoryCheckBox okPushButton cancelPushButton customRingtoneRadioButton customRingbackRadioButton sys_settings.h qlistbox.h qcombobox.h gui.h sockets/interfaces.h selectprofileform.h qstringlist.h audits/memman.h qlistview.h qspinbox.h qfiledialog.h qfileinfo.h twinkle_config.h qregexp.h qvalidator.h syssettingsform.ui.h int idxOtherCaptureDevOss; int idxOtherCaptureDevAlsa; int idxOtherPlaybackDevOss; int idxOtherPlaybackDevAlsa; list<t_audio_device> list_audio_playback_dev; list<t_audio_device> list_audio_capture_dev; sipUdpPortChanged() rtpPortChanged() showCategory( int index ) populateComboBox( QComboBox * cb, const QString & s ) populate() validate() show() exec() chooseRingtone() chooseRingback() devRingtoneSelected( int idx ) devSpeakerSelected( int idx ) devMicSelected( int idx ) playRingToneCheckBoxToggles( bool on ) playRingBackToneCheckBoxToggles( bool on ) init() comboItem2audio_dev( QString item, QLineEdit * qleOther, bool playback ) twinkle-1.4.2/src/gui/gui.h0000644000175000001440000003446411144355775012447 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GUI_H #define _GUI_H #include "twinkle_config.h" #include "phone.h" #include "userintf.h" #include "im/msg_session.h" #include "messageform.h" #include "qaction.h" #include "qcombobox.h" #include "qlabel.h" #include "qlineedit.h" #include "qprogressdialog.h" #include "qtimer.h" #include "qtoolbutton.h" #include "qwidget.h" #ifdef HAVE_KDE #include #endif using namespace std; // Forward declaration class MphoneForm; // Length of redial list in combo boxes #define SIZE_REDIAL_LIST 10 // Selection purpose for select user form enum t_select_purpose { SELECT_REGISTER, SELECT_DEREGISTER, SELECT_DEREGISTER_ALL, SELECT_DND, SELECT_AUTO_ANSWER }; QString str2html(const QString &s); void setDisabledIcon(QAction *action, const QString &icon); void setDisabledIcon(QToolButton *toolButton, const QString &icon); class t_gui : public QObject, public t_userintf { Q_OBJECT private: MphoneForm *mainWindow; // List of active instant messaging session. list messageSessions; // Timer to schedule updating of message sessions every second. QTimer *timerUpdateMessageSessions; // Progress dialog for FW/NAT discovery progress bar QProgressDialog *natDiscoveryProgressDialog; // Pointers to line information fields to display information QLineEdit *fromLabel; QLineEdit *toLabel; QLineEdit *subjectLabel; QLabel *codecLabel; QLabel *photoLabel; // Timers to auto show main window on incoming call QTimer autoShowTimer[NUM_USER_LINES]; #ifdef HAVE_KDE // Popup window on system tray for incoming call notification KPassivePopup *sys_tray_popup; unsigned short line_sys_tray_popup; // lineno for popup #endif // Last dir path browsed by the user with a file dialog QString lastFileBrowsePath; // Set the line information field pointers to the fields for 'line' void setLineFields(int line); // Set text inf from, to and subject fields void displayTo(const QString &s); void displayFrom(const QString &s); void displaySubject(const QString &s); // Display the codecs in use for the line void displayCodecInfo(int line); // Display a photo void displayPhoto(const QImage &photo); protected: // The do_* methods perform the commands parsed by the exec_* methods. virtual bool do_invite(const string &destination, const string &display, const string &subject, bool immediate, bool anonymous); virtual void do_redial(void); virtual void do_answer(void); virtual void do_answerbye(void); virtual void do_reject(void); virtual void do_redirect(bool show_status, bool type_present, t_cf_type cf_type, bool action_present, bool enable, int num_redirections, const list &dest_strlist, bool immediate); virtual void do_dnd(bool show_status, bool toggle, bool enable); virtual void do_auto_answer(bool show_status, bool toggle, bool enable); virtual void do_bye(void); virtual void do_hold(void); virtual void do_retrieve(void); virtual bool do_refer(const string &destination, t_transfer_type transfer_type, bool immediate); virtual void do_conference(void); virtual void do_mute(bool show_status, bool toggle, bool enable); virtual void do_dtmf(const string &digits); virtual void do_register(bool reg_all_profiles); virtual void do_deregister(bool dereg_all_profiles, bool dereg_all_devices); virtual void do_fetch_registrations(void); virtual bool do_options(bool dest_set, const string &destination, bool immediate); virtual void do_line(int line); virtual void do_user(const string &profile_name); virtual void do_zrtp(t_zrtp_cmd zrtp_cmd); virtual bool do_message(const string &destination, const string &display, const im::t_msg &msg); virtual void do_presence(t_presence_state::t_basic_state basic_state); virtual void do_quit(void); virtual void do_help(const list &al); public: t_gui(t_phone *_phone); virtual ~t_gui(); // Start the GUI void run(void); // Save user interface state to system settings void save_state(void); // Restore user interface state from system settings void restore_state(void); /** Save state to restore a UI session. */ void save_session_state(void); /** Restore UI session state. */ void restore_session_state(void); // Lock the user interface to synchornize output void lock(void); void unlock(void); // Select network interface to use. string select_network_intf(void); // Select a user configuration file. Returns false if selection failed. bool select_user_config(list &config_files); // Clear the contents of the line information fields. After clearing // the field pointers point to the fields for 'line' void clearLineFields(int line); // Call back functions void cb_incoming_call(t_user *user_config, int line, const t_request *r); void cb_call_cancelled(int line); void cb_far_end_hung_up(int line); void cb_answer_timeout(int line); void cb_sdp_answer_not_supported(int line, const string &reason); void cb_sdp_answer_missing(int line); void cb_unsupported_content_type(int line, const t_sip_message *r); void cb_ack_timeout(int line); void cb_100rel_timeout(int line); void cb_prack_failed(int line, const t_response *r); void cb_provisional_resp_invite(int line, const t_response *r); void cb_cancel_failed(int line, const t_response *r); void cb_call_answered(t_user *user_config, int line, const t_response *r); void cb_call_failed(t_user *user_config, int line, const t_response *r); void cb_stun_failed_call_ended(int line); void cb_call_ended(int line); void cb_call_established(int line); void cb_options_response(const t_response *r); void cb_reinvite_success(int line, const t_response *r); void cb_reinvite_failed(int line, const t_response *r); void cb_retrieve_failed(int line, const t_response *r); void cb_invalid_reg_resp(t_user *user_config, const t_response *r, const string &reason); void cb_register_success(t_user *user_config, const t_response *r, unsigned long expires, bool first_success); void cb_register_failed(t_user *user_config, const t_response *r, bool first_failure); void cb_register_stun_failed(t_user *user_config, bool first_failure); void cb_deregister_success(t_user *user_config, const t_response *r); void cb_deregister_failed(t_user *user_config, const t_response *r); void cb_fetch_reg_failed(t_user *user_config, const t_response *r); void cb_fetch_reg_result(t_user *user_config, const t_response *r); void cb_register_inprog(t_user *user_config, t_register_type register_type); void cb_redirecting_request(t_user *user_config, int line, const t_contact_param &contact); void cb_redirecting_request(t_user *user_config, const t_contact_param &contact); void cb_notify_call(int line, const QString &from_party, const QString &organization, const QImage &photo, const QString &subject, QString &referred_by_party); void cb_stop_call_notification(int line); void cb_dtmf_detected(int line, char dtmf_event); void cb_send_dtmf(int line, char dtmf_event); void cb_dtmf_not_supported(int line); void cb_dtmf_supported(int line); void cb_line_state_changed(void); void cb_send_codec_changed(int line, t_audio_codec codec); void cb_recv_codec_changed(int line, t_audio_codec codec); void cb_notify_recvd(int line, const t_request *r); void cb_refer_failed(int line, const t_response *r); void cb_refer_result_success(int line); void cb_refer_result_failed(int line); void cb_refer_result_inprog(int line); // A call is being referred by the far end. r must be the REFER request. void cb_call_referred(t_user *user_config, int line, t_request *r); // The reference failed. Call to referrer is retrieved. void cb_retrieve_referrer(t_user *user_config, int line); // A consulation call for a call transfer is being setup. void cb_consultation_call_setup(t_user *user_config, int line); // STUN errors void cb_stun_failed(t_user *user_config, int err_code, const string &err_reason); void cb_stun_failed(t_user *user_config); // Interactive call back functions bool cb_ask_user_to_redirect_invite(t_user *user_config, const t_url &destination, const string &display); bool cb_ask_user_to_redirect_request(t_user *user_config, const t_url &destination, const string &display, t_method method); bool cb_ask_credentials(t_user *user_config, const string &realm, string &username, string &password); // Ask questions asynchronously. void cb_ask_user_to_refer(t_user *user_config, const t_url &refer_to_uri, const string &refer_to_display, const t_url &referred_by_uri, const string &referred_by_display); // Show an error message to the user. Depending on the interface mode // the user has to acknowledge the error before processing continues. void cb_show_msg(const string &msg, t_msg_priority prio = MSG_INFO); void cb_show_msg(QWidget *parent, const string &msg, t_msg_priority prio = MSG_INFO); // Ask a yes/no question to the user. // Returns true for yes and false for no. bool cb_ask_msg(const string &msg, t_msg_priority prio = MSG_INFO); bool cb_ask_msg(QWidget *parent, const string &msg, t_msg_priority prio = MSG_INFO); // Display an error message. void cb_display_msg(const string &msg, t_msg_priority prio = MSG_INFO); // Log file has been updated void cb_log_updated(bool log_zapped = false); // Call history has been updated void cb_call_history_updated(void); void cb_missed_call(int num_missed_calls); // Show firewall/NAT discovery progress void cb_nat_discovery_progress_start(int num_steps); void cb_nat_discovery_progress_step(int step); void cb_nat_discovery_finished(void); bool cb_nat_discovery_cancelled(void); // ZRTP void cb_line_encrypted(int line, bool encrypted, const string &cipher_mode = ""); void cb_show_zrtp_sas(int line, const string &sas); void cb_zrtp_confirm_go_clear(int line); void cb_zrtp_sas_confirmed(int line); void cb_zrtp_sas_confirmation_reset(int line); // MWI void cb_update_mwi(void); void cb_mwi_subscribe_failed(t_user *user_config, t_response *r, bool first_failure); void cb_mwi_terminated(t_user *user_config, const string &reason); // Instant messaging bool cb_message_request(t_user *user_config, t_request *r); void cb_message_response(t_user *user_config, t_response *r, t_request *req); void cb_im_iscomposing_request(t_user *user_config, t_request *r, im::t_composing_state state, time_t refresh); void cb_im_iscomposing_not_supported(t_user *user_config, t_response *r); // Execute external commands void cmd_call(const string &destination, bool immediate); void cmd_quit(void); void cmd_show(void); void cmd_hide(void); // Lookup a URL in the address book string get_name_from_abook(t_user *user_config, const t_url &u); // Actions void action_register(list user_list); void action_deregister(list user_list, bool dereg_all); void action_show_registrations(list user_list); void action_invite(t_user *user_config, const t_url &destination, const string &display, const string &subject, bool anonymous); void action_answer(void); void action_bye(void); void action_reject(void); void action_reject(unsigned short line); void action_redirect(const list &contacts); void action_refer(const t_url &destination, const string &display); void action_refer(unsigned short line_from, unsigned short line_to); void action_setup_consultation_call(const t_url &destination, const string &display); void action_hold(void); void action_retrieve(void); void action_conference(void); void action_mute(bool on); void action_options(void); void action_options(t_user *user_config, const t_url &contact); void action_dtmf(const string &digits); void action_activate_line(unsigned short line); bool action_seize(void); void action_unseize(void); void action_confirm_zrtp_sas(int line); void action_confirm_zrtp_sas(); void action_reset_zrtp_sas_confirmation(int line); void action_reset_zrtp_sas_confirmation(); void action_enable_zrtp(void); void action_zrtp_request_go_clear(void); void action_zrtp_go_clear_ok(unsigned short line); // Service (de)activation void srv_dnd(list user_list, bool on); void srv_enable_cf(t_user *user_config, t_cf_type cf_type, const list &cf_dest); void srv_disable_cf(t_user *user_config, t_cf_type cf_type); void srv_auto_answer(list user_list, bool on); // Fill a combo box with user names (display, uri) of active users void fill_user_combo(QComboBox *cb); // Get/set last dir path for a file dialog browse session QString get_last_file_browse_path(void) const; void set_last_file_browse_path(QString path); #ifdef HAVE_KDE // Get the line associated with the sys tray popup unsigned short get_line_sys_tray_popup(void) const; #endif // Get the message session for a dialog between the user // and the remote url. If the display name was not known // to the session yet, it is set to the passed display. // Returns NULL if no form exists. im::t_msg_session *getMessageSession(t_user *user_config, const t_url &remote_url, const string &display) const; void addMessageSession(im::t_msg_session *s); void removeMessageSession(im::t_msg_session *s); void destroyAllMessageSessions(void); /** * Convert a mime type to a file extension. * @param media [in] The mime type. * @return file extension as glob expression. */ string mime2file_extension(t_media media); /** * Open a URL in an external web browser. * @param url [in] URL to open. */ void open_url_in_browser(const QString &url); private slots: /** * Update timers associated with message sessions. This * function should be called every second. */ void updateTimersMessageSessions(); }; #endif twinkle-1.4.2/src/gui/sendfileform.ui.h0000644000175000001440000000601111127714044014724 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_KDE #include #endif void SendFileForm::init() { setWFlags(getWFlags() | Qt::WDestructiveClose); _chooseFileDialog = NULL; } void SendFileForm::destroy() { // Auto destruct window MEMMAN_DELETE(this); if (_chooseFileDialog) { MEMMAN_DELETE(_chooseFileDialog); delete _chooseFileDialog; } } /** Signal the selected information to an observer. */ void SendFileForm::signalSelectedInfo() { if (!QFile::exists(fileLineEdit->text())) { ((t_gui *)ui)->cb_show_msg(this, tr("File does not exist.").ascii(), MSG_WARNING); return; } emit selected(fileLineEdit->text(), subjectLineEdit->text()); accept(); } /** Choose a file from a file dialog. */ void SendFileForm::chooseFile() { #ifdef HAVE_KDE KFileDialog *d = new KFileDialog(QString::null, QString::null, this, 0, true); MEMMAN_NEW(d); d->setOperationMode(KFileDialog::Other); connect(d, SIGNAL(okClicked()), this, SLOT(setFilename())); #else QFileDialog *d = new QFileDialog(QString::null, QString::null, this, 0, true); MEMMAN_NEW(d); connect(d, SIGNAL(fileSelected(const QString &)), this, SLOT(setFilename())); #endif d->setCaption(tr("Send file...")); if (_chooseFileDialog) { MEMMAN_DELETE(_chooseFileDialog); delete _chooseFileDialog; } _chooseFileDialog = d; d->show(); } /** * Set the filename value. * @param filename [in] The value to set. */ void SendFileForm::setFilename() { QString filename; #ifdef HAVE_KDE KFileDialog *d = dynamic_cast(_chooseFileDialog); filename = d->selectedFile(); #else QFileDialog *d = dynamic_cast(_chooseFileDialog); filename = d->selectedFile(); #endif fileLineEdit->setText(filename); } twinkle-1.4.2/src/gui/historyform.ui0000644000175000001440000004554111150237536014423 00000000000000 HistoryForm HistoryForm 0 0 872 647 Twinkle - Call History unnamed Time true true In/Out true true From/To true true Subject true true Status true true historyListView true true LastColumn layout37 unnamed cdrGroupBox Call details unnamed cdrTextEdit RichText NoWrap true AutoAll Details of the selected call record. viewGroupBox View unnamed inCheckBox &Incoming calls Alt+I Check this option to show incoming calls. outCheckBox &Outgoing calls Alt+O Check this option to show outgoing calls. successCheckBox &Answered calls Alt+A Check this option to show answered calls. missedCheckBox &Missed calls Alt+M Check this option to show missed calls. profileCheckBox Current &user profiles only Alt+U Check this option to show only calls associated with this user profile. layout39 unnamed clearPushButton C&lear Alt+L <p>Clear the complete call history.</p> <p><b>Note:</b> this will clear <b>all</b> records, also records not shown depending on the checked view options.</p> spacer28 Horizontal Expanding 540 20 closePushButton Clo&se Alt+S false Close this window. callPushButton &Call Alt+C true Call selected address. layout6 unnamed numberlCallsTtextLabel Number of calls: numberCallsValueTextLabel ### totalDurationTextLabel Total call duration: totalDurationValueTextLabel ### spacer11 Horizontal Expanding 460 20 closePushButton clicked() HistoryForm close() historyListView currentChanged(QListViewItem*) HistoryForm showCallDetails(QListViewItem*) inCheckBox toggled(bool) HistoryForm loadHistory() missedCheckBox toggled(bool) HistoryForm loadHistory() outCheckBox toggled(bool) HistoryForm loadHistory() profileCheckBox toggled(bool) HistoryForm loadHistory() successCheckBox toggled(bool) HistoryForm loadHistory() historyListView rightButtonPressed(QListViewItem*,const QPoint&,int) HistoryForm popupMenu(QListViewItem*,const QPoint&) historyListView doubleClicked(QListViewItem*,const QPoint&,int) HistoryForm call(QListViewItem*) clearPushButton clicked() HistoryForm clearHistory() callPushButton clicked() HistoryForm call() historyListView cdrTextEdit inCheckBox outCheckBox successCheckBox missedCheckBox profileCheckBox clearPushButton closePushButton user.h phone.h qpopupmenu.h call_history.h util.h gui.h qlistview.h historylistview.h qiconset.h audits/memman.h historyform.ui.h extern t_phone *phone; time_t timeLastViewed; QPopupMenu *histPopupMenu; int itemCall; call(t_user *, const QString &, const QString &, bool) loadHistory() update() show() closeEvent( QCloseEvent * e ) showCallDetails( QListViewItem * item ) popupMenu( QListViewItem * item, const QPoint & pos ) call( QListViewItem * item ) call( void ) deleteEntry( void ) clearHistory() init() destroy() twinkle-1.4.2/src/gui/textbrowsernoautolink.h0000644000175000001440000000351111127714044016331 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TEXTBROWSERNOAUTOLINK_H #define _TEXTBROWSERNOAUTOLINK_H #include /** * A text browser similar to QTextBrowser, but when a user clicks a link * the browser will not automatically load the linked document. */ class TextBrowserNoAutoLink : public QTextBrowser { Q_OBJECT public: TextBrowserNoAutoLink ( QWidget * parent = 0, const char * name = 0 ) : QTextBrowser(parent, name) {}; virtual void setSource ( const QString & name ) {}; }; #endif twinkle-1.4.2/src/gui/freedesksystray.cpp0000644000175000001440000001236211127714053015423 00000000000000/*************************************************************************** * Copyright (C) 2004 by Emil Stoyanov * * emosto@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ // 2006 Modified by Michel de Boer #include "freedesksystray.h" FreeDeskSysTray::FreeDeskSysTray ( QWidget *pParent , const char *pszName ) : QLabel(pParent, pszName, WMouseNoMask | WRepaintNoErase | WType_TopLevel | WStyle_Customize | WStyle_NoBorder | WStyle_StaysOnTop) { mainWindow = pParent; trayMenu = new QPopupMenu(this); } void FreeDeskSysTray::dock () { trayMenu->insertSeparator(); trayMenu->insertItem(tr("Show/Hide"), this, SLOT(slotMenuItemShow())) ; QIconSet quitIcon(QPixmap::fromMimeSource("exit.png")); trayMenu->insertItem(quitIcon, tr("Quit"), this, SLOT(slotMenuItemQuit())) ; Display *dpy = QPaintDevice::x11AppDisplay(); WId trayWin = winId(); // System Tray Protocol Specification from freedesktop.org Screen *screen = XDefaultScreenOfDisplay(dpy); int iScreen = XScreenNumberOfScreen(screen); char szAtom[32]; snprintf(szAtom, sizeof(szAtom), "_NET_SYSTEM_TRAY_S%d", iScreen); Atom selectionAtom = XInternAtom(dpy, szAtom, false); XGrabServer(dpy); Window managerWin = XGetSelectionOwner(dpy, selectionAtom); XSelectInput(dpy, managerWin, StructureNotifyMask); XUngrabServer(dpy); XFlush(dpy); XEvent ev; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = managerWin; ev.xclient.message_type = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", true); ev.xclient.format = 32; ev.xclient.data.l[0] = CurrentTime; ev.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK; ev.xclient.data.l[2] = trayWin; ev.xclient.data.l[3] = 0; ev.xclient.data.l[4] = 0; XSendEvent(dpy, managerWin, false, NoEventMask, &ev); XSync(dpy, false); Atom trayAtom; // KDE 3 WId forWin = mainWindow ? mainWindow->topLevelWidget()->winId() : qt_xrootwin(); trayAtom = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", false); XChangeProperty(dpy, trayWin, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char *) &forWin, 1); setMinimumSize(22, 22); setBackgroundMode(Qt::X11ParentRelative); // because of GNOME - needs a wait of at least 50-100 ms, otherwise width=1 // KDocker solves the problem so (bug?) QTimer::singleShot(500, this, SLOT(show())); } void FreeDeskSysTray::undock () { XUnmapWindow(QPaintDevice::x11AppDisplay(), winId()); hide(); } FreeDeskSysTray::~FreeDeskSysTray () {} void FreeDeskSysTray::mousePressEvent ( QMouseEvent *pMouseEvent ) { if (!QLabel::rect().contains(pMouseEvent->pos())) return; switch (pMouseEvent->button()) { case LeftButton: slotMenuItemShow(); break; case RightButton: showContextMenu(pMouseEvent->globalPos()); break; default: break; } } void FreeDeskSysTray::setPixmapOverlay ( const QPixmap& pmOverlay ) { QWidget *pParent = parentWidget(); if (pParent == 0) return; // Get base pixmap from parent widget. QPixmap pm; pm.convertFromImage(pParent->icon()->convertToImage().smoothScale(22, 22), 0); // Merge with the overlay pixmap. QBitmap bmMask(*pm.mask()); bitBlt(&bmMask, 0, 0, pmOverlay.mask(), 0, 0, -1, -1, Qt::OrROP); pm.setMask(bmMask); bitBlt(&pm, 0, 0, &pmOverlay); QLabel::setPixmap(pm); } QPopupMenu *FreeDeskSysTray::contextMenu() { return trayMenu; } void FreeDeskSysTray::setPixmap(const QPixmap& pixmap) { QLabel::setPixmap(pixmap); repaint(true); } void FreeDeskSysTray::showContextMenu(const QPoint& position) { trayMenu->popup(position,0); } void FreeDeskSysTray::slotMenuItemShow() { // mainWindowGeometry = mainWindow->geometry(); // windowPos = mainWindow->frameGeometry().topLeft(); if (mainWindow->isVisible()) { //mainWindow->setGeometry(mainWindowGeometry); mainWindow->close(); } else { // mainWindow->move( windowPos ); // restore position mainWindow->show(); } } void FreeDeskSysTray::slotMenuItemQuit() { emit quitSelected(); } twinkle-1.4.2/src/gui/selectprofileform.ui.h0000644000175000001440000004365111151060015015773 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void SelectProfileForm::init() { user_config = 0; } void SelectProfileForm::destroy() { if (user_config) { MEMMAN_DELETE(user_config); delete user_config; } } // The exec() method is called at startup int SelectProfileForm::execForm() { mainWindow = 0; profileListView->clear(); defaultSet = false; // no default has been set // Get list of all profiles QStringList profiles; QString error; if (!SelectProfileForm::getUserProfiles(profiles, error)) { QMessageBox::critical(this, PRODUCT_NAME, error); return QDialog::Rejected; } // If there are no profiles then the user has to create one if (profiles.isEmpty()) { QMessageBox::information(this, PRODUCT_NAME, tr( ""\ "Before you can use Twinkle, you must create a user "\ "profile.
Click OK to create a profile.")); int newProfileMethod = QMessageBox::question(this, PRODUCT_NAME, tr( ""\ "You can use the profile editor to create a profile. "\ "With the profile editor you can change many settings "\ "to tune the SIP protocol, RTP and many other things.

"\ "Alternatively you can use the wizard to quickly setup a "\ "user profile. The wizard asks you only a few essential "\ "settings. If you create a user profile with the wizard you "\ "can still edit the full profile with the profile editor at a later "\ "time.

"\ "You can create a Diamondcard account to make worldwide "\ "calls to regular and cell phones and send SMS messages.

"\ "Choose what method you wish to use."), tr("&Wizard"), tr("&Profile editor"), tr("&Diamondcard")); switch (newProfileMethod) { case 0: wizardProfile(true); break; case 1: newProfile(true); break; case 2: diamondcardProfile(true); break; default: return QDialog::Rejected; } if (profileListView->childCount() == 0) { // No profile has been created. return QDialog::Rejected; } // Select the created profile QCheckListItem *item = (QCheckListItem *)profileListView->currentItem(); QString profile = item->text(); profile.append(USER_FILE_EXT); selectedProfiles.clear(); selectedProfiles.push_back(profile.ascii()); QMessageBox::information(this, PRODUCT_NAME, tr( ""\ "Next you may adjust the system settings. "\ "You can change these settings always at a later time."\ "

"\ "Click OK to view and adjust the system settings.")); SysSettingsForm f(this, "system settings", true); f.exec(); return QDialog::Accepted; } fillProfileListView(profiles); sysPushButton->show(); runPushButton->setFocus(); // Show the modal dialog return QDialog::exec(); } // The showForm() method is called from File menu when Twinkle is running. // The execForm() method cannot be used as it will block the Qt event loop. // NOTE: the method show() is not re-implemented as Qt calls this method // from exec() internally. void SelectProfileForm::showForm(QMainWindow *_mainWindow) { mainWindow = _mainWindow; profileListView->clear(); defaultSet = false; // Get list of all profiles QStringList profiles; QString error; if (!SelectProfileForm::getUserProfiles(profiles, error)) { QMessageBox::critical(this, PRODUCT_NAME, error); return; } // Initialize profile list view fillProfileListView(profiles); QListViewItemIterator j(profileListView); while (j.current()) { QCheckListItem *item = (QCheckListItem *)j.current(); QString profile = item->text(); // Set pixmap of default profile list l = sys_config->get_start_user_profiles(); if (std::find(l.begin(), l.end(), profile.ascii()) != l.end()) { item->setPixmap(0, QPixmap::fromMimeSource("twinkle16.png")); defaultSet = true; } // Tick check box of active profile if (phone->ref_user_profile(profile.ascii())) { item->setOn(true); } j++; } sysPushButton->hide(); runPushButton->setText("&OK"); runPushButton->setFocus(); QDialog::show(); } void SelectProfileForm::runProfile() { selectedProfiles.clear(); QListViewItemIterator i(profileListView, QListViewItemIterator::Checked); while (i.current()) { QCheckListItem *item = (QCheckListItem *)i.current(); QString profile =item->text(); profile.append(USER_FILE_EXT); selectedProfiles.push_back(profile.ascii()); i++; } if (selectedProfiles.empty()) { QMessageBox::warning(this, PRODUCT_NAME, tr( "You did not select any user profile to run.\n"\ "Please select a profile.")); return; } // This signal will be caught when Twinkle is running. // At startup the selectedProfiles attribute is read. emit selection(selectedProfiles); accept(); } void SelectProfileForm::editProfile() { QCheckListItem *item = (QCheckListItem *)profileListView->currentItem(); QString profile = item->text(); // If the profile to edit is currently active, then edit the in-memory // user profile owned by the t_phone_user object if (mainWindow) { t_user *active_user = phone->ref_user_profile(profile.ascii()); if (active_user) { list user_list; user_list.push_back(active_user); UserProfileForm *f = new UserProfileForm(this, "edit user profile", true, Qt::WDestructiveClose); connect(f, SIGNAL(authCredentialsChanged(t_user *, const string&)), mainWindow, SLOT(updateAuthCache(t_user *, const string&))); connect(f, SIGNAL(stunServerChanged(t_user *)), mainWindow, SLOT(updateStunSettings(t_user *))); f->show(user_list, ""); return; } } // Edit the user profile from disk. profile.append(USER_FILE_EXT); // Read selected config file string error_msg; if (user_config) { MEMMAN_DELETE(user_config); delete user_config; } user_config = new t_user(); MEMMAN_NEW(user_config); if (!user_config->read_config(profile.ascii(), error_msg)) { ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_WARNING); return; } // Show the edit user profile form (modal dialog) list user_list; user_list.push_back(user_config); UserProfileForm *f = new UserProfileForm(this, "edit user profile", true, Qt::WDestructiveClose); f->show(user_list, ""); } void SelectProfileForm::newProfile() { newProfile(false); } void SelectProfileForm::newProfile(bool exec_mode) { // Ask user for a profile name GetProfileNameForm getProfileNameForm(this, "get profile name", true); if (!getProfileNameForm.execNewName()) return; // Create file name QString profile = getProfileNameForm.getProfileName(); QString filename = profile; filename.append(USER_FILE_EXT); // Create a new user config if (user_config) { MEMMAN_DELETE(user_config); delete user_config; } user_config = new t_user(); MEMMAN_NEW(user_config); user_config->set_config(filename.ascii()); // Show the edit user profile form (modal dialog) list user_list; user_list.push_back(user_config); UserProfileForm *f = new UserProfileForm(this, "edit user profile", true, Qt::WDestructiveClose); connect(f, SIGNAL(success()), this, SLOT(newProfileCreated())); if (exec_mode) { f->exec(user_list, ""); } else { f->show(user_list, ""); } } void SelectProfileForm::newProfileCreated() { // New profile created // Add the new profile to the profile list box QCheckListItem *item = new QCheckListItem(profileListView, user_config->get_profile_name().c_str(), QCheckListItem::CheckBox); item->setPixmap(0, QPixmap::fromMimeSource("penguin-small.png")); // Make the new profile the selected profile // Do not change this without changing the exec method. // When there are no profiles, the exec methods relies on the // fact that afer creation of the profile it is selected. profileListView->setSelected(item, true); // Enable buttons that act on a profile editPushButton->setEnabled(true); deletePushButton->setEnabled(true); renamePushButton->setEnabled(true); defaultPushButton->setEnabled(true); runPushButton->setEnabled(true); } void SelectProfileForm::deleteProfile() { QCheckListItem *item = (QCheckListItem *)profileListView->currentItem(); QString profile = item->text(); QString msg = tr("Are you sure you want to delete profile '%1'?").arg(profile); QMessageBox *mb = new QMessageBox(tr("Delete profile"), msg, QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton, this); MEMMAN_NEW(mb); if (mb->exec() == QMessageBox::Yes) { // Delete file QDir d = QDir::home(); d.cd(USER_DIR); QString filename = profile; filename.append(USER_FILE_EXT); QString fullname = d.filePath(filename); if (!QFile::remove(fullname)) { // Failed to delete file QMessageBox::critical(this, PRODUCT_NAME, tr("Failed to delete profile.")); } else { // Delete possible backup of the profile QString backupname = fullname; backupname.append("~"); (void)QFile::remove(backupname); // Delete service files filename = profile; filename.append(SVC_FILE_EXT); fullname = d.filePath(filename); (void)QFile::remove(fullname); fullname.append("~"); (void)QFile::remove(fullname); // Delete profile from list of default profiles in // system settings list l = sys_config->get_start_user_profiles(); if (std::find(l.begin(), l.end(), profile.ascii()) != l.end()) { l.remove(profile.ascii()); sys_config->set_start_user_profiles(l); string error_msg; if (!sys_config->write_config(error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); } } // Delete profile from profile list box QCheckListItem *item = (QCheckListItem *)profileListView-> currentItem(); delete item; if (profileListView->childCount() == 0) { // There are no profiles anymore // Disable buttons that act on a profile editPushButton->setEnabled(false); deletePushButton->setEnabled(false); renamePushButton->setEnabled(false); defaultPushButton->setEnabled(false); runPushButton->setEnabled(false); } else { profileListView->setSelected(profileListView-> firstChild(), true); } } } MEMMAN_DELETE(mb); delete mb; } void SelectProfileForm::renameProfile() { QCheckListItem *item = (QCheckListItem *)profileListView->currentItem(); QString oldProfile = item->text(); // Ask user for a new profile name GetProfileNameForm getProfileNameForm(this, "get profile name", true); if (!getProfileNameForm.execRename(oldProfile)) return; // Create file name for the new profile QString newProfile = getProfileNameForm.getProfileName(); QString newFilename = newProfile; newFilename.append(USER_FILE_EXT); // Create file name for the old profile QString oldFilename = oldProfile; oldFilename.append(USER_FILE_EXT); // Rename the file QDir d = QDir::home(); d.cd(USER_DIR); if (!d.rename(oldFilename, newFilename)) { // Failed to delete file QMessageBox::critical(this, PRODUCT_NAME, tr("Failed to rename profile.")); } else { // If there is a backup of the profile, rename it too. QString oldBackupFilename = oldFilename; oldBackupFilename.append("~"); QString oldBackupFullname = d.filePath(oldBackupFilename); if (QFile::exists(oldBackupFullname)) { QString newBackupFilename = newFilename; newBackupFilename.append("~"); d.rename(oldBackupFilename, newBackupFilename); } // Rename service files oldFilename = oldProfile; oldFilename.append(SVC_FILE_EXT); QString oldFullname = d.filePath(oldFilename); if (QFile::exists(oldFullname)) { newFilename = newProfile; newFilename.append(SVC_FILE_EXT); d.rename(oldFilename, newFilename); } // Rename service backup file oldFilename.append("~"); oldFullname = d.filePath(oldFilename); if (QFile::exists(oldFullname)) { newFilename.append("~"); d.rename(oldFilename, newFilename); } // Rename buddy list file oldFilename = oldProfile; oldFilename.append(BUDDY_FILE_EXT); oldFullname = d.filePath(oldFilename); if (QFile::exists(oldFullname)) { newFilename = newProfile; newFilename.append(BUDDY_FILE_EXT); d.rename(oldFilename, newFilename); } // Rename profile in list of default profiles in // system settings list l = sys_config->get_start_user_profiles(); if (std::find(l.begin(), l.end(), oldProfile.ascii()) != l.end()) { std::replace(l.begin(), l.end(), oldProfile.ascii(), newProfile.ascii()); sys_config->set_start_user_profiles(l); string error_msg; if (!sys_config->write_config(error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); } } emit profileRenamed(); // Change profile name in the list box QCheckListItem *item = (QCheckListItem *)profileListView->currentItem(); item->setText(0, newProfile); } } void SelectProfileForm::setAsDefault() { // Only show the information when the default button is // pressed for the first time. if (!defaultSet) { QMessageBox::information(this, PRODUCT_NAME, tr( "

" "If you want to remove or " "change the default at a later time, you can do that " "via the system settings." "

")); } defaultSet = true; // Restore all pixmaps QListViewItemIterator i(profileListView); while (i.current()) { i.current()->setPixmap(0, QPixmap::fromMimeSource("penguin-small.png")); i++; } // Set pixmap of the default profiles. // Set default profiles in system settings. list l; QListViewItemIterator j(profileListView, QListViewItemIterator::Checked); while (j.current()) { QCheckListItem *item = (QCheckListItem *)j.current(); item->setPixmap(0, QPixmap::fromMimeSource("twinkle16.png")); l.push_back(item->text().ascii()); j++; } sys_config->set_start_user_profiles(l); // Write default to system settings string error_msg; if (!sys_config->write_config(error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); } } void SelectProfileForm::wizardProfile() { wizardProfile(false); } void SelectProfileForm::wizardProfile(bool exec_mode) { // Ask user for a profile name GetProfileNameForm getProfileNameForm(this, "get profile name", true); if (!getProfileNameForm.execNewName()) return; // Create file name QString profile = getProfileNameForm.getProfileName(); QString filename = profile; filename.append(USER_FILE_EXT); // Create a new user config if (user_config) { MEMMAN_DELETE(user_config); delete user_config; } user_config = new t_user(); MEMMAN_NEW(user_config); user_config->set_config(filename.ascii()); // Show the wizard form (modal dialog) WizardForm *f = new WizardForm(this, "wizard", true, Qt::WDestructiveClose); connect(f, SIGNAL(success()), this, SLOT(newProfileCreated())); if (exec_mode) { f->exec(user_config); } else { f->show(user_config); } } void SelectProfileForm::diamondcardProfile() { diamondcardProfile(false); } void SelectProfileForm::diamondcardProfile(bool exec_mode) { // Create a new user config if (user_config) { MEMMAN_DELETE(user_config); delete user_config; } user_config = new t_user(); MEMMAN_NEW(user_config); // Show the diamondcard profile form (modal dialog) DiamondcardProfileForm *f = new DiamondcardProfileForm(this, "diamondcard", true, Qt::WDestructiveClose); connect(f, SIGNAL(success()), this, SLOT(newProfileCreated())); if (exec_mode) { f->exec(user_config); } else { f->show(user_config); } } void SelectProfileForm::sysSettings() { SysSettingsForm *f = new SysSettingsForm(this, "system settings", true, Qt::WDestructiveClose); f->show(); } // Get a list of all profiles. Returns false if there is an error. bool SelectProfileForm::getUserProfiles(QStringList &profiles, QString &error) { // Find the .twinkle directory in HOME QDir d = QDir::home(); if (!d.cd(USER_DIR)) { error = tr("Cannot find .twinkle directory in your home directory."); return false; } // Select all config files QString filterName = "*"; filterName.append(USER_FILE_EXT); d.setFilter(QDir::Files); d.setNameFilter(filterName); d.setSorting(QDir::Name | QDir::IgnoreCase); profiles = d.entryList(); return true; } void SelectProfileForm::fillProfileListView(const QStringList &profiles) { // Put the profiles in the profile list view for (QStringList::ConstIterator i = profiles.begin(); i != profiles.end(); i++) { // Strip off the user file extension QString profile = *i; profile.truncate(profile.length() - strlen(USER_FILE_EXT)); QCheckListItem *item = new QCheckListItem( profileListView, profile, QCheckListItem::CheckBox); item->setPixmap(0, QPixmap::fromMimeSource("penguin-small.png")); } // Highlight the first profile profileListView->setSelected(profileListView->firstChild(), true); } void SelectProfileForm::toggleItem(QListViewItem *item) { QCheckListItem *checkItem = (QCheckListItem *)item; checkItem->setOn(!checkItem->isOn()); } twinkle-1.4.2/src/gui/userprofileform.ui.h0000644000175000001440000014445011146337633015512 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Indices of categories in the category list box #define idxCatUser 0 #define idxCatSipServer 1 #define idxCatVoiceMail 2 #define idxCatIM 3 #define idxCatPresence 4 #define idxCatRtpAudio 5 #define idxCatSipProtocol 6 #define idxCatNat 7 #define idxCatAddrFmt 8 #define idxCatTimers 9 #define idxCatRingTones 10 #define idxCatScripts 11 #define idxCatSecurity 12 // Indices of call hold variants in the call hold variant list box #define idxHoldRfc2543 0 #define idxHoldRfc3264 1 // Indices of SIP extension support types in the list box #define idxExtDisabled 0 #define idxExtSupported 1 #define idxExtRequired 2 #define idxExtPreferred 3 // Indices of RTP audio tabs #define idxRtpCodecs 0 #define idxRtpPreprocessing 1 #define idxRtpIlbc 2 #define idxRtpSpeex 3 #define idxRtpDtmf 4 // Codec labels #define labelCodecG711a "G.711 A-law" #define labelCodecG711u "G.711 u-law" #define labelCodecGSM "GSM" #define labelCodecSpeexNb "speex-nb (8 kHz)" #define labelCodecSpeexWb "speex-wb (16 kHz)" #define labelCodecSpeexUwb "speex-uwb (32 kHz)" #define labelCodecIlbc "iLBC" #define labelCodecG726_16 "G.726 16 kbps" #define labelCodecG726_24 "G.726 24 kbps" #define labelCodecG726_32 "G.726 32 kbps" #define labelCodecG726_40 "G.726 40 kbps" // Indices of iLBC modes #define idxIlbcMode20 0 #define idxIlbcMode30 1 // Indices of G.726 packing modes #define idxG726PackRfc3551 0 #define idxG726PackAal2 1 // Indices of DTMF transport modes in the DTMF transport list box #define idxDtmfAuto 0 #define idxDtmfRfc2833 1 #define idxDtmfInband 2 #define idxDtmfInfo 3 // Columns in the number conversion list view #define colExpr 0 #define colReplace 1 // MWI type indices #define idxMWIUnsollicited 0 #define idxMWISollicited 1 // SIP transport protocol indices #define idxSipTransportAuto 0 #define idxSipTransportUDP 1 #define idxSipTransportTCP 2 void UserProfileForm::init() { QRegExp rxNoSpace("\\S*"); QRegExp rxNoAtSign("[^@]*"); QRegExp rxQvalue("(0\\.[0-9]{0,3})|(1\\.0{0,3})"); QRegExp rxAkaOpValue("[a-zA-Z0-9]{0,32}"); QRegExp rxAkaAmfValue("[a-zA-Z0-9]{0,4}"); // Set validators // USER domainLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); authAkaOpLineEdit->setValidator(new QRegExpValidator(rxAkaOpValue, this)); authAkaAmfLineEdit->setValidator(new QRegExpValidator(rxAkaAmfValue, this)); // SIP SERVER registrarLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); regQvalueLineEdit->setValidator(new QRegExpValidator(rxQvalue, this)); proxyLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); // Voice mail mwiServerLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); // NAT publicIPLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); // Address format testConversionLineEdit->setValidator(new QRegExpValidator(rxNoAtSign, this)); #ifndef HAVE_SPEEX // Speex & (Speex) Preprocessing speexGroupBox->hide(); preprocessingGroupBox->hide(); rtpAudioTabWidget->setTabEnabled(rtpAudioTabWidget->page(idxRtpSpeex), false); rtpAudioTabWidget->setTabEnabled(rtpAudioTabWidget->page(idxRtpPreprocessing), false); #endif #ifndef HAVE_ILBC // iLBC ilbcGroupBox->hide(); rtpAudioTabWidget->setTabEnabled(rtpAudioTabWidget->page(idxRtpIlbc), false); #endif #ifndef HAVE_ZRTP // Zrtp zrtpEnabledCheckBox->setEnabled(false); zrtpSettingsGroupBox->hide(); #endif // Set toolbutton icons for disabled options. QIconSet i; i = openRingtoneToolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource("fileopen-disabled.png"), QIconSet::Automatic, QIconSet::Disabled); openRingtoneToolButton->setIconSet(i); openRingbackToolButton->setIconSet(i); openIncomingCallScriptToolButton->setIconSet(i); } void UserProfileForm::showCategory( int index ) { if (index == idxCatUser) { settingsWidgetStack->raiseWidget(pageUser); } else if (index == idxCatSipServer) { settingsWidgetStack->raiseWidget(pageSipServer); } else if (index == idxCatVoiceMail) { settingsWidgetStack->raiseWidget(pageVoiceMail); } else if (index == idxCatIM) { settingsWidgetStack->raiseWidget(pageIM); } else if (index == idxCatPresence) { settingsWidgetStack->raiseWidget(pagePresence); } else if (index == idxCatRtpAudio) { settingsWidgetStack->raiseWidget(pageRtpAudio); } else if (index == idxCatSipProtocol) { settingsWidgetStack->raiseWidget(pageSipProtocol); } else if (index == idxCatNat) { settingsWidgetStack->raiseWidget(pageNat); } else if (index == idxCatAddrFmt) { settingsWidgetStack->raiseWidget(pageAddressFormat); } else if (index == idxCatTimers) { settingsWidgetStack->raiseWidget(pageTimers); } else if (index == idxCatRingTones) { settingsWidgetStack->raiseWidget(pageRingTones); } else if (index == idxCatScripts) { settingsWidgetStack->raiseWidget(pageScripts); } else if (index == idxCatSecurity) { settingsWidgetStack->raiseWidget(pageSecurity); } } // Convert a label to a codec t_audio_codec UserProfileForm::label2codec(const QString &label) { if (label == labelCodecG711a) { return CODEC_G711_ALAW; } else if (label == labelCodecG711u) { return CODEC_G711_ULAW; } else if (label == labelCodecGSM) { return CODEC_GSM; } else if (label == labelCodecSpeexNb) { return CODEC_SPEEX_NB; } else if (label == labelCodecSpeexWb) { return CODEC_SPEEX_WB; } else if (label == labelCodecSpeexUwb) { return CODEC_SPEEX_UWB; } else if (label == labelCodecIlbc) { return CODEC_ILBC; } else if (label == labelCodecG726_16) { return CODEC_G726_16; } else if (label == labelCodecG726_24) { return CODEC_G726_24; } else if (label == labelCodecG726_32) { return CODEC_G726_32; } else if (label == labelCodecG726_40) { return CODEC_G726_40; } return CODEC_NULL; } // Convert a codec to a label QString UserProfileForm::codec2label(t_audio_codec &codec) { switch (codec) { case CODEC_G711_ALAW: return labelCodecG711a; case CODEC_G711_ULAW: return labelCodecG711u; case CODEC_GSM: return labelCodecGSM; case CODEC_SPEEX_NB: return labelCodecSpeexNb; case CODEC_SPEEX_WB: return labelCodecSpeexWb; case CODEC_SPEEX_UWB: return labelCodecSpeexUwb; case CODEC_ILBC: return labelCodecIlbc; case CODEC_G726_16: return labelCodecG726_16; case CODEC_G726_24: return labelCodecG726_24; case CODEC_G726_32: return labelCodecG726_32; case CODEC_G726_40: return labelCodecG726_40; default: return ""; } } // Convert t_ext_support to an index in the SIP extension combo box int UserProfileForm::ext_support2indexComboItem(t_ext_support ext) { switch(ext) { case EXT_DISABLED: return idxExtDisabled; case EXT_SUPPORTED: return idxExtSupported; case EXT_REQUIRED: return idxExtRequired; case EXT_PREFERRED: return idxExtPreferred; default: return idxExtDisabled; } return idxExtDisabled; } t_ext_support UserProfileForm::indexComboItem2ext_support(int index) { switch(index) { case idxExtDisabled: return EXT_DISABLED; case idxExtSupported: return EXT_SUPPORTED; case idxExtRequired: return EXT_REQUIRED; case idxExtPreferred: return EXT_PREFERRED; } return EXT_DISABLED; } // Populate the form void UserProfileForm::populate() { QString s; // Set user profile name in the titlebar s = PRODUCT_NAME; s.append(" - ").append(tr("User profile:")).append(" "); s.append(current_profile->get_profile_name().c_str()); setCaption(s); // Select the User category categoryListBox->setSelected(idxCatUser, true); settingsWidgetStack->raiseWidget(pageUser); // Set focus on first field displayLineEdit->setFocus(); // Set the values of the current_profile object in the form // USER displayLineEdit->setText(current_profile->get_display(false).c_str()); usernameLineEdit->setText(current_profile->get_name().c_str()); domainLineEdit->setText(current_profile->get_domain().c_str()); organizationLineEdit->setText(current_profile->get_organization().c_str()); authRealmLineEdit->setText(current_profile->get_auth_realm().c_str()); authNameLineEdit->setText(current_profile->get_auth_name().c_str()); authPasswordLineEdit->setText(current_profile->get_auth_pass().c_str()); uint8 aka_op[AKA_OPLEN]; current_profile->get_auth_aka_op(aka_op); authAkaOpLineEdit->setText(binary2hex(aka_op, AKA_OPLEN).c_str()); uint8 aka_amf[AKA_AMFLEN]; current_profile->get_auth_aka_amf(aka_amf); authAkaAmfLineEdit->setText(binary2hex(aka_amf, AKA_AMFLEN).c_str()); // SIP SERVER registrarLineEdit->setText(current_profile->get_registrar().encode_noscheme().c_str()); expirySpinBox->setValue(current_profile->get_registration_time()); regAtStartupCheckBox->setChecked(current_profile->get_register_at_startup()); regAddQvalueCheckBox->setChecked(current_profile->get_reg_add_qvalue()); regQvalueLineEdit->setEnabled(current_profile->get_reg_add_qvalue()); regQvalueLineEdit->setText(float2str(current_profile->get_reg_qvalue(), 3).c_str()); useProxyCheckBox->setChecked(current_profile->get_use_outbound_proxy()); proxyTextLabel->setEnabled(current_profile->get_use_outbound_proxy()); proxyLineEdit->setEnabled(current_profile->get_use_outbound_proxy()); if (current_profile->get_use_outbound_proxy()) { proxyLineEdit->setText(current_profile-> get_outbound_proxy().encode_noscheme().c_str()); } else { proxyLineEdit->clear(); } allRequestsCheckBox->setChecked(current_profile->get_all_requests_to_proxy()); allRequestsCheckBox->setEnabled(current_profile->get_use_outbound_proxy()); proxyNonResolvableCheckBox->setChecked(current_profile->get_non_resolvable_to_proxy()); proxyNonResolvableCheckBox->setEnabled(current_profile->get_use_outbound_proxy()); // VOICE MAIL vmAddressLineEdit->setText(current_profile->get_mwi_vm_address().c_str()); if (current_profile->get_mwi_sollicited()) { mwiTypeComboBox->setCurrentItem(idxMWISollicited); mwiSollicitedGroupBox->setEnabled(true); } else { mwiTypeComboBox->setCurrentItem(idxMWIUnsollicited); mwiSollicitedGroupBox->setEnabled(false); } mwiUserLineEdit->setText(current_profile->get_mwi_user().c_str()); mwiServerLineEdit->setText(current_profile-> get_mwi_server().encode_noscheme().c_str()); mwiViaProxyCheckBox->setChecked(current_profile->get_mwi_via_proxy()); mwiDurationSpinBox->setValue(current_profile->get_mwi_subscription_time()); // INSTANT MESSAGE imMaxSessionsSpinBox->setValue(current_profile->get_im_max_sessions()); isComposingCheckBox->setChecked(current_profile->get_im_send_iscomposing()); // PRESENCE presPublishCheckBox->setChecked(current_profile->get_pres_publish_startup()); presPublishTimeSpinBox->setValue(current_profile->get_pres_publication_time()); presSubscribeTimeSpinBox->setValue(current_profile->get_pres_subscription_time()); // RTP AUDIO // Codecs QStringList allCodecs; allCodecs.append(labelCodecG711a); allCodecs.append(labelCodecG711u); allCodecs.append(labelCodecGSM); #ifdef HAVE_SPEEX allCodecs.append(labelCodecSpeexNb); allCodecs.append(labelCodecSpeexWb); allCodecs.append(labelCodecSpeexUwb); #endif #ifdef HAVE_ILBC allCodecs.append(labelCodecIlbc); #endif allCodecs.append(labelCodecG726_16); allCodecs.append(labelCodecG726_24); allCodecs.append(labelCodecG726_32); allCodecs.append(labelCodecG726_40); activeCodecListBox->clear(); list audio_codecs = current_profile->get_codecs(); for (list::iterator i = audio_codecs.begin(); i != audio_codecs.end(); i++) { activeCodecListBox->insertItem(codec2label(*i)); allCodecs.remove(codec2label(*i)); } availCodecListBox->clear(); if (!allCodecs.empty()) availCodecListBox->insertStringList(allCodecs); // G.711/G.726 ptime ptimeSpinBox->setValue(current_profile->get_ptime()); // Codec preference inFarEndCodecPrefCheckBox->setChecked(current_profile->get_in_obey_far_end_codec_pref()); outFarEndCodecPrefCheckBox->setChecked(current_profile->get_out_obey_far_end_codec_pref()); // Speex preprocessing and AEC spxDspVadCheckBox->setChecked(current_profile->get_speex_dsp_vad()); spxDspAgcCheckBox->setChecked(current_profile->get_speex_dsp_agc()); spxDspAecCheckBox->setChecked(current_profile->get_speex_dsp_aec()); spxDspNrdCheckBox->setChecked(current_profile->get_speex_dsp_nrd()); spxDspAgcLevelSpinBox->setValue(current_profile->get_speex_dsp_agc_level()); spxDspAgcLevelTextLabel->setEnabled(current_profile->get_speex_dsp_agc()); spxDspAgcLevelSpinBox->setEnabled(current_profile->get_speex_dsp_agc()); // Speex ([en/de]coding) spxVbrCheckBox->setChecked(current_profile->get_speex_bit_rate_type() == BIT_RATE_VBR); spxDtxCheckBox->setChecked(current_profile->get_speex_dtx()); spxPenhCheckBox->setChecked(current_profile->get_speex_penh()); spxQualitySpinBox->setValue(current_profile->get_speex_quality()); spxComplexitySpinBox->setValue(current_profile->get_speex_complexity()); spxNbPayloadSpinBox->setValue(current_profile->get_speex_nb_payload_type()); spxWbPayloadSpinBox->setValue(current_profile->get_speex_wb_payload_type()); spxUwbPayloadSpinBox->setValue(current_profile->get_speex_uwb_payload_type()); // iLBC ilbcPayloadSpinBox->setValue(current_profile->get_ilbc_payload_type()); if (current_profile->get_ilbc_mode() == 20) { ilbcPayloadSizeComboBox->setCurrentItem(idxIlbcMode20); } else { ilbcPayloadSizeComboBox->setCurrentItem(idxIlbcMode30); } // G.726 g72616PayloadSpinBox->setValue(current_profile->get_g726_16_payload_type()); g72624PayloadSpinBox->setValue(current_profile->get_g726_24_payload_type()); g72632PayloadSpinBox->setValue(current_profile->get_g726_32_payload_type()); g72640PayloadSpinBox->setValue(current_profile->get_g726_40_payload_type()); if (current_profile->get_g726_packing() == G726_PACK_RFC3551) { g726PackComboBox->setCurrentItem(idxG726PackRfc3551); } else { g726PackComboBox->setCurrentItem(idxG726PackAal2); } // DTMF switch (current_profile->get_dtmf_transport()) { case DTMF_RFC2833: dtmfTransportComboBox->setCurrentItem(idxDtmfRfc2833); break; case DTMF_INBAND: dtmfTransportComboBox->setCurrentItem(idxDtmfInband); break; case DTMF_INFO: dtmfTransportComboBox->setCurrentItem(idxDtmfInfo); break; default: dtmfTransportComboBox->setCurrentItem(idxDtmfAuto); break; } dtmfPayloadTypeSpinBox->setValue(current_profile->get_dtmf_payload_type()); dtmfDurationSpinBox->setValue(current_profile->get_dtmf_duration()); dtmfPauseSpinBox->setValue(current_profile->get_dtmf_pause()); dtmfVolumeSpinBox->setValue(-(current_profile->get_dtmf_volume())); // SIP PROTOCOL switch (current_profile->get_hold_variant()) { case HOLD_RFC2543: holdVariantComboBox->setCurrentItem(idxHoldRfc2543); break; default: holdVariantComboBox->setCurrentItem(idxHoldRfc3264); break; } maxForwardsCheckBox->setChecked(current_profile->get_check_max_forwards()); missingContactCheckBox->setChecked(current_profile->get_allow_missing_contact_reg()); regTimeCheckBox->setChecked(current_profile->get_registration_time_in_contact()); compactHeadersCheckBox->setChecked(current_profile->get_compact_headers()); multiValuesListCheckBox->setChecked( current_profile->get_encode_multi_values_as_list()); useDomainInContactCheckBox->setChecked( current_profile->get_use_domain_in_contact()); allowSdpChangeCheckBox->setChecked(current_profile->get_allow_sdp_change()); allowRedirectionCheckBox->setChecked(current_profile->get_allow_redirection()); askUserRedirectCheckBox->setEnabled(current_profile->get_allow_redirection()); askUserRedirectCheckBox->setChecked(current_profile->get_ask_user_to_redirect()); maxRedirectTextLabel->setEnabled(current_profile->get_allow_redirection()); maxRedirectSpinBox->setEnabled(current_profile->get_allow_redirection()); maxRedirectSpinBox->setValue(current_profile->get_max_redirections()); ext100relComboBox->setCurrentItem( ext_support2indexComboItem(current_profile->get_ext_100rel())); extReplacesCheckBox->setChecked(current_profile->get_ext_replaces()); allowReferCheckBox->setChecked(current_profile->get_allow_refer()); askUserReferCheckBox->setEnabled(current_profile->get_allow_refer()); askUserReferCheckBox->setChecked(current_profile->get_ask_user_to_refer()); refereeHoldCheckBox->setEnabled(current_profile->get_allow_refer()); refereeHoldCheckBox->setChecked(current_profile->get_referee_hold()); referrerHoldCheckBox->setChecked(current_profile->get_referrer_hold()); refreshReferSubCheckBox->setChecked(current_profile->get_auto_refresh_refer_sub()); referAorCheckBox->setChecked(current_profile->get_attended_refer_to_aor()); transferConsultInprogCheckBox->setChecked( current_profile->get_allow_transfer_consultation_inprog()); pPreferredIdCheckBox->setChecked(current_profile->get_send_p_preferred_id()); // Transport/NAT switch (current_profile->get_sip_transport()) { case SIP_TRANS_UDP: sipTransportComboBox->setCurrentItem(idxSipTransportUDP); break; case SIP_TRANS_TCP: sipTransportComboBox->setCurrentItem(idxSipTransportTCP); break; default: sipTransportComboBox->setCurrentItem(idxSipTransportAuto); break; } udpThresholdSpinBox->setValue(current_profile->get_sip_transport_udp_threshold()); udpThresholdTextLabel->setEnabled(current_profile->get_sip_transport() == SIP_TRANS_AUTO); udpThresholdSpinBox->setEnabled(current_profile->get_sip_transport() == SIP_TRANS_AUTO); if (current_profile->get_use_nat_public_ip()) { natStaticRadioButton->setChecked(true); } else if (current_profile->get_use_stun()) { natStunRadioButton->setChecked(true); } else { natNoneRadioButton->setChecked(true); } publicIPTextLabel->setEnabled(current_profile->get_use_nat_public_ip()); publicIPLineEdit->setEnabled(current_profile->get_use_nat_public_ip()); publicIPLineEdit->setText(current_profile->get_nat_public_ip().c_str()); stunServerTextLabel->setEnabled(current_profile->get_use_stun()); stunServerLineEdit->setEnabled(current_profile->get_use_stun()); stunServerLineEdit->setText(current_profile->get_stun_server(). encode_noscheme().c_str()); persistentTcpCheckBox->setChecked(current_profile->get_persistent_tcp()); persistentTcpCheckBox->setEnabled(current_profile->get_sip_transport() == SIP_TRANS_TCP); natKeepaliveCheckBox->setChecked(current_profile->get_enable_nat_keepalive()); natKeepaliveCheckBox->setDisabled(current_profile->get_use_stun()); // ADDRESS FORMAT displayTelUserCheckBox->setChecked(current_profile->get_display_useronly_phone()); numericalUserIsTelCheckBox->setChecked( current_profile->get_numerical_user_is_phone()); removeSpecialCheckBox->setChecked( current_profile->get_remove_special_phone_symbols()); specialLineEdit->setText(current_profile->get_special_phone_symbols().c_str()); useTelUriCheckBox->setChecked(current_profile->get_use_tel_uri_for_phone()); conversionListView->clear(); conversionListView->setSorting(-1); list conversions = current_profile->get_number_conversions(); for (list::reverse_iterator i = conversions.rbegin(); i != conversions.rend(); i++) { new QListViewItem(conversionListView, i->re.str().c_str(), i->fmt.c_str()); } // TIMERS tmrNoanswerSpinBox->setValue(current_profile->get_timer_noanswer()); tmrNatKeepaliveSpinBox->setValue(current_profile->get_timer_nat_keepalive()); // RING TONES ringtoneLineEdit->setText(current_profile->get_ringtone_file().c_str()); ringbackLineEdit->setText(current_profile->get_ringback_file().c_str()); // SCRIPTS incomingCallScriptLineEdit->setText(current_profile->get_script_incoming_call().c_str()); inCallAnsweredLineEdit->setText(current_profile->get_script_in_call_answered().c_str()); inCallFailedLineEdit->setText(current_profile->get_script_in_call_failed().c_str()); outCallLineEdit->setText(current_profile->get_script_outgoing_call().c_str()); outCallAnsweredLineEdit->setText(current_profile->get_script_out_call_answered().c_str()); outCallFailedLineEdit->setText(current_profile->get_script_out_call_failed().c_str()); localReleaseLineEdit->setText(current_profile->get_script_local_release().c_str()); remoteReleaseLineEdit->setText(current_profile->get_script_remote_release().c_str()); // Security zrtpEnabledCheckBox->setChecked(current_profile->get_zrtp_enabled()); zrtpSettingsGroupBox->setEnabled(current_profile->get_zrtp_enabled()); zrtpSendIfSupportedCheckBox->setChecked(current_profile->get_zrtp_send_if_supported()); zrtpSdpCheckBox->setChecked(current_profile->get_zrtp_sdp()); zrtpGoClearWarningCheckBox->setChecked(current_profile->get_zrtp_goclear_warning()); } void UserProfileForm::initProfileList(list profiles, QString show_profile_name) { profile_list = profiles; // Initialize user profile combo box current_profile_idx = -1; profileComboBox->clear(); t_user *show_profile = NULL; int show_idx = 0; int idx = 0; for (list::iterator i = profile_list.begin(); i != profile_list.end(); i++) { profileComboBox->insertItem((*i)->get_profile_name().c_str()); if (show_profile_name == (*i)->get_profile_name().c_str()) { show_idx = idx; show_profile = *i; } idx++; } profileComboBox->setEnabled(profile_list.size() > 1); current_profile_idx = show_idx; if (show_profile == NULL) { current_profile = profile_list.front(); } else { current_profile = show_profile; } profileComboBox->setCurrentItem(current_profile_idx); } // Show the form void UserProfileForm::show(list profiles, QString show_profile) { map_last_cat.clear(); initProfileList(profiles, show_profile); populate(); // Show form QDialog::show(); } // Modal execution int UserProfileForm::exec(list profiles, QString show_profile) { map_last_cat.clear(); initProfileList(profiles, show_profile); populate(); return QDialog::exec(); } bool UserProfileForm::check_dynamic_payload(QSpinBox *spb, QValueList &checked_list) { if (checked_list.contains(spb->value())) { categoryListBox->setSelected(idxCatRtpAudio, true); settingsWidgetStack->raiseWidget(pageRtpAudio); QString msg = tr("Dynamic payload type %1 is used more than once.").arg(spb->value()); ((t_gui *)ui)->cb_show_msg(this, msg.ascii(), MSG_CRITICAL); spb->setFocus(); return false; } checked_list.append(spb->value()); return true; } list UserProfileForm::get_number_conversions() { list conversions; QListViewItemIterator it(conversionListView); while (it.current()) { QListViewItem *item = it.current(); t_number_conversion c; try { c.re.assign(item->text(colExpr).ascii()); c.fmt = item->text(colReplace).ascii(); conversions.push_back(c); } catch (boost::bad_expression) { // Should never happen as validity has been // checked already. Just being defensive here. } ++it; } return conversions; } bool UserProfileForm::validateValues() { QString s; // Validity check user page // SIP username is mandatory if (usernameLineEdit->text().isEmpty()) { categoryListBox->setSelected(idxCatUser, true); settingsWidgetStack->raiseWidget(pageUser); ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a user name for your SIP account.").ascii(), MSG_CRITICAL); usernameLineEdit->setFocus(); return false; } // SIP user domain is mandatory if (domainLineEdit->text().isEmpty()) { categoryListBox->setSelected(idxCatUser, true); settingsWidgetStack->raiseWidget(pageUser); ((t_gui *)ui)->cb_show_msg(this, tr( "You must fill in a domain name for your SIP account.\n" "This could be the hostname or IP address of your PC " "if you want direct PC to PC dialing.").ascii(), MSG_CRITICAL); domainLineEdit->setFocus(); return false; } // Check validity of domain s = USER_SCHEME; s.append(':').append(domainLineEdit->text()); t_url u_domain(s.ascii()); if (!u_domain.is_valid() || u_domain.get_user() != "") { categoryListBox->setSelected(idxCatUser, true); settingsWidgetStack->raiseWidget(pageUser); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid domain.").ascii(), MSG_CRITICAL); domainLineEdit->setFocus(); return false; } // Check validity of user s = USER_SCHEME; s.append(':').append(usernameLineEdit->text()).append('@'); s.append(domainLineEdit->text()); t_url u_user_domain(s.ascii()); if (!u_user_domain.is_valid()) { categoryListBox->setSelected(idxCatUser, true); settingsWidgetStack->raiseWidget(pageUser); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid user name.").ascii(), MSG_CRITICAL); usernameLineEdit->setFocus(); return false; } // Registrar if (!registrarLineEdit->text().isEmpty()) { s = USER_SCHEME; s.append(':').append(registrarLineEdit->text()); t_url u(s.ascii()); if (!u.is_valid() || u.get_user() != "") { categoryListBox->setSelected(idxCatSipServer, true); settingsWidgetStack->raiseWidget(pageSipServer); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid value for registrar.").ascii(), MSG_CRITICAL); registrarLineEdit->setFocus(); registrarLineEdit->selectAll(); return false; } } // Outbound proxy if (useProxyCheckBox->isChecked()) { s = USER_SCHEME; s.append(':').append(proxyLineEdit->text()); t_url u(s.ascii()); if (!u.is_valid() || u.get_user() != "") { categoryListBox->setSelected(idxCatSipServer, true); settingsWidgetStack->raiseWidget(pageSipServer); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid value for outbound proxy.").ascii(), MSG_CRITICAL); proxyLineEdit->setFocus(); proxyLineEdit->selectAll(); return false; } } // Validity check voice mail page if (mwiTypeComboBox->currentItem() == idxMWISollicited) { // Mailbox user name is mandatory if (mwiUserLineEdit->text().isEmpty()) { categoryListBox->setSelected(idxCatVoiceMail, true); settingsWidgetStack->raiseWidget(pageVoiceMail); ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a mailbox user name.").ascii(), MSG_CRITICAL); mwiUserLineEdit->setFocus(); return false; } // Mailbox server is mandatory if (mwiServerLineEdit->text().isEmpty()) { categoryListBox->setSelected(idxCatVoiceMail, true); settingsWidgetStack->raiseWidget(pageVoiceMail); ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a mailbox server").ascii(), MSG_CRITICAL); mwiServerLineEdit->setFocus(); return false; } // Check validity of mailbox server s = USER_SCHEME; s.append(':').append(mwiServerLineEdit->text()); t_url u_server(s.ascii()); if (!u_server.is_valid() || u_server.get_user() != "") { categoryListBox->setSelected(idxCatVoiceMail, true); settingsWidgetStack->raiseWidget(pageVoiceMail); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid mailbox server.").ascii(), MSG_CRITICAL); mwiServerLineEdit->setFocus(); return false; } // Check validity of mailbox user name s = USER_SCHEME; s.append(':').append(mwiUserLineEdit->text()).append('@'); s.append(mwiServerLineEdit->text()); t_url u_user_server(s.ascii()); if (!u_user_server.is_valid()) { categoryListBox->setSelected(idxCatVoiceMail, true); settingsWidgetStack->raiseWidget(pageVoiceMail); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid mailbox user name.").ascii(), MSG_CRITICAL); mwiUserLineEdit->setFocus(); return false; } } // NAT public IP if (natStaticRadioButton->isChecked()) { if (publicIPLineEdit->text().isEmpty()){ categoryListBox->setSelected(idxCatNat, true); settingsWidgetStack->raiseWidget(pageNat); ((t_gui *)ui)->cb_show_msg(this, tr("Value for public IP address missing.").ascii(), MSG_CRITICAL); publicIPLineEdit->setFocus(); return false; } } // Check for double RTP dynamic payload types QValueList checked_types; if (!check_dynamic_payload(spxNbPayloadSpinBox, checked_types) || !check_dynamic_payload(spxWbPayloadSpinBox, checked_types) || !check_dynamic_payload(spxUwbPayloadSpinBox, checked_types)) { rtpAudioTabWidget->showPage(tabSpeex); return false; } if (!check_dynamic_payload(ilbcPayloadSpinBox, checked_types)) { rtpAudioTabWidget->showPage(tabIlbc); return false; } if (!check_dynamic_payload(g72616PayloadSpinBox, checked_types) || !check_dynamic_payload(g72624PayloadSpinBox, checked_types) || !check_dynamic_payload(g72632PayloadSpinBox, checked_types) || !check_dynamic_payload(g72640PayloadSpinBox, checked_types)) { rtpAudioTabWidget->showPage(tabG726); return false; } if (!check_dynamic_payload(dtmfPayloadTypeSpinBox, checked_types)) { rtpAudioTabWidget->showPage(tabDtmf); return false; } // STUN server if (natStunRadioButton->isChecked()) { s = "stun:"; s.append(stunServerLineEdit->text()); t_url u(s.ascii()); if (!u.is_valid() || u.get_user() != "") { categoryListBox->setSelected(idxCatNat, true); settingsWidgetStack->raiseWidget(pageNat); ((t_gui *)ui)->cb_show_msg(this, tr("Invalid value for STUN server.").ascii(), MSG_CRITICAL); stunServerLineEdit->setFocus(); stunServerLineEdit->selectAll(); return false; } } // Clear outbound proxy if not used if (!useProxyCheckBox->isChecked()) { proxyLineEdit->clear(); } // Clear sollicited MWI settings if unsollicited MWI is used if (mwiTypeComboBox->currentItem() == idxMWIUnsollicited) { t_user user_default; mwiUserLineEdit->clear(); mwiServerLineEdit->clear(); mwiViaProxyCheckBox->setChecked(user_default.get_mwi_via_proxy()); mwiDurationSpinBox->setValue(user_default.get_mwi_subscription_time()); } // Clear NAT public IP if not used if (!natStaticRadioButton->isChecked()) { publicIPLineEdit->clear(); } // Clear STUN server if not used if (!natStunRadioButton->isChecked()) { stunServerLineEdit->clear(); } // Set all values in the current_profile object // USER if (current_profile->get_name() != usernameLineEdit->text().ascii() || current_profile->get_display(false) != displayLineEdit->text().ascii() || current_profile->get_domain() != domainLineEdit->text().ascii()) { current_profile->set_display(displayLineEdit->text().ascii()); current_profile->set_name(usernameLineEdit->text().ascii()); current_profile->set_domain (domainLineEdit->text().ascii()); emit sipUserChanged(current_profile); } current_profile->set_organization(organizationLineEdit->text().ascii()); uint8 new_aka_op[AKA_OPLEN]; uint8 new_aka_amf[AKA_AMFLEN]; uint8 current_aka_op[AKA_OPLEN]; uint8 current_aka_amf[AKA_AMFLEN]; hex2binary(padleft(authAkaOpLineEdit->text().ascii(), '0', 32), new_aka_op); hex2binary(padleft(authAkaAmfLineEdit->text().ascii(), '0', 4), new_aka_amf); current_profile->get_auth_aka_op(current_aka_op); current_profile->get_auth_aka_amf(current_aka_amf); if (current_profile->get_auth_realm() != authRealmLineEdit->text().ascii() || current_profile->get_auth_name() != authNameLineEdit->text().ascii() || current_profile->get_auth_pass() != authPasswordLineEdit->text().ascii() || memcmp(current_aka_op, new_aka_op, AKA_OPLEN) != 0 || memcmp(current_aka_amf, new_aka_amf, AKA_AMFLEN) != 0) { emit authCredentialsChanged(current_profile, current_profile->get_auth_realm()); current_profile->set_auth_realm(authRealmLineEdit->text().ascii()); current_profile->set_auth_name(authNameLineEdit->text().ascii()); current_profile->set_auth_pass(authPasswordLineEdit->text().ascii()); current_profile->set_auth_aka_op(new_aka_op); current_profile->set_auth_aka_amf(new_aka_amf); } // SIP SERVER current_profile->set_use_registrar(!registrarLineEdit->text().isEmpty()); s = USER_SCHEME; s.append(':').append(registrarLineEdit->text()); current_profile->set_registrar(t_url(s.ascii())); current_profile->set_registration_time(expirySpinBox->value()); current_profile->set_register_at_startup(regAtStartupCheckBox->isChecked()); current_profile->set_reg_add_qvalue(regAddQvalueCheckBox->isChecked()); current_profile->set_reg_qvalue(atof(regQvalueLineEdit->text().ascii())); current_profile->set_use_outbound_proxy(useProxyCheckBox->isChecked()); s = USER_SCHEME; s.append(':').append(proxyLineEdit->text()); current_profile->set_outbound_proxy(t_url(s.ascii())); current_profile->set_all_requests_to_proxy(allRequestsCheckBox->isChecked()); current_profile->set_non_resolvable_to_proxy( proxyNonResolvableCheckBox->isChecked()); // VOICE MAIL current_profile->set_mwi_vm_address(vmAddressLineEdit->text().ascii()); bool mustTriggerMWISubscribe = false; bool mwiSollicited = (mwiTypeComboBox->currentItem() == idxMWISollicited); if (mwiSollicited) { if (!current_profile->get_mwi_sollicited()) { // Sollicited MWI now enabled. Subscribe after all MWI // settings have been changed. mustTriggerMWISubscribe = true; } else { s = USER_SCHEME; s.append(':').append(mwiServerLineEdit->text()); if (mwiUserLineEdit->text().ascii() != current_profile->get_mwi_user() || t_url(s.ascii()) != current_profile->get_mwi_server() || mwiViaProxyCheckBox->isChecked() != current_profile->get_mwi_via_proxy()) { // Sollicited MWI settings changed. Trigger unsubscribe // of current MWI subscription. emit mwiChangeUnsubscribe(current_profile); // Subscribe after the settings have been changed. mustTriggerMWISubscribe = true; } } } else { if (current_profile->get_mwi_sollicited()) { // MWI type changes to unsollicited. Trigger unsubscribe of // current MWI subscription. emit mwiChangeUnsubscribe(current_profile); } } current_profile->set_mwi_sollicited(mwiSollicited); current_profile->set_mwi_user(mwiUserLineEdit->text().ascii()); s = USER_SCHEME; s.append(':').append(mwiServerLineEdit->text()); current_profile->set_mwi_server(t_url(s.ascii())); current_profile->set_mwi_via_proxy(mwiViaProxyCheckBox->isChecked()); current_profile->set_mwi_subscription_time(mwiDurationSpinBox->value()); if (mustTriggerMWISubscribe) { emit mwiChangeSubscribe(current_profile); } // INSTANT MESSAGE current_profile->set_im_max_sessions(imMaxSessionsSpinBox->value()); current_profile->set_im_send_iscomposing(isComposingCheckBox->isChecked()); // PRESENCE current_profile->set_pres_publish_startup(presPublishCheckBox->isChecked()); current_profile->set_pres_publication_time(presPublishTimeSpinBox->value()); current_profile->set_pres_subscription_time(presSubscribeTimeSpinBox->value()); // RTP AUDIO // Codecs list audio_codecs; for (size_t i = 0; i < activeCodecListBox->count(); i++) { audio_codecs.push_back(label2codec(activeCodecListBox->text(i))); } current_profile->set_codecs(audio_codecs); // G.711/G.726 ptime current_profile->set_ptime(ptimeSpinBox->value()); // Codec preference current_profile->set_in_obey_far_end_codec_pref(inFarEndCodecPrefCheckBox->isChecked()); current_profile->set_out_obey_far_end_codec_pref(outFarEndCodecPrefCheckBox->isChecked()); // Speex preprocessing & AEC current_profile->set_speex_dsp_vad(spxDspVadCheckBox->isChecked()); current_profile->set_speex_dsp_agc(spxDspAgcCheckBox->isChecked()); current_profile->set_speex_dsp_aec(spxDspAecCheckBox->isChecked()); current_profile->set_speex_dsp_nrd(spxDspNrdCheckBox->isChecked()); current_profile->set_speex_dsp_agc_level(spxDspAgcLevelSpinBox->value()); // Speex ([en/de]coding) current_profile->set_speex_bit_rate_type((spxVbrCheckBox->isChecked() ? BIT_RATE_VBR : BIT_RATE_CBR)); current_profile->set_speex_dtx(spxDtxCheckBox->isChecked()); current_profile->set_speex_penh(spxPenhCheckBox->isChecked()); current_profile->set_speex_quality(spxQualitySpinBox->value()); current_profile->set_speex_complexity(spxComplexitySpinBox->value()); current_profile->set_speex_nb_payload_type(spxNbPayloadSpinBox->value()); current_profile->set_speex_wb_payload_type(spxWbPayloadSpinBox->value()); current_profile->set_speex_uwb_payload_type(spxUwbPayloadSpinBox->value()); // iLBC current_profile->set_ilbc_payload_type(ilbcPayloadSpinBox->value()); switch (ilbcPayloadSizeComboBox->currentItem()) { case idxIlbcMode20: current_profile->set_ilbc_mode(20); break; default: current_profile->set_ilbc_mode(30); break; } // G726 current_profile->set_g726_16_payload_type(g72616PayloadSpinBox->value()); current_profile->set_g726_24_payload_type(g72624PayloadSpinBox->value()); current_profile->set_g726_32_payload_type(g72632PayloadSpinBox->value()); current_profile->set_g726_40_payload_type(g72640PayloadSpinBox->value()); switch (g726PackComboBox->currentItem()) { case idxG726PackRfc3551: current_profile->set_g726_packing(G726_PACK_RFC3551); break; default: current_profile->set_g726_packing(G726_PACK_AAL2); break; } // DTMF switch (dtmfTransportComboBox->currentItem()) { case idxDtmfRfc2833: current_profile->set_dtmf_transport(DTMF_RFC2833); break; case idxDtmfInband: current_profile->set_dtmf_transport(DTMF_INBAND); break; case idxDtmfInfo: current_profile->set_dtmf_transport(DTMF_INFO); break; default: current_profile->set_dtmf_transport(DTMF_AUTO); break; } current_profile->set_dtmf_payload_type(dtmfPayloadTypeSpinBox->value()); current_profile->set_dtmf_duration(dtmfDurationSpinBox->value()); current_profile->set_dtmf_pause(dtmfPauseSpinBox->value()); current_profile->set_dtmf_volume(-(dtmfVolumeSpinBox->value())); // SIP PROTOCOL switch (holdVariantComboBox->currentItem()) { case idxHoldRfc2543: current_profile->set_hold_variant(HOLD_RFC2543); break; default: current_profile->set_hold_variant(HOLD_RFC3264); break; } current_profile->set_check_max_forwards(maxForwardsCheckBox->isChecked()); current_profile->set_allow_missing_contact_reg(missingContactCheckBox->isChecked()); current_profile->set_registration_time_in_contact(regTimeCheckBox->isChecked()); current_profile->set_compact_headers(compactHeadersCheckBox->isChecked()); current_profile->set_encode_multi_values_as_list( multiValuesListCheckBox->isChecked()); current_profile->set_use_domain_in_contact( useDomainInContactCheckBox->isChecked()); current_profile->set_allow_sdp_change(allowSdpChangeCheckBox->isChecked()); current_profile->set_allow_redirection(allowRedirectionCheckBox->isChecked()); current_profile->set_ask_user_to_redirect(askUserRedirectCheckBox->isChecked()); current_profile->set_max_redirections(maxRedirectSpinBox->value()); current_profile->set_ext_100rel(indexComboItem2ext_support( ext100relComboBox->currentItem())); current_profile->set_ext_replaces(extReplacesCheckBox->isChecked()); current_profile->set_allow_refer(allowReferCheckBox->isChecked()); current_profile->set_ask_user_to_refer(askUserReferCheckBox->isChecked()); current_profile->set_referee_hold(refereeHoldCheckBox->isChecked()); current_profile->set_referrer_hold(referrerHoldCheckBox->isChecked()); current_profile->set_auto_refresh_refer_sub(refreshReferSubCheckBox->isChecked()); current_profile->set_attended_refer_to_aor(referAorCheckBox->isChecked()); current_profile->set_allow_transfer_consultation_inprog( transferConsultInprogCheckBox->isChecked()); current_profile->set_send_p_preferred_id(pPreferredIdCheckBox->isChecked()); // Transport/NAT switch (sipTransportComboBox->currentItem()) { case idxSipTransportUDP: current_profile->set_sip_transport(SIP_TRANS_UDP); break; case idxSipTransportTCP: current_profile->set_sip_transport(SIP_TRANS_TCP); break; default: current_profile->set_sip_transport(SIP_TRANS_AUTO); break; } current_profile->set_sip_transport_udp_threshold(udpThresholdSpinBox->value()); current_profile->set_use_nat_public_ip(natStaticRadioButton->isChecked()); current_profile->set_nat_public_ip(publicIPLineEdit->text().ascii()); current_profile->set_use_stun(natStunRadioButton->isChecked()); if (current_profile->get_stun_server().encode_noscheme() != stunServerLineEdit->text().ascii() || current_profile->get_enable_nat_keepalive() != natKeepaliveCheckBox->isChecked()) { s = "stun:"; s.append(stunServerLineEdit->text()); current_profile->set_stun_server(t_url(s.ascii())); current_profile->set_enable_nat_keepalive(natKeepaliveCheckBox->isChecked()); emit stunServerChanged(current_profile); } current_profile->set_persistent_tcp(persistentTcpCheckBox->isChecked()); // ADDRESS FORMAT current_profile->set_display_useronly_phone( displayTelUserCheckBox->isChecked()); current_profile->set_numerical_user_is_phone( numericalUserIsTelCheckBox->isChecked()); current_profile->set_remove_special_phone_symbols( removeSpecialCheckBox->isChecked()); current_profile->set_special_phone_symbols( specialLineEdit->text().stripWhiteSpace().ascii()); current_profile->set_number_conversions(get_number_conversions()); current_profile->set_use_tel_uri_for_phone(useTelUriCheckBox->isChecked()); // TIMERS current_profile->set_timer_noanswer(tmrNoanswerSpinBox->value()); current_profile->set_timer_nat_keepalive(tmrNatKeepaliveSpinBox->value()); // RING TONES current_profile->set_ringtone_file(ringtoneLineEdit->text().stripWhiteSpace().ascii()); current_profile->set_ringback_file(ringbackLineEdit->text().stripWhiteSpace().ascii()); // SCRIPTS current_profile->set_script_incoming_call(incomingCallScriptLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_in_call_answered(inCallAnsweredLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_in_call_failed(inCallFailedLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_outgoing_call(outCallLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_out_call_answered(outCallAnsweredLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_out_call_failed(outCallFailedLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_local_release(localReleaseLineEdit-> text().stripWhiteSpace().ascii()); current_profile->set_script_remote_release(remoteReleaseLineEdit-> text().stripWhiteSpace().ascii()); // Security current_profile->set_zrtp_enabled(zrtpEnabledCheckBox->isChecked()); current_profile->set_zrtp_send_if_supported(zrtpSendIfSupportedCheckBox->isChecked()); current_profile->set_zrtp_sdp(zrtpSdpCheckBox->isChecked()); current_profile->set_zrtp_goclear_warning(zrtpGoClearWarningCheckBox->isChecked()); // Save user config string error_msg; if (!current_profile->write_config(current_profile->get_filename(), error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); return false; } return true; } void UserProfileForm::validate() { if (validateValues()) { emit success(); accept(); } } // User wants to change to another profile void UserProfileForm::changeProfile(const QString &profileName) { if (current_profile_idx == -1) { // Initializing combo box return; } // Make the current profile permanent. if (!validateValues()) { // Current values are not valid. // Do not change to the new profile. profileComboBox->setCurrentItem(current_profile_idx); return; } // Store the current viewed category map_last_cat[current_profile] = categoryListBox->index(categoryListBox->selectedItem()); // Change to new profile. for (list::iterator i = profile_list.begin(); i != profile_list.end(); i++) { if ((*i)->get_profile_name() == profileName.ascii()) { current_profile = *i; break; } } current_profile_idx = profileComboBox->currentItem(); populate(); // Restore last viewed category int idxCat = map_last_cat[current_profile]; categoryListBox->setSelected(idxCat, true); showCategory(idxCat); } void UserProfileForm::chooseFile(QLineEdit *qle, const QString &filter, const QString &caption) { QString file = QFileDialog::getOpenFileName( ((t_gui *)ui)->get_last_file_browse_path(), filter, this, "open file dialog", caption); if (!file.isEmpty()) { qle->setText(file); ((t_gui *)ui)->set_last_file_browse_path(QFileInfo(file).dirPath(true)); } } void UserProfileForm::chooseRingtone() { chooseFile(ringtoneLineEdit, tr("Ring tones", "Description of .wav files in file dialog").append(" (*.wav)"), tr("Choose ring tone")); } void UserProfileForm::chooseRingback() { chooseFile(ringbackLineEdit, tr("Ring back tones", "Description of .wav files in file dialog").append(" (*.wav)"), "Choose ring back tone"); } void UserProfileForm::chooseIncomingCallScript() { chooseFile(incomingCallScriptLineEdit, tr("All files").append(" (*)"), tr("Choose incoming call script")); } void UserProfileForm::chooseInCallAnsweredScript() { chooseFile(inCallAnsweredLineEdit, tr("All files").append(" (*)"), tr("Choose incoming call answered script")); } void UserProfileForm::chooseInCallFailedScript() { chooseFile(inCallFailedLineEdit, tr("All files").append(" (*)"), tr("Choose incoming call failed script")); } void UserProfileForm::chooseOutgoingCallScript() { chooseFile(outCallLineEdit, tr("All files").append(" (*)"), tr("Choose outgoing call script")); } void UserProfileForm::chooseOutCallAnsweredScript() { chooseFile(outCallAnsweredLineEdit, tr("All files").append(" (*)"), tr("Choose outgoing call answered script")); } void UserProfileForm::chooseOutCallFailedScript() { chooseFile(outCallFailedLineEdit, tr("All files").append(" (*)"), tr("Choose outgoing call failed script")); } void UserProfileForm::chooseLocalReleaseScript() { chooseFile(localReleaseLineEdit, tr("All files").append(" (*)"), tr("Choose local release script")); } void UserProfileForm::chooseRemoteReleaseScript() { chooseFile(remoteReleaseLineEdit, tr("All files").append(" (*)"), tr("Choose remote release script")); } void UserProfileForm::addCodec() { for (size_t i = 0; i < availCodecListBox->count(); i++) { if (availCodecListBox->isSelected(i)) { activeCodecListBox->insertItem(availCodecListBox->text(i)); activeCodecListBox->setSelected( activeCodecListBox->count() - 1, true); availCodecListBox->removeItem(i); return; } } } void UserProfileForm::removeCodec() { for (size_t i = 0; i < activeCodecListBox->count(); i++) { if (activeCodecListBox->isSelected(i)) { availCodecListBox->insertItem(activeCodecListBox->text(i)); availCodecListBox->setSelected( availCodecListBox->count() - 1, true); activeCodecListBox->removeItem(i); return; } } } void UserProfileForm::upCodec() { QListBoxItem *lbi = activeCodecListBox->selectedItem(); if (!lbi) return; int idx = activeCodecListBox->index(lbi); if (idx == 0) return; QString label = lbi->text(); activeCodecListBox->removeItem(idx); activeCodecListBox->insertItem(label, idx - 1); activeCodecListBox->setSelected(idx - 1, true); } void UserProfileForm::downCodec() { QListBoxItem *lbi = activeCodecListBox->selectedItem(); if (!lbi) return; size_t idx = activeCodecListBox->index(lbi); if (idx == activeCodecListBox->count() - 1) return; QString label = lbi->text(); activeCodecListBox->removeItem(idx); activeCodecListBox->insertItem(label, idx + 1); activeCodecListBox->setSelected(idx + 1, true); } void UserProfileForm::upConversion() { QListViewItem *lvi = conversionListView->selectedItem(); if (!lvi) return; QListViewItem *above = lvi->itemAbove(); if (!above) return; QListViewItem *newAbove = above->itemAbove(); if (newAbove) { lvi->moveItem(newAbove); } else { above->moveItem(lvi); } lvi->setSelected(true); } void UserProfileForm::downConversion() { QListViewItem *lvi = conversionListView->selectedItem(); if (!lvi) return; QListViewItem *below = lvi->itemBelow(); if (!below) return; lvi->moveItem(below); lvi->setSelected(true); } void UserProfileForm::addConversion() { QString expr; QString replace; NumberConversionForm f; if (f.exec(expr, replace) == QDialog::Accepted) { QListViewItem *last = conversionListView->lastItem(); if (last) { new QListViewItem(conversionListView, last, expr, replace); } else { new QListViewItem(conversionListView, expr, replace); } } } void UserProfileForm::editConversion() { QListViewItem *lvi = conversionListView->selectedItem(); if (!lvi) return; QString expr = lvi->text(colExpr); QString replace = lvi->text(colReplace); NumberConversionForm f; if (f.exec(expr, replace) == QDialog::Accepted) { lvi->setText(colExpr, expr); lvi->setText(colReplace, replace); } } void UserProfileForm::removeConversion() { QListViewItem *lvi = conversionListView->selectedItem(); if (!lvi) return; delete lvi; } void UserProfileForm::testConversion() { QString number = testConversionLineEdit->text(); if (number.isEmpty()) return; bool remove_special_phone_symbols = removeSpecialCheckBox->isChecked(); QString special_phone_symbols = specialLineEdit->text(); number = remove_white_space(number.ascii()).c_str(); // Remove special symbols if (remove_special_phone_symbols && looks_like_phone(number.ascii(), special_phone_symbols.ascii())) { number = remove_symbols( number.ascii(), special_phone_symbols.ascii()).c_str(); } QString msg = tr("%1 converts to %2") .arg(number) .arg(current_profile->convert_number(number.ascii(), get_number_conversions()).c_str()); ((t_gui *)ui)->cb_show_msg(this, msg.ascii(), MSG_INFO); } void UserProfileForm::changeMWIType(int idxMWIType) { if (idxMWIType == idxMWISollicited) { mwiSollicitedGroupBox->setEnabled(true); // Set defaults if (mwiUserLineEdit->text().isEmpty()) { mwiUserLineEdit->setText(usernameLineEdit->text()); } if (mwiServerLineEdit->text().isEmpty()) { mwiServerLineEdit->setText(domainLineEdit->text()); mwiViaProxyCheckBox->setChecked(useProxyCheckBox->isChecked()); } } else { mwiSollicitedGroupBox->setEnabled(false); } } void UserProfileForm::changeSipTransportProtocol(int idx) { udpThresholdTextLabel->setEnabled(idx == idxSipTransportAuto); udpThresholdSpinBox->setEnabled(idx == idxSipTransportAuto); persistentTcpCheckBox->setEnabled(idx == idxSipTransportTCP); } twinkle-1.4.2/src/gui/selectnicform.ui0000644000175000001440000001745710503576707014707 00000000000000 SelectNicForm SelectNicForm 0 0 482 144 Twinkle - Select NIC unnamed nicIconTextLabel kcmpci.png spacer53 Vertical Expanding 20 41 layout42 unnamed selectTextLabel Select the network interface/IP address that you want to use: WordBreak|AlignTop nicListBox You have multiple IP addresses. Here you must select which IP address should be used. This IP address will be used inside the SIP messages. spacer9 Vertical Expanding 20 16 layout11 unnamed spacer7 Horizontal Expanding 40 20 defaultIpPushButton Set as default &IP Alt+I Make the selected IP address the default IP address. The next time you start Twinkle, this IP address will be automatically selected. defaultNicPushButton Set as default &NIC Alt+N Make the selected network interface the default interface. The next time you start Twinkle, this interface will be automatically selected. okPushButton &OK Alt+O true okPushButton clicked() SelectNicForm accept() nicListBox selected(const QString&) SelectNicForm accept() defaultIpPushButton clicked() SelectNicForm setAsDefaultIp() defaultNicPushButton clicked() SelectNicForm setAsDefaultNic() gui.h qmessagebox.h sys_settings.h selectnicform.ui.h int idxDefault; setAsDefault( bool setIp ) setAsDefaultIp() setAsDefaultNic() init() twinkle-1.4.2/src/gui/addresscardform.ui0000644000175000001440000002152210534111601015157 00000000000000 AddressCardForm AddressCardForm 0 0 604 209 Twinkle - Address Card unnamed layout73 unnamed remarkTextLabel &Remark: remarkLineEdit infixNameLineEdit Infix name of contact. firstNameLineEdit First name of contact. firstNameTextLabel &First name: firstNameLineEdit remarkLineEdit You may place any remark about the contact here. phoneTextLabel &Phone: phoneLineEdit infixNameTextLabel &Infix name: infixNameLineEdit phoneLineEdit Phone number or SIP address of contact. lastNameLineEdit Last name of contact. lastNameTextLabel &Last name: lastNameLineEdit spacer100 Vertical Expanding 20 31 layout72 unnamed spacer99 Horizontal Expanding 261 20 okPushButton &OK Alt+O true cancelPushButton &Cancel Alt+C okPushButton clicked() AddressCardForm validate() cancelPushButton clicked() AddressCardForm reject() firstNameLineEdit infixNameLineEdit lastNameLineEdit phoneLineEdit remarkLineEdit okPushButton cancelPushButton address_book.h gui.h addresscardform.ui.h validate() exec( t_address_card & card ) twinkle-1.4.2/src/gui/selectuserform.ui0000644000175000001440000001605210514421672015072 00000000000000 SelectUserForm SelectUserForm 0 0 584 228 Twinkle - Select user unnamed cancelPushButton &Cancel Alt+C selectPushButton &Select all Alt+S spacer47 Horizontal Expanding 41 20 okPushButton &OK Alt+O true clearPushButton C&lear all Alt+L layout100 unnamed purposeTextLabel 1 5 0 0 purpose No need to translate User true true userListView Manual NoSelection LastColumn okPushButton clicked() SelectUserForm validate() cancelPushButton clicked() SelectUserForm reject() selectPushButton clicked() SelectUserForm selectAll() clearPushButton clicked() SelectUserForm clearAll() userListView doubleClicked(QListViewItem*) SelectUserForm toggle(QListViewItem*) userListView selectPushButton clearPushButton okPushButton cancelPushButton user.h phone.h gui.h cassert qlistview.h selectuserform.ui.h extern t_phone *phone; selection(list<t_user *>) not_selected(list<t_user*>) show( t_select_purpose purpose ) validate() selectAll() clearAll() toggle( QListViewItem * item ) init() twinkle-1.4.2/src/gui/messageform.ui0000644000175000001440000003657211150242272014343 00000000000000 MessageForm MessageForm 0 0 578 356 Twinkle - Instant message unnamed layout154 unnamed toTextLabel &To: toLineEdit fromComboBox The user that will send the message. layout152 unnamed toLineEdit The address of the user that you want to send a message. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. addressToolButton TabFocus F10 kontact_contacts.png Address book Select an address from the address book. profileTextLabel &User profile: fromComboBox conversationGroupBox Conversation unnamed conversationBrowser layout158 unnamed msgLineEdit Type your message here and then press "send" to send it. sendPushButton &Send Alt+S false true Send the message. Toolbar false Instant message toolbar TextBrowserNoAutoLink
textbrowsernoautolink.h
-1 -1 0 7 7 0 0 image0 linkClicked( const QString & link )
sendFileAction attach.png Send file... Send file 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082 sendPushButton clicked() MessageForm sendMessage() addressToolButton clicked() MessageForm showAddressBook() conversationBrowser linkClicked(const QString&) MessageForm showAttachmentPopupMenu(const QString&) sendFileAction activated() MessageForm chooseFileToSend() toLineEdit textChanged(const QString&) MessageForm toAddressChanged(const QString&) msgLineEdit textChanged(const QString&) MessageForm showMessageSize() getaddressform.h qstring.h user.h im/msg_session.h phone.h qpopupmenu.h qlabel.h gui.h sockets/url.h qstylesheet.h audits/memman.h util.h qpixmap.h qcursor.h qfiledialog.h utils/file_utils.h qfile.h sendfileform.h qstatusbar.h qframe.h messageform.ui.h extern t_phone *phone; QDialog *_saveAsDialog; map<string, string> _filenameMap; im::t_msg_session *_msgSession; bool _remotePartyComplete; GetAddressForm *_getAddressForm; QPopupMenu *attachmentPopupMenu; QString clickedAttachment; void *_serviceMap; QLabel *_isComposingLabel; QLabel *_msgSizeLabel; closeEvent( QCloseEvent * e ) show() selectUserConfig( t_user * user_config ) showAddressBook() selectedAddress( const QString & address ) sendMessage() sendFile( const QString & filename, const QString & subject ) addMessage( const im::t_msg & msg, const QString & name ) displayError( const QString & errorMsg ) displayDeliveryNotification( const QString & notification ) setRemotePartyCaption( void ) showAttachmentPopupMenu( const QString & attachment ) attachmentPopupActivated( int id ) saveAttachment() chooseFileToSend() setComposingIndication( const QString & name ) clearComposingIndication() setLocalComposingIndicationActive() keyPressEvent( QKeyEvent * e ) toAddressChanged( const QString & address ) showMessageSize() init() destroy() updateMessageSession() prepareSendMessage() textbrowsernoautolink.h
twinkle-1.4.2/src/gui/buddyform.ui0000644000175000001440000002377410641530304014026 00000000000000 BuddyForm BuddyForm 0 0 484 154 Twinkle - Buddy unnamed layout12 unnamed spacer25 Vertical Expanding 20 47 addressToolButton TabFocus kontact_contacts.png Address book Select an address from the address book. phoneTextLabel &Phone: phoneLineEdit nameLineEdit Name of your buddy. subscribeCheckBox &Show availability Alt+S true Check this option if you want to see the availability of your buddy. This will only work if your provider offers a presence agent. nameTextLabel &Name: nameLineEdit phoneLineEdit SIP address your buddy. spacer14 Vertical Expanding 20 16 layout54 unnamed spacer13 Horizontal Expanding 131 20 okPushButton &OK Alt+O true cancelPushButton &Cancel Alt+C okPushButton clicked() BuddyForm validate() cancelPushButton clicked() BuddyForm reject() addressToolButton clicked() BuddyForm showAddressBook() nameLineEdit phoneLineEdit subscribeCheckBox addressToolButton okPushButton cancelPushButton presence/buddy.h user.h qlistview.h getaddressform.h gui.h sockets/url.h buddylistview.h audits/memman.h buddyform.ui.h GetAddressForm *getAddressForm; t_user *user_config; bool edit_mode; t_buddy_list *buddy_list; t_buddy *edit_buddy; QListViewItem *profileItem; showNew( t_buddy_list & _buddy_list, QListViewItem * _profileItem ) showEdit( t_buddy & buddy ) validate() showAddressBook() selectedAddress( const QString & name, const QString & phone ) init() destroy() twinkle-1.4.2/src/gui/wizardform.ui.h0000644000175000001440000001707311134647705014454 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define PROV_NONE QT_TRANSLATE_NOOP("WizardForm", "None (direct IP to IP calls)") #define PROV_OTHER QT_TRANSLATE_NOOP("WizardForm", "Other") struct t_provider { QString domain; QString sip_proxy; QString stun_server; }; void WizardForm::init() { QRegExp rxNoSpace("\\S*"); // Set validators usernameLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); domainLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); authNameLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); proxyLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); initProviders(); serviceProviderComboBox->setCurrentItem(serviceProviderComboBox->count() - 1); update(tr(PROV_OTHER)); } void WizardForm::initProviders() { serviceProviderComboBox->clear(); serviceProviderComboBox->insertItem(tr(PROV_NONE)); QString fname = sys_config->get_dir_share().c_str(); fname.append("/").append(FILE_PROVIDERS); QFile providersFile(fname); if (providersFile.open(IO_ReadOnly)) { QTextStream providersStream(&providersFile); QString entry; while ((entry = providersStream.readLine()) != QString::null) { // Skip comment if (entry[0] == '#') continue; QStringList l = QStringList::split(";", entry, true); // Skip invalid lines if (l.size() != 4) continue; t_provider p; p.domain = l[1]; p.sip_proxy = l[2]; p.stun_server = l[3]; mapProviders[l[0]] = p; serviceProviderComboBox->insertItem(l[0]); } providersFile.close(); } serviceProviderComboBox->insertItem(tr(PROV_OTHER)); } int WizardForm::exec(t_user *user) { user_config = user; // Set user profile name in the titlebar QString s = PRODUCT_NAME; s.append(" - ").append(tr("User profile wizard:")).append(" "); s.append(user_config->get_profile_name().c_str()); setCaption(s); return QDialog::exec(); } void WizardForm::show(t_user *user) { user_config = user; // Set user profile name in the titlebar QString s = PRODUCT_NAME; s.append(" - ").append(tr("User profile wizard:")).append(" "); s.append(user_config->get_profile_name().c_str()); setCaption(s); QDialog::show(); } void WizardForm::update(const QString &item) { // Disable/Enable controls if (item == tr(PROV_NONE)) { suggestAuthName = false; authNameTextLabel->setEnabled(false); authNameLineEdit->setEnabled(false); authPasswordTextLabel->setEnabled(false); authPasswordLineEdit->setEnabled(false); proxyTextLabel->setEnabled(false); proxyLineEdit->setEnabled(false); stunServerTextLabel->setEnabled(false); stunServerLineEdit->setEnabled(false); } else { if (usernameLineEdit->text() == authNameLineEdit->text()) { suggestAuthName = true; } else { suggestAuthName = false; } authNameTextLabel->setEnabled(true); authNameLineEdit->setEnabled(true); authPasswordTextLabel->setEnabled(true); authPasswordLineEdit->setEnabled(true); proxyTextLabel->setEnabled(true); proxyLineEdit->setEnabled(true); stunServerTextLabel->setEnabled(true); stunServerLineEdit->setEnabled(true); } // Set values if (item == tr(PROV_NONE)) { domainLineEdit->clear(); authNameLineEdit->clear(); authPasswordLineEdit->clear(); proxyLineEdit->clear(); stunServerLineEdit->clear(); } else if (item == tr(PROV_OTHER)) { domainLineEdit->clear(); stunServerLineEdit->clear(); proxyLineEdit->clear(); } else { t_provider p = mapProviders[item]; domainLineEdit->setText(p.domain); proxyLineEdit->setText(p.sip_proxy); stunServerLineEdit->setText(p.stun_server); } } void WizardForm::updateAuthName(const QString &s) { if (suggestAuthName) { authNameLineEdit->setText(s); } } void WizardForm::disableSuggestAuthName() { suggestAuthName = false; } void WizardForm::validate() { QString s; // Validity check user page // SIP username is mandatory if (usernameLineEdit->text().isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a user name for your SIP account.").ascii(), MSG_CRITICAL); usernameLineEdit->setFocus(); return; } // SIP user domain is mandatory if (domainLineEdit->text().isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr( "You must fill in a domain name for your SIP account.\n" "This could be the hostname or IP address of your PC " "if you want direct PC to PC dialing.").ascii(), MSG_CRITICAL); domainLineEdit->setFocus(); return; } // SIP proxy if (proxyLineEdit->text() != "") { s = USER_SCHEME; s.append(':').append(proxyLineEdit->text()); t_url u(s.ascii()); if (!u.is_valid() || u.get_user() != "") { ((t_gui *)ui)->cb_show_msg(this, tr("Invalid value for SIP proxy.").ascii(), MSG_CRITICAL); proxyLineEdit->setFocus(); proxyLineEdit->selectAll(); return; } } // Register and publish presence at startup if (serviceProviderComboBox->currentText() == tr(PROV_NONE)) { user_config->set_register_at_startup(false); user_config->set_pres_publish_startup(false); } // STUN server if (stunServerLineEdit->text() != "") { s = "stun:"; s.append(stunServerLineEdit->text()); t_url u(s.ascii()); if (!u.is_valid() || u.get_user() != "") { ((t_gui *)ui)->cb_show_msg(this, tr("Invalid value for STUN server.").ascii(), MSG_CRITICAL); stunServerLineEdit->setFocus(); stunServerLineEdit->selectAll(); return; } } // Set all values in the user_config object // USER user_config->set_display(displayLineEdit->text().ascii()); user_config->set_name(usernameLineEdit->text().ascii()); user_config->set_domain(domainLineEdit->text().ascii()); user_config->set_auth_name(authNameLineEdit->text().ascii()); user_config->set_auth_pass(authPasswordLineEdit->text().ascii()); // SIP SERVER user_config->set_use_outbound_proxy(!proxyLineEdit->text().isEmpty()); s = USER_SCHEME; s.append(':').append(proxyLineEdit->text()); user_config->set_outbound_proxy(t_url(s.ascii())); // NAT user_config->set_use_stun(!stunServerLineEdit->text().isEmpty()); s = "stun:"; s.append(stunServerLineEdit->text()); user_config->set_stun_server(t_url(s.ascii())); // Save user config string error_msg; if (!user_config->write_config(user_config->get_filename(), error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); return; } emit success(); accept(); } twinkle-1.4.2/src/gui/inviteform.ui0000644000175000001440000003532111131204631014200 00000000000000 InviteForm InviteForm 0 0 592 203 5 5 0 0 Twinkle - Call unnamed layout40 unnamed inviteTextLabel &To: inviteComboBox spacer3 Vertical Expanding 20 23 subjectLineEdit Optionally you can provide a subject here. This might be shown to the callee. addressToolButton TabFocus F10 kontact_contacts.png Address book Select an address from the address book. spacer24 Vertical Expanding 20 20 inviteComboBox 7 0 0 0 true 10 NoInsertion true The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. fromComboBox 7 0 0 0 The user that will make the call. subjectTextLabel &Subject: subjectLineEdit fromTextLabel &From: fromComboBox layout13 unnamed hideUserCheckBox &Hide identity Alt+H <p> With this option you request your SIP provider to hide your identity from the called party. This will only hide your identity, e.g. your SIP address, telephone number. It does <b>not</b> hide your IP address. </p> <p> <b>Warning:</b> not all providers support identity hiding. </p> spacer5 Horizontal Expanding 181 20 spacer12 Vertical Expanding 20 20 layout20 unnamed spacer11 Horizontal Expanding 91 20 okPushButton &OK true cancelPushButton &Cancel cancelPushButton clicked() InviteForm reject() okPushButton clicked() InviteForm validate() addressToolButton clicked() InviteForm showAddressBook() hideUserCheckBox clicked() InviteForm warnHideUser() inviteComboBox subjectLineEdit hideUserCheckBox addressToolButton okPushButton cancelPushButton fromComboBox qstring.h sockets/url.h getaddressform.h user.h phone.h gui.h util.h audits/memman.h sys_settings.h qregexp.h qvalidator.h inviteform.ui.h extern t_phone *phone; GetAddressForm *getAddressForm; destination(t_user *, const QString &, const t_url &, const QString &, bool) raw_destination(const QString &) clear() show( t_user * user_config, const QString & dest, const QString & subject, bool anonymous ) validate() addToInviteComboBox( const QString & destination ) reject() closeEvent( QCloseEvent * ) showAddressBook() selectedAddress( const QString & address ) warnHideUser( void ) init() destroy() twinkle-1.4.2/src/gui/wizardform.ui0000644000175000001440000003733011134647705014224 00000000000000 WizardForm WizardForm 0 0 596 321 Twinkle - Wizard unnamed layout15 unnamed stunServerLineEdit The hostname, domain name or IP address of the STUN server. stunServerTextLabel S&TUN server: stunServerLineEdit usernameLineEdit The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. domainTextLabel &Domain*: domainLineEdit serviceProviderComboBox Choose your SIP service provider. If your SIP service provider is not in the list, then select <b>Other</b> and fill in the settings you received from your provider.<br><br> If you select one of the predefined SIP service providers then you only have to fill in your name, user name, authentication name and password. authNameTextLabel &Authentication name: authNameLineEdit dislpayTextLabel &Your name: displayLineEdit authNameLineEdit Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. spacer22 Horizontal Expanding 206 20 domainLineEdit The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. displayLineEdit This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. proxyTextLabel true SIP pro&xy: proxyLineEdit proxyLineEdit true The hostname, domain name or IP address of your SIP proxy. If this is the same value as your domain, you may leave this field empty. serviceProviderTextLabel &SIP service provider: serviceProviderComboBox authPasswordTextLabel &Password: authPasswordLineEdit usernameTextLabel &User name*: usernameLineEdit authPasswordLineEdit Password Your password for authentication. spacer23 Vertical Expanding 20 20 layout14 unnamed spacer20 Horizontal Expanding 371 20 okPushButton &OK Alt+O true cancelPushButton &Cancel Alt+C okPushButton clicked() WizardForm validate() cancelPushButton clicked() WizardForm reject() usernameLineEdit textChanged(const QString&) WizardForm updateAuthName(const QString&) serviceProviderComboBox activated(const QString&) WizardForm update(const QString&) authNameLineEdit lostFocus() WizardForm disableSuggestAuthName() serviceProviderComboBox displayLineEdit usernameLineEdit domainLineEdit authNameLineEdit authPasswordLineEdit proxyLineEdit stunServerLineEdit okPushButton cancelPushButton map user.h qregexp.h qlineedit.h qlabel.h qvalidator.h qcombobox.h gui.h qfile.h wizardform.ui.h struct t_provider; bool suggestAuthName; std::map<QString, t_provider> mapProviders; t_user *user_config; success() initProviders() exec( t_user * user ) update( const QString & item ) updateAuthName( const QString & s ) disableSuggestAuthName() validate() init() show( t_user * user ) twinkle-1.4.2/src/gui/numberconversionform.ui0000644000175000001440000001465510541322051016310 00000000000000 NumberConversionForm NumberConversionForm 0 0 436 122 Twinkle - Number conversion unnamed layout43 unnamed exprTextLabel &Match expression: exprLineEdit replaceTextLabel &Replace: replaceLineEdit replaceLineEdit Perl style format string for the replacement number. exprLineEdit Perl style regular expression matching the number format you want to modify. spacer62 Vertical Expanding 20 20 layout44 unnamed spacer61 Horizontal Expanding 71 20 okPushButton &OK Alt+O cancelPushButton &Cancel Alt+C cancelPushButton clicked() NumberConversionForm reject() okPushButton clicked() NumberConversionForm validate() exprLineEdit replaceLineEdit okPushButton cancelPushButton qstring.h gui.h boost/regex.hpp qregexp.h qvalidator.h numberconversionform.ui.h validate() init() exec( QString & expr, QString & replace ) twinkle-1.4.2/src/gui/main.cpp0000644000175000001440000010510311146330705013113 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinkle_config.h" #ifdef HAVE_KDE #include #include #endif #include #include #include #include #include #include "mphoneform.h" #include #include #include #include #include #include #include "address_book.h" #include "address_finder.h" #include "call_history.h" #include "cmd_socket.h" #include "events.h" #include "listener.h" #include "log.h" #include "protocol.h" #include "sender.h" #include "transaction_mgr.h" #include "twinkleapplication.h" #include "user.h" #include "util.h" #include "phone.h" #include "gui.h" #include "qt_translator.h" #include "command_args.h" #include "sockets/connection_table.h" #include "sockets/interfaces.h" #include "sockets/socket.h" #include "threads/thread.h" #include "utils/mime_database.h" #include "audits/memman.h" using namespace std; using namespace utils; // Class to initialize the random generator before objects of // other classes are created. Initializing just from the main function // is too late. class t_init_rand { public: t_init_rand(); }; t_init_rand::t_init_rand() { srand(time(NULL)); } // Initialize random generator t_init_rand init_rand; // Language translator for the core of Twinkle t_translator *translator = NULL; // Indicates if application is ending (because user pressed Quit) bool end_app; // Memory manager for memory leak tracing t_memman *memman; // IP address on which the phone is running string user_host; // Local host name string local_hostname; // SIP UDP socket for sending and receiving signaling t_socket_udp *sip_socket; // SIP TCP socket for sending and receiving signaling t_socket_tcp *sip_socket_tcp; // SIP connection table for connection oriented transport t_connection_table *connection_table; // Event queue that is handled by the transaction manager thread // The following threads write to this queue // - UDP listener // - transaction layer // - timekeeper t_event_queue *evq_trans_mgr; // Event queue that is handled by the UDP sender thread // The following threads write to this queue: // - phone UAS // - phone UAC // - transaction manager t_event_queue *evq_sender; // Event queue that is handled by the transaction layer thread // The following threads write to this queue // - transaction manager // - timekeeper t_event_queue *evq_trans_layer; // Event queue that is handled by the phone timekeeper thread // The following threads write into this queue // - phone UAS // - phone UAC // - transaction manager t_event_queue *evq_timekeeper; // The timekeeper t_timekeeper *timekeeper; // The transaction manager t_transaction_mgr *transaction_mgr; // The phone t_phone *phone; // User interface t_userintf *ui; // Log file t_log *log_file; // System config t_sys_settings *sys_config; // Call history t_call_history *call_history; // Local address book t_address_book *ab_local; // Mime database t_mime_database *mime_database; /** Command arguments. */ t_command_args g_cmd_args; // Thread id of main thread pthread_t thread_id_main; // Indicates if LinuxThreads or NPTL is active. bool threading_is_LinuxThreads; /** * Parse arguments passed to application * @param argc [in] Number of arguments * @param argv [in] Array of arguments * @param cli_mode [out] Indicates if Twinkle must run in CLI mode. * @param override_lock_file [out] Indicates if an existing lock file must be overriden. * @param config_files [out] User profiles passed on the command line. * @param remain_argc [out] The number of arguments not parsed by this function. * @param remain_argv [out] The arguments not parsed by this function. * remain_argv[0] == argv[0] */ void parse_main_args(int argc, char **argv, bool &cli_mode, bool &override_lock_file, list &config_files, int &remain_argc, char **&remain_argv) { cli_mode = false; override_lock_file = false; config_files.clear(); // Initialize the remaining arguments with the first argument (application name) // from the original arguments. remain_argv = (char**)malloc(argc * sizeof(char*)); remain_argv[0] = argv[0]; remain_argc = 1; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { // Help cout << "Usage: twinkle [options]\n\n"; cout << "Options:\n"; cout << " -c"; cout << "\t\tRun in command line interface (CLI) mode\n"; cout << endl; cout << " --share "; cout << "\tSet the share directory.\n"; cout << endl; cout << " -f "; cout << "\tStartup with a specific profile. You will not be requested\n"; cout << "\t\tto choose a profile at startup. The profiles that you created\n"; cout << "\t\tare the .cfg files in your .twinkle directory.\n"; cout << "\t\tYou may specify multiple profiles separated by spaces.\n"; cout << endl; cout << " --force"; cout << "\tIf a lock file is detected at startup, then override it\n"; cout << "\t\tand startup.\n"; cout << endl; #if 0 // DEPRECATED cout << " -i "; cout << "\tIf you have multiple IP addresses on your computer,\n"; cout << "\t\tthen you can supply the IP address to use here.\n"; cout << endl; #endif cout << " --sip-port \n"; cout << "\t\tPort for SIP signalling.\n"; cout << "\t\tThis port overrides the port from the system settings.\n"; cout << endl; cout << " --rtp-port \n"; cout << "\t\tPort for RTP.\n"; cout << "\t\tThis port overrides the port from the system settings.\n"; cout << endl; #if 0 // DEPRECATED cout << " --nic "; cout << "\tIf you have multiple NICs on your computer,\n"; cout << "\t\tthen you can supply the NIC name to use here (e.g. eth0).\n"; cout << endl; #endif cout << " --call
\n"; cout << "\t\tInstruct Twinkle to call the address.\n"; cout << "\t\tWhen Twinkle is already running, this will instruct the running\n"; cout << "\t\tprocess to call the address.\n"; cout << "\t\tThe address may be a full or partial SIP URI. A partial SIP URI\n"; cout << "\t\twill be completed with the information from the user profile.\n"; cout << endl; cout << "\t\tA subject may be passed by appending '?subject='\n"; cout << "\t\tto the address.\n"; cout << endl; cout << "\t\tExamples:\n"; cout << "\t\ttwinkle --call 123456\n"; cout << "\t\ttwinkle --call sip:example@example.com?subject=hello\n"; cout << endl; cout << " --cmd \n"; cout << "\t\tInstruct Twinkle to execute the CLI command. You can run\n"; cout << "\t\tall commands from the command line interface mode.\n"; cout << "\t\tWhen Twinkle is already running, this will instruct the running\n"; cout << "\t\tprocess to execute the CLI command.\n"; cout << endl; cout << "\t\tExamples:\n"; cout << "\t\ttwinkle --cmd answer\n"; cout << "\t\ttwinkle --cmd mute\n"; cout << "\t\ttwinkle --cmd 'transfer 12345'\n"; cout << endl; cout << " --immediate"; cout << "\tThis option can be used in conjunction with --call or --cmd\n"; cout << "\t\tIt indicates the the command or call is to be performed\n"; cout << "\t\timmediately without asking the user for any confirmation.\n"; cout << endl; cout << " --set-profile \n"; cout << "\t\tMake the active profile.\n"; cout << "\t\tWhen using this option in conjuction with --call and --cmd,\n"; cout << "\t\tthen the profile is activated before executing --call or \n"; cout << "\t\t--cmd.\n"; cout << endl; cout << " --show"; cout << "\t\tInstruct a running instance of Twinkle to show the main window\n"; cout << "\t\tand take focus.\n"; cout << endl; cout << " --hide"; cout << "\t\tInstruct a running instance of Twinkle to hide in the sytem tray.\n"; cout << "\t\tIf no system tray is used, then Twinkle will minimize.\n"; cout << endl; cout << " --help-cli [cli command]\n"; cout << "\t\tWithout a cli command this option lists all available CLI\n"; cout << "\t\tcommands. With a CLI command this option prints help on\n"; cout << "\t\tthe CLI command.\n"; cout << endl; cout << " --version"; cout << "\tGet version information.\n"; exit(0); } else if (strcmp(argv[i], "--version") == 0) { // Get version QString s = sys_config->about(false).c_str(); cout << s; exit(0); } else if (strcmp(argv[i], "-c") == 0) { // CLI mode cli_mode = true; } else if (strcmp(argv[i], "--share") == 0) { if (i < argc - 1 && argv[i+1][0] != '-') { i++; sys_config->set_dir_share(argv[i]); } else { cout << argv[0] << ": "; cout << "Directory missing for option '-share'.\n"; exit(0); } } else if (strcmp(argv[i], "-f") == 0) { if (i < argc - 1 && argv[i+1][0] != '-') { while (i < argc -1 && argv[i+1][0] != '-') { i++; // Config file name QString config_file = argv[i]; if (!config_file.endsWith(USER_FILE_EXT)) { config_file += USER_FILE_EXT; } config_files.push_back(config_file.ascii()); } } else { cout << argv[0] << ": "; cout << "Config file name missing for option '-f'.\n"; exit(0); } } else if (strcmp(argv[i], "--force") == 0) { override_lock_file = true; #if 0 // DEPRECATED } else if (strcmp(argv[i], "-i") == 0) { if (i < argc - 1) { i++; // IP address user_host = argv[i]; if (!exists_interface(user_host)) { cout << argv[0] << ": "; cout << "There is no interface with IP address "; cout << user_host << endl; exit(0); } } else { cout << argv[0] << ": "; cout << "IP address missing for option '-i'.\n"; exit(0); } #endif } else if (strcmp(argv[i], "--sip-port") == 0) { if (i < argc - 1) { i++; g_cmd_args.override_sip_port = atoi(argv[i]); } else { cout << argv[0] << ": "; cout << "Port missing for option '--sip-port'\n"; } } else if (strcmp(argv[i], "--rtp-port") == 0) { if (i < argc - 1) { i++; g_cmd_args.override_rtp_port = atoi(argv[i]); } else { cout << argv[0] << ": "; cout << "Port missing for option '--rtp-port'\n"; } } else if (strcmp(argv[i], "--call") == 0) { if (i < argc - 1) { i++; // SIP URI g_cmd_args.callto_destination = argv[i]; if (g_cmd_args.callto_destination.isEmpty()) { cout << argv[0] << ": "; cout << "--call argument may not be empty.\n"; exit(0); } } else { cout << argv[0] << ": "; cout << "SIP URI missing for option '--call'.\n"; exit(0); } } else if (strcmp(argv[i], "--cmd") == 0) { if (i < argc - 1) { i++; // CLI command g_cmd_args.cli_command = argv[i]; if (g_cmd_args.cli_command.isEmpty()) { cout << argv[0] << ": "; cout << "--cmd argument may not be empty.\n"; exit(0); } } else { cout << argv[0] << ": "; cout << "CLI command missing for option '--cmd'.\n"; exit(0); } } else if (strcmp(argv[i], "--immediate") == 0) { // Immediate mode g_cmd_args.cmd_immediate_mode = true; } else if (strcmp(argv[i], "--set-profile") == 0) { if (i < argc - 1) { i++; // Set profile g_cmd_args.cmd_set_profile = argv[i]; } else { cout << argv[0] << ": "; cout << "Profile missing for option '--set-profile'.\n"; exit(0); } } else if (strcmp(argv[i], "--show") == 0) { // Show main window g_cmd_args.cmd_show = true; } else if (strcmp(argv[i], "--hide") == 0) { // Hide main window g_cmd_args.cmd_hide = true; } else if (strcmp(argv[i], "--help-cli") == 0) { string cmd_help("help "); if (i < argc -1) { i++; // Help CLI cmd_help += argv[i]; } t_phone p; t_userintf u(&p); u.exec_command(cmd_help); exit(0); } else { // Unknown argument. Assume that it is an Qt/KDE argument. remain_argv[remain_argc++] = argv[i]; } } if (!g_cmd_args.callto_destination.isEmpty() && !g_cmd_args.cli_command.isEmpty()) { cout << argv[0] << ": "; cout << "--call and --cmd cannot be used at the same time.\n"; exit(0); } return; } bool open_sip_socket(bool cli_mode) { QString sock_type; // Open socket for SIP signaling try { sock_type = "UDP"; sip_socket = new t_socket_udp(sys_config->get_sip_port(true)); MEMMAN_NEW(sip_socket); if (sip_socket->enable_icmp()) { log_file->write_report("ICMP processing enabled.", "::main"); } else { log_file->write_report("ICMP processing disabled.", "::main"); } sock_type = "TCP"; sip_socket_tcp = new t_socket_tcp(sys_config->get_sip_port()); MEMMAN_NEW(sip_socket_tcp); } catch (int err) { string msg; if (cli_mode) { msg = QString("Failed to create a %1 socket (SIP) on port %2") .arg(sock_type) .arg(sys_config->get_sip_port()).ascii(); } else { msg = qApp->translate("GUI", "Failed to create a %1 socket (SIP) on port %2") .arg(sock_type) .arg(sys_config->get_sip_port()).ascii(); } msg += "\n"; msg += get_error_str(err); log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); return false; } return true; } QApplication *create_user_interface(bool cli_mode, int argc, char **argv, QTranslator *qtranslator) { QApplication *qa = NULL; if (cli_mode) { // CLI mode ui = new t_userintf(phone); MEMMAN_NEW(ui); } else { // GUI mode #ifdef HAVE_KDE // Store the defualt mime source factory for the embedded icons. // This is created by Qt. The KApplication constructor seems to destroy // this default. QMimeSourceFactory *factory_qt = QMimeSourceFactory::takeDefaultFactory(); // Initialize the KApplication KCmdLineArgs::init(argc, argv, "twinkle", PRODUCT_NAME, "Soft phone", PRODUCT_VERSION, true); qa = new t_twinkle_application(); MEMMAN_NEW(qa); // Store the KDE mime source factory QMimeSourceFactory *factory_kde = QMimeSourceFactory::takeDefaultFactory(); // Make the Qt factory the default to make the embedded icons work. QMimeSourceFactory::setDefaultFactory(factory_qt); // Add the KDE factory QMimeSourceFactory::addFactory(factory_kde); #else int tmp = argc; qa = new t_twinkle_application(tmp, argv); MEMMAN_NEW(qa); #endif QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8")); QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); // Install Qt translator // Do not report to memman as the translator will be deleted // automatically when the QApplication is deleted. qtranslator = new QTranslator(0); qtranslator->load(QString("twinkle_") + QTextCodec::locale(), QString(sys_config->get_dir_lang().c_str())); qa->installTranslator(qtranslator); // Create translator for translation of strings from the core translator = new t_qt_translator(qa); MEMMAN_NEW(translator); ui = new t_gui(phone); MEMMAN_NEW(ui); } return qa; } int main( int argc, char ** argv ) { string error_msg; bool cli_mode; bool override_lock_file; list config_files; // Initialize globals end_app = false; // Determine threading implementation threading_is_LinuxThreads = t_thread::is_LinuxThreads(); QApplication *qa = NULL; QTranslator *qtranslator = NULL; // Store id of main thread thread_id_main = t_thread::self(); memman = new t_memman(); MEMMAN_NEW(memman); connection_table = new t_connection_table(); MEMMAN_NEW(connection_table); evq_trans_mgr = new t_event_queue(); MEMMAN_NEW(evq_trans_mgr); evq_sender = new t_event_queue(); MEMMAN_NEW(evq_sender); evq_trans_layer = new t_event_queue(); MEMMAN_NEW(evq_trans_layer); evq_timekeeper = new t_event_queue(); MEMMAN_NEW(evq_timekeeper); timekeeper = new t_timekeeper(); MEMMAN_NEW(timekeeper); transaction_mgr = new t_transaction_mgr(); MEMMAN_NEW(transaction_mgr); phone = new t_phone(); MEMMAN_NEW(phone); // Create system configuration object sys_config = new t_sys_settings(); MEMMAN_NEW(sys_config); // Parse command line arguments int remain_argc = 0; char **remain_argv = NULL; parse_main_args(argc, argv, cli_mode, override_lock_file, config_files, remain_argc, remain_argv); sys_config->set_override_sip_port(g_cmd_args.override_sip_port); sys_config->set_override_rtp_port(g_cmd_args.override_rtp_port); // Checking the environment and creating the lock is done at // this early stage to improve performance of the --call parameter. // Creation of the QApplication object for the GUI is slow. // However for errors, the user interface must be created to give // either a message box or text formatted error. // Check requirements on environment // If check fails, then display error after user interface has been // created. string env_error_msg; bool env_check_ok = sys_config->check_environment(env_error_msg); // Create a lock file to guarantee that the application runs only once. bool already_running; bool lock_created = false; string lock_error_msg; if (env_check_ok && !(lock_created = sys_config->create_lock_file(false, lock_error_msg, already_running))) { bool must_exit = false; // Show the main window of the running Twinkle process. if (already_running && g_cmd_args.cmd_show) { cmdsocket::cmd_show(); must_exit = true; } // Hide the main window of the running Twinkle process. if (already_running && g_cmd_args.cmd_hide) { cmdsocket::cmd_hide(); must_exit = true; } // Activate a profile in the running Twinkle process. if (already_running && !g_cmd_args.cmd_set_profile.isEmpty()) { cmdsocket::cmd_cli(string("user ") + g_cmd_args.cmd_set_profile.ascii(), true); // Do not exit now as this option may be used in conjuction // with --call or --cmd must_exit = true; } // If Twinkle is running already and the --call parameter // is present, then send the call destination to the running // Twinkle process. if (already_running && !g_cmd_args.callto_destination.isEmpty()) { cmdsocket::cmd_call(g_cmd_args.callto_destination.ascii(), g_cmd_args.cmd_immediate_mode); exit(0); } // If the --cmd parameter is present, send the cli command // to the running Twinkle process if (already_running && !g_cmd_args.cli_command.isEmpty()) { cmdsocket::cmd_cli(g_cmd_args.cli_command.ascii(), g_cmd_args.cmd_immediate_mode); exit(0); } // Exit if an instruction for a running instance was given. if (must_exit) { exit(0); } } // Read system configuration bool sys_config_read = sys_config->read_config(error_msg); qa = create_user_interface(cli_mode, remain_argc, remain_argv, qtranslator); if (!sys_config_read) { ui->cb_show_msg(error_msg, MSG_CRITICAL); exit(1); } user_host = AUTO_IP4_ADDRESS; local_hostname = get_local_hostname(); if (!env_check_ok) { // Environment is not good // Call the check_environment once more to get proper translation // of the error message. The previous check was done before // the QApplication was created. (void)sys_config->check_environment(env_error_msg); ui->cb_show_msg(env_error_msg, MSG_CRITICAL); exit(1); } // Show error if lock file could not be created if (!lock_created) { string msg; // Call create lock file once more to get proper translation of // error message. if (!sys_config->create_lock_file(false, msg, already_running)) { if (already_running) { if (!cli_mode) { msg += "\n\n"; msg += qApp->translate("GUI", "Override lock file and start anyway?").ascii(); } if (override_lock_file || ui->cb_ask_msg(msg, MSG_WARNING)) { sys_config->delete_lock_file(); if (!sys_config->create_lock_file(true, msg, already_running)) { ui->cb_show_msg(msg, MSG_CRITICAL); exit(1); } } else { exit(1); } } else { ui->cb_show_msg(msg, MSG_CRITICAL); exit(1); } } // If for some obscure reason the lock file could be // created this time, then continue. } // Create log file log_file = new t_log(); MEMMAN_NEW(log_file); // Write threading implementation to log file. May be useful for debugging. if (threading_is_LinuxThreads) { log_file->write_report("Threading implementation is LinuxThreads.", "::main", LOG_NORMAL, LOG_INFO); } else { log_file->write_report("Threading implementation is NPTL.", "::main", LOG_NORMAL, LOG_INFO); } // Check if the previous Twinkle session was stopped by a system // shutdow and now gets restored. if (qa && qa->isSessionRestored()) { QString msg = "Restore session: " + qa->sessionId(); log_file->write_report(msg.ascii(), "::main"); if (sys_config->get_ui_session_id() == qa->sessionId().ascii()) { config_files = sys_config->get_ui_session_active_profiles(); // Note: the GUI state is restore in t_gui::run() } else { log_file->write_header("::main", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Cannot restore session.\n"); log_file->write_raw("Stored session id: "); log_file->write_raw(sys_config->get_ui_session_id()); log_file->write_endl(); log_file->write_footer(); } } // Get default values from system configuration if (config_files.empty()) { list start_user_profiles = sys_config->get_start_user_profiles(); for (list::iterator i = start_user_profiles.begin(); i != start_user_profiles.end(); i++) { QString config_file = (*i).c_str(); config_file += USER_FILE_EXT; config_files.push_back(config_file.ascii()); } } bool profile_selected = false; while(!profile_selected) { // Select user profile if (config_files.empty()) { if (!ui->select_user_config(config_files)) { sys_config->delete_lock_file(); exit(1); } } for (list::iterator i = config_files.begin(); i != config_files.end(); i++) { t_user user_config; // Read user configuration if (user_config.read_config(*i, error_msg)) { t_user *dup_user; if (phone->add_phone_user( user_config, &dup_user)) { profile_selected = true; } else { if (cli_mode) { error_msg = QString("The following profiles are both for user %1").arg(user_config.get_name().c_str()).ascii(); } else { error_msg = qApp->translate("GUI", "The following profiles are both for user %1").arg(user_config.get_name().c_str()).ascii(); } error_msg += ":\n\n"; error_msg += user_config.get_profile_name(); error_msg += "\n"; error_msg += dup_user->get_profile_name(); error_msg += "\n\n"; if (cli_mode) { error_msg += QString("You can only run multiple profiles for different users.").ascii(); error_msg += "\n"; error_msg += QString("If these are users for different domains, then enable the following option in your user profile (SIP protocol):"); error_msg += "\n"; error_msg += QString("Use domain name to create a unique contact header"); } else { error_msg += qApp->translate("GUI", "You can only run multiple profiles for different users.").ascii(); error_msg += "\n"; error_msg += qApp->translate("GUI", "If these are users for different domains, then enable the following option in your user profile (SIP protocol)"); error_msg += ":\n"; error_msg += qApp->translate("GUI", "Use domain name to create a unique contact header"); } ui->cb_show_msg(error_msg, MSG_CRITICAL); profile_selected = false; break; } } else { ui->cb_show_msg(error_msg, MSG_CRITICAL); profile_selected = false; break; } } if (profile_selected && !open_sip_socket(cli_mode)) { // Opening SIP socket failed. Let user pick a user profile // again, so he can make changes in settings to fix the error. profile_selected = false; } // In CLI mode the user cannot select another profile. if (!profile_selected) { if (cli_mode) { sys_config->delete_lock_file(); exit(1); } } config_files.clear(); } // Initialize RTP port settings. phone->init_rtp_ports(); // Create call history call_history = new t_call_history(); MEMMAN_NEW(call_history); // Read call history if (!call_history->load(error_msg)) { log_file->write_report(error_msg, "::main", LOG_NORMAL, LOG_WARNING); } // Create local address book ab_local = new t_address_book(); MEMMAN_NEW(ab_local); // Read local address book if (!ab_local->load(error_msg)) { log_file->write_report(error_msg, "::main", LOG_NORMAL, LOG_WARNING); ui->cb_show_msg(error_msg, MSG_WARNING); } // Preload the address finder (KABC is only available in GUI mode) if (!cli_mode) { t_address_finder::preload(); } // Create mime database mime_database = new t_mime_database(); MEMMAN_NEW(mime_database); if (!mime_database->load(error_msg)) { log_file->write_report(error_msg, "::main", LOG_NORMAL, LOG_WARNING); } // Discover NAT type if STUN is enabled list user_list = phone->ref_users(); ui->cb_nat_discovery_progress_start(user_list.size()); list msg_list; int progressStep = 0; for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { ui->cb_nat_discovery_progress_step(progressStep); if (ui->cb_nat_discovery_cancelled()) { log_file->write_report("User aborted NAT discovery.", "::main"); sys_config->delete_lock_file(); exit(1); } if (!phone->stun_discover_nat(*i, error_msg)) { msg_list.push_back(error_msg); } progressStep++; } ui->cb_nat_discovery_finished(); for (list::iterator i = msg_list.begin(); i != msg_list.end(); i++) { ui->cb_show_msg(*i, MSG_WARNING); } // Open socket for external commands from the command line string cmd_sock_name = sys_config->get_dir_user(); cmd_sock_name += '/'; cmd_sock_name += CMD_SOCKNAME; t_socket_local *sock_cmd = NULL; try { // The local socket may still exist if Twinkle got killed // previously, so remove it if it is still there. unlink(cmd_sock_name.c_str()); sock_cmd = new t_socket_local(); MEMMAN_NEW(sock_cmd); sock_cmd->bind(cmd_sock_name); sock_cmd->listen(5); string log_msg = "Created local socket: "; log_msg += cmd_sock_name; log_file->write_report(log_msg, "::main"); } catch (int e) { if (sock_cmd) { MEMMAN_DELETE(sock_cmd); delete sock_cmd; sock_cmd = NULL; } string log_msg = "Failed to create local socket: "; log_msg += cmd_sock_name; log_msg += "\n"; log_msg += get_error_str(e); log_msg += "\n"; log_file->write_report(log_msg, "::main", LOG_NORMAL, LOG_WARNING); } // Dedicated thread will catch SIGALRM, SIGINT, SIGTERM, SIGCHLD signals, // therefore all threads must block these signals. Block now, then all // created threads will inherit the signal mask. // In LinuxThreads the sigwait does not work very well, so // in LinuxThreads a signal handler is used instead. if (!threading_is_LinuxThreads) { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, NULL); } else { if (!phone->set_sighandler()) { string msg = "Failed to register signal handler."; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } } // Ignore SIGPIPE so read from broken sockets will not cause // the process to terminate. (void)signal(SIGPIPE, SIG_IGN); // Create threads t_thread *thr_sender; t_thread *thr_tcp_sender; t_thread *thr_listen_udp; t_thread *thr_listen_data_tcp; t_thread *thr_listen_conn_tcp; t_thread *thr_conn_timeout_handler; t_thread *thr_timekeeper; t_thread *thr_alarm_catcher = NULL; t_thread *thr_sig_catcher = NULL; t_thread *thr_trans_mgr; t_thread *thr_phone_uas; t_thread *thr_listen_cmd = NULL; try { // SIP sender thread thr_sender = new t_thread(sender_loop, NULL); MEMMAN_NEW(thr_sender); // SIP TCP sender thread thr_tcp_sender = new t_thread(tcp_sender_loop, NULL); MEMMAN_NEW(thr_tcp_sender); // UDP listener thread thr_listen_udp = new t_thread(listen_udp, NULL); MEMMAN_NEW(thr_listen_udp); // TCP data listener thread thr_listen_data_tcp = new t_thread(listen_for_data_tcp, NULL); MEMMAN_NEW(thr_listen_data_tcp); // TCP connection listener thread thr_listen_conn_tcp = new t_thread(listen_for_conn_requests_tcp, NULL); MEMMAN_NEW(thr_listen_conn_tcp); // Connection timeout handler thread thr_conn_timeout_handler = new t_thread(connection_timeout_main, NULL); MEMMAN_NEW(thr_conn_timeout_handler); // Timekeeper thread thr_timekeeper = new t_thread(timekeeper_main, NULL); MEMMAN_NEW(thr_timekeeper); if (!threading_is_LinuxThreads) { // Alarm catcher thread thr_alarm_catcher = new t_thread(timekeeper_sigwait, NULL); MEMMAN_NEW(thr_alarm_catcher); // Signal catcher thread thr_sig_catcher = new t_thread(phone_sigwait, NULL); MEMMAN_NEW(thr_sig_catcher); } // Transaction manager thread thr_trans_mgr = new t_thread(transaction_mgr_main, NULL); MEMMAN_NEW(thr_trans_mgr); // Phone thread (UAS) thr_phone_uas = new t_thread(phone_uas_main, NULL); MEMMAN_NEW(thr_phone_uas); // External command listener thread if (sock_cmd) { thr_listen_cmd = new t_thread(cmdsocket::listen_cmd, sock_cmd); MEMMAN_NEW(thr_listen_cmd); } } catch (int) { string msg = "Failed to create threads."; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } // Validate sound devices if (!sys_config->exec_audio_validation(true, true, true, error_msg)) { ui->cb_show_msg(error_msg, MSG_WARNING); } // Start UI event loop (CLI/QApplication/KApplication) try { ui->run(); } catch (string e) { string msg = "Exception: "; msg += e; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } catch (...) { string msg = "Unknown exception"; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } // Application is ending end_app = true; // Terminate threads // Kill the threads getting receiving input from the outside world first, // so no new inputs come in during termination. if (thr_listen_cmd) { thr_listen_cmd->cancel(); thr_listen_cmd->join(); log_file->write_report("thr_listen_cmd stopped.", "::main", LOG_NORMAL, LOG_DEBUG); } thr_listen_udp->cancel(); thr_listen_udp->join(); log_file->write_report("thr_listen_udp stopped.", "::main", LOG_NORMAL, LOG_DEBUG); thr_listen_conn_tcp->cancel(); thr_listen_conn_tcp->join(); log_file->write_report("thr_listen_conn_tcp stopped.", "::main", LOG_NORMAL, LOG_DEBUG); connection_table->cancel_select(); thr_listen_data_tcp->join(); log_file->write_report("thr_listen_data_tcp stopped.", "::main", LOG_NORMAL, LOG_DEBUG); thr_conn_timeout_handler->join(); log_file->write_report("thr_conn_timeout_handler stopped.", "::main", LOG_NORMAL, LOG_DEBUG); thr_tcp_sender->join(); log_file->write_report("thr_tcp_sender stopped.", "::main", LOG_NORMAL, LOG_DEBUG); evq_trans_layer->push_quit(); thr_phone_uas->join(); log_file->write_report("thr_phone_uas stopped.", "::main", LOG_NORMAL, LOG_DEBUG); evq_trans_mgr->push_quit(); thr_trans_mgr->join(); if (!threading_is_LinuxThreads) { try { thr_sig_catcher->cancel(); } catch (int) { // Thread terminated already by itself } thr_sig_catcher->join(); log_file->write_report("thr_sig_catcher stopped.", "::main", LOG_NORMAL, LOG_DEBUG); thr_alarm_catcher->cancel(); thr_alarm_catcher->join(); log_file->write_report("thr_alarm_catcher stopped.", "::main", LOG_NORMAL, LOG_DEBUG); } evq_timekeeper->push_quit(); thr_timekeeper->join(); log_file->write_report("thr_timekeeper stopped.", "::main", LOG_NORMAL, LOG_DEBUG); evq_sender->push_quit(); thr_sender->join(); log_file->write_report("thr_sender stopped.", "::main", LOG_NORMAL, LOG_DEBUG); sys_config->remove_all_tmp_files(); if (thr_listen_cmd) { MEMMAN_DELETE(thr_listen_cmd); delete thr_listen_cmd; } MEMMAN_DELETE(thr_phone_uas); delete thr_phone_uas; MEMMAN_DELETE(thr_trans_mgr); delete thr_trans_mgr; MEMMAN_DELETE(thr_timekeeper); delete thr_timekeeper; MEMMAN_DELETE(thr_conn_timeout_handler); delete thr_conn_timeout_handler; if (!threading_is_LinuxThreads) { MEMMAN_DELETE(thr_sig_catcher); delete thr_sig_catcher; MEMMAN_DELETE(thr_alarm_catcher); delete thr_alarm_catcher; } MEMMAN_DELETE(thr_listen_udp); delete thr_listen_udp; MEMMAN_DELETE(thr_sender); delete thr_sender; MEMMAN_DELETE(thr_tcp_sender); delete thr_tcp_sender; MEMMAN_DELETE(thr_listen_data_tcp); delete thr_listen_data_tcp; MEMMAN_DELETE(thr_listen_conn_tcp); delete thr_listen_conn_tcp; MEMMAN_DELETE(mime_database); delete mime_database; MEMMAN_DELETE(ab_local); delete ab_local; MEMMAN_DELETE(call_history); delete call_history; call_history = NULL; MEMMAN_DELETE(ui); delete ui; ui = NULL; MEMMAN_DELETE(connection_table); delete connection_table; MEMMAN_DELETE(sip_socket_tcp); delete sip_socket_tcp; MEMMAN_DELETE(sip_socket); delete sip_socket; if (sock_cmd) { MEMMAN_DELETE(sock_cmd); delete sock_cmd; unlink(cmd_sock_name.c_str()); } MEMMAN_DELETE(phone); delete phone; MEMMAN_DELETE(transaction_mgr); delete transaction_mgr; MEMMAN_DELETE(timekeeper); delete timekeeper; MEMMAN_DELETE(evq_trans_mgr); delete evq_trans_mgr; MEMMAN_DELETE(evq_sender); delete evq_sender; MEMMAN_DELETE(evq_trans_layer); delete evq_trans_layer; MEMMAN_DELETE(evq_timekeeper); delete evq_timekeeper; if (translator) { MEMMAN_DELETE(translator); delete translator; translator = NULL; } if (qtranslator) { MEMMAN_DELETE(qtranslator); delete(qtranslator); } if (qa) { MEMMAN_DELETE(qa); delete qa; } // Report memory leaks // Report deletion of log_file and sys_config already to get a correct // report. MEMMAN_DELETE(sys_config); MEMMAN_DELETE(log_file); MEMMAN_DELETE(memman); MEMMAN_REPORT; delete log_file; delete memman; sys_config->delete_lock_file(); delete sys_config; } twinkle-1.4.2/src/gui/userprofileform.ui0000644000175000001440000123672711146337650015275 00000000000000 UserProfileForm UserProfileForm 0 0 783 594 Twinkle - User Profile unnamed layout142 unnamed profileTextLabel User profile: profileComboBox 7 0 0 0 Select which profile you want to edit. User penguin.png SIP server package_network.png Voice mail mwi_none.png Instant message message32.png Presence presence.png RTP audio kmix.png SIP protocol package_system.png Transport/NAT yast_babelfish.png Address format yast_PhoneTTOffhook.png Timers clock.png Ring tones knotify.png Scripts edit.png Security encrypted32.png categoryListBox 1 7 0 0 150 0 0 Select a category for which you want to see or modify the settings. layout12 unnamed spacer8 Horizontal Expanding 441 20 okPushButton &OK Alt+O true Accept and save your changes. cancelPushButton &Cancel Alt+C Undo all your changes and close the window. settingsWidgetStack 7 5 0 0 Box pageUser 0 unnamed userTitleTextLabel 150 150 150 21 Box User 10 accountGroupBox SIP account unnamed usernameTextLabel &User name*: usernameLineEdit domainTextLabel &Domain*: domainLineEdit organizationTextLabel Or&ganization: organizationLineEdit usernameLineEdit The SIP user name given to you by your provider. It is the user part in your SIP address, <b>username</b>@domain.com This could be a telephone number. <br><br> This field is mandatory. domainLineEdit The domain part of your SIP address, username@<b>domain.com</b>. Instead of a real domain this could also be the hostname or IP address of your <b>SIP proxy</b>. If you want direct IP phone to IP phone communications then you fill in the hostname or IP address of your computer. <br><br> This field is mandatory. organizationLineEdit You may fill in the name of your organization. When you make a call, this might be shown to the called party. displayLineEdit This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. dislpayTextLabel &Your name: displayLineEdit authenticationGroupBox SIP authentication unnamed authRealmTextLabel &Realm: authRealmLineEdit authNameTextLabel Authentication &name: authNameLineEdit authRealmLineEdit The realm for authentication. This value must be provided by your SIP provider. If you leave this field empty, then Twinkle will try the user name and password for any realm that it will be challenged with. authNameLineEdit Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. authAkaAmfTextLabel AKA AM&F: authAkaAmfLineEdit authAkaOpTextLabel A&KA OP: authAkaOpLineEdit authPasswordLineEdit Password Your password for authentication. authPasswordTextLabel &Password: authPasswordLineEdit authAkaAmfLineEdit Authentication management field for AKAv1-MD5 authentication. authAkaOpLineEdit Operator variant key for AKAv1-MD5 authentication. spacer9 Vertical Expanding 20 110 pageSipServer 1 unnamed sipServerTitleTextLabel 150 150 150 21 Box SIP server 10 registrarGroupBox Registrar unnamed registrarTextLabel &Registrar: registrarLineEdit registrarLineEdit The hostname, domain name or IP address of your registrar. If you use an outbound proxy that is the same as your registrar, then you may leave this field empty and only fill in the address of the outbound proxy. expiryTextLabel &Expiry: expirySpinBox layout22 unnamed expirySpinBox 90 0 999999 100 The registration expiry time that Twinkle will request. secondsTextLabel seconds spacer1 Horizontal Expanding 260 20 regAtStartupCheckBox Re&gister at startup Alt+G Indicates if Twinkle should automatically register when you run this user profile. You should disable this when you want to do direct IP phone to IP phone communication without a SIP proxy. layout37 unnamed regAddQvalueCheckBox Add q-value to registration The q-value indicates the priority of your registered device. If besides Twinkle you register other SIP devices for this account, then the network may use these values to determine which device to try first when delivering a call. regQvalueLineEdit The q-value is a value between 0.000 and 1.000. A higher value means a higher priority. spacer48 Horizontal Expanding 210 20 outboundProxyGroupBox Outbound Proxy unnamed useProxyCheckBox &Use outbound proxy Alt+U Indicates if Twinkle should use an outbound proxy. If an outbound proxy is used then all SIP requests are sent to this proxy. Without an outbound proxy, Twinkle will try to resolve the SIP address that you type for a call invitation for example to an IP address and send the SIP request there. proxyTextLabel true Outbound &proxy: proxyLineEdit proxyNonResolvableCheckBox &Don't send a request to proxy if its destination can be resolved locally. Alt+D When you tick this option Twinkle will first try to resolve a SIP address to an IP address itself. If it can, then the SIP request will be sent there. Only when it cannot resolve the address, it will send the SIP request to the proxy (note that an in-dialog request will only be sent to the proxy in this case when you also ticked the previous option.) proxyLineEdit true The hostname, domain name or IP address of your outbound proxy. allRequestsCheckBox &Send in-dialog requests to proxy Alt+S SIP requests within a SIP dialog are normally sent to the address in the contact-headers exchanged during call setup. If you tick this box, that address is ignored and in-dialog request are also sent to the outbound proxy. spacer10 Vertical Expanding 20 100 pageRtpAudio 2 unnamed rtpAudioTitleTextLabel 150 150 150 21 Box RTP audio 10 rtpAudioTabWidget tabCodecs Co&decs unnamed layout18 unnamed ptimeTextLabel &G.711/G.726 payload size: ptimeSpinBox ptimeSpinBox 1 0 0 0 46 0 32767 32767 50 10 10 The preferred payload size for the G.711 and G.726 codecs. payloadMsTextLabel ms spacer24 Horizontal Expanding 121 20 inFarEndCodecPrefCheckBox &Follow codec preference from far end on incoming calls Alt+F <p> For incoming calls, follow the preference from the far-end (SDP offer). Pick the first codec from the SDP offer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP offer is picked. outFarEndCodecPrefCheckBox Follow codec &preference from far end on outgoing calls Alt+P <p> For outgoing calls, follow the preference from the far-end (SDP answer). Pick the first codec from the SDP answer that is also in the list of active codecs. <p> If you disable this option, then the first codec from the active codecs that is also in the SDP answer is picked. spacer38 Vertical Expanding 20 16 codecsGroupBox Codecs unnamed layout19 unnamed availCodecTextLabel Available codecs: G.711 A-law G.711 u-law GSM speex-nb (8 kHz) speex-wb (16 kHz) speex-uwb (32 kHz) availCodecListBox Manual AlwaysOff List of available codecs. layout14 unnamed spacer17_2 Vertical Expanding 20 20 addCodecPushButton 1rightarrow.png Move a codec from the list of available codecs to the list of active codecs. rmvCodecPushButton 1leftarrow.png Move a codec from the list of active codecs to the list of available codecs. spacer18 Vertical Expanding 20 21 layout20 unnamed useCodecTextLabel Active codecs: activeCodecListBox List of active codecs. These are the codecs that will be used for media negotiation during call setup. The order of the codecs is the order of preference of use. layout15 unnamed spacer19_2 Vertical Expanding 20 21 upCodecPushButton 1uparrow.png Move a codec upwards in the list of active codecs, i.e. increase its preference of use. downCodecPushButton 1downarrow.png Move a codec downwards in the list of active codecs, i.e. decrease its preference of use. spacer20_2 Vertical Expanding 20 31 tabPreprocessing Prepr&ocessing unnamed preprocessingGroupBox Preprocessing (improves quality at remote end) unnamed layout23 unnamed spxDspAgcCheckBox &Automatic gain control Alt+A Automatic gain control (AGC) is a feature that deals with the fact that the recording volume may vary by a large amount between different setups. The AGC provides a way to adjust a signal to a reference volume. This is useful because it removes the need for manual adjustment of the microphone gain. A secondary advantage is that by setting the microphone gain to a conservative (low) level, it is easier to avoid clipping. spxDspAgcLevelTextLabel true Automatic gain control &level: spxDspAgcLevelSpinBox spxDspAgcLevelSpinBox true 100 1 Automatic gain control level represents percentual value of automatic gain setting of a microphone. Recommended value is about 25%. spxDspVadCheckBox &Voice activity detection Alt+V When enabled, voice activity detection detects whether the input signal represents a speech or a silence/background noise. spxDspNrdCheckBox &Noise reduction Alt+N The noise reduction can be used to reduce the amount of background noise present in the input signal. This provides higher quality speech. spxDspAecCheckBox Acoustic &Echo Cancellation Alt+E In any VoIP communication, if a speech from the remote end is played in the local loudspeaker, then it propagates in the room and is captured by the microphone. If the audio captured from the microphone is sent directly to the remote end, then the remote user hears an echo of his voice. An acoustic echo cancellation is designed to remove the acoustic echo before it is sent to the remote end. It is important to understand that the echo canceller is meant to improve the quality on the remote end. spacer24 Horizontal Expanding 31 20 spacer25 Vertical Expanding 20 121 tabIlbc &iLBC unnamed ilbcGroupBox iLBC unnamed layout16 unnamed ilbcPayloadTextLabel i&LBC payload type: ilbcPayloadSpinBox ilbcPayloadSizeTextLabel iLBC &payload size (ms): ilbcPayloadSizeComboBox layout17_2 unnamed ilbcPayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for iLBC. 20 30 ilbcPayloadSizeComboBox The preferred payload size for iLBC. spacer26 Horizontal Expanding 71 20 spacer29_2 Vertical Expanding 20 81 tabSpeex &Speex unnamed speexGroupBox Speex unnamed layout17_3 unnamed spxPenhCheckBox Perceptual &enhancement Alt+E Perceptual enhancement is a part of the decoder which, when turned on, tries to reduce (the perception of) the noise produced by the coding/decoding process. In most cases, perceptual enhancement make the sound further from the original objectively (if you use SNR), but in the end it still sounds better (subjective improvement). spxUwbPayloadTextLabel &Ultra wide band payload type: spxUwbPayloadSpinBox spxWbPayloadTextLabel &Wide band payload type: spxWbPayloadSpinBox spxVbrCheckBox Variable &bit-rate Alt+B Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to the "difficulty" of the audio being encoded. In the example of Speex, sounds like vowels and high-energy transients require a higher bit-rate to achieve good quality, while fricatives (e.g. s,f sounds) can be coded adequately with less bits. For this reason, VBR can achieve a lower bit-rate for the same quality, or a better quality for a certain bit-rate. Despite its advantages, VBR has two main drawbacks: first, by only specifying quality, there's no guarantee about the final average bit-rate. Second, for some real-time applications like voice over IP (VoIP), what counts is the maximum bit-rate, which must be low enough for the communication channel. spxUwbPayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for speex wide band. spxDtxCheckBox Discontinuous &Transmission Alt+T Discontinuous transmission is an addition to VAD/VBR operation, that allows to stop transmitting completely when the background noise is stationary. spxWbPayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for speex wide band. spxNbPayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for speex narrow band. spxQualityTextLabel &Quality: spxQualitySpinBox spxQualitySpinBox 10 0 Speex is a lossy codec, which means that it achives compression at the expense of fidelity of the input speech signal. Unlike some other speech codecs, it is possible to control the tradeoff made between quality and bit-rate. The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. spxComplexityTextLabel Co&mplexity: spxComplexitySpinBox spxComplexitySpinBox 10 1 With Speex, it is possible to vary the complexity allowed for the encoder. This is done by controlling how the search is performed with an integer ranging from 1 to 10 in a way that's similar to the -1 to -9 options to gzip and bzip2 compression utilities. For normal use, the noise level at complexity 1 is between 1 and 2 dB higher than at complexity 10, but the CPU requirements for complexity 10 is about 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF tones. spxNbPayloadTextLabel &Narrow band payload type: spxNbPayloadSpinBox spacer23_2 Horizontal Expanding 31 20 spacer30_2 Vertical Expanding 20 121 tabG726 G.726 unnamed g726GroupBox G.726 unnamed layout22 unnamed g72640PayloadTypeTextLabel G.726 &40 kbps payload type: g72640PayloadSpinBox g72640PayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for G.726 40 kbps. g72632PayloadSpinBox 127 0 The dynamic type value (96 or higher) to be used for G.726 32 kbps. g72624PayloadTypeTextLabel G.726 &24 kbps payload type: g72624PayloadSpinBox g72624PayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for G.726 24 kbps. g72632PayloadTypeTextLabel G.726 &32 kbps payload type: g72632PayloadSpinBox g72616PayloadSpinBox 127 96 The dynamic type value (96 or higher) to be used for G.726 16 kbps. g72616PayloadTypeTextLabel G.726 &16 kbps payload type: g72616PayloadSpinBox spacer31 Horizontal Expanding 231 20 layout41 unnamed g726PackingTextLabel Codeword &packing order: g726PackComboBox RFC 3551 ATM AAL2 g726PackComboBox There are 2 standards to pack the G.726 codewords into an RTP packet. RFC 3551 is the default packing method. Some SIP devices use ATM AAL2 however. If you experience bad quality using G.726 with RFC 3551 packing, then try ATM AAL2 packing. spacer40_2 Horizontal Expanding 141 20 spacer32 Vertical Expanding 20 150 tabDtmf DT&MF unnamed dtmfGroupBox DTMF unnamed spacer17 Horizontal Expanding 280 20 layout8 unnamed dtmfPayloadTypeSpinBox 1 0 0 0 49 0 32767 32767 127 96 The dynamic type value (96 or higher) to be used for DTMF events (RFC 2833). dtmfDurationMsTextLabel ms dtmfVolumeTextLabel DTMF vo&lume: dtmfVolumeSpinBox dtmfVolumeSpinBox 0 -63 10 -10 The power level of the DTMF tone in dB. dtmfPauseSpinBox 1 0 0 0 49 0 32767 32767 100 20 10 The pause after a DTMF tone. dtmfDurationTextLabel DTMF &duration: dtmfDurationSpinBox dtmfPauseMsTextLabel ms dtmfPayloadTypeTextLabel DTMF payload &type: dtmfPayloadTypeSpinBox dtmfPauseTextLabel DTMF &pause: dtmfPauseSpinBox dtmfVolDbmTextLabel dB dtmfDurationSpinBox 1 0 0 0 49 0 32767 32767 500 40 10 Duration of a DTMF tone. layout15 unnamed dtmfTransportTextLabel DTMF t&ransport: dtmfTransportComboBox Auto RFC 2833 Inband Out-of-band (SIP INFO) dtmfTransportComboBox <h2>RFC 2833</h2> <p>Send DTMF tones as RFC 2833 telephone events.</p> <h2>Inband</h2> <p>Send DTMF inband.</p> <h2>Auto</h2> <p>If the far end of your call supports RFC 2833, then a DTMF tone will be send as RFC 2833 telephone event, otherwise it will be sent inband. </p> <h2>Out-of-band (SIP INFO)</h2> <p> Send DTMF out-of-band via a SIP INFO request. </p> spacer22_2 Horizontal Expanding 161 20 spacer23_3 Vertical Expanding 20 120 pageSipProtocol 3 unnamed sipProtocolTitleTextLabel 150 150 150 21 Box SIP protocol 10 sipProtoclTabWidget tab General unnamed spacer24_2 Vertical Expanding 20 16 optionsGroupBox Protocol options unnamed holdVariantTextLabel Call &Hold variant: holdVariantComboBox RFC 2543 RFC 3264 holdVariantComboBox 1 0 0 0 110 0 Indicates if RFC 2543 (set media IP address in SDP to 0.0.0.0) or RFC 3264 (use direction attributes in SDP) is used to put a call on-hold. spacer4 Horizontal Expanding 70 20 missingContactCheckBox Allow m&issing Contact header in 200 OK on REGISTER Alt+I A 200 OK response on a REGISTER request must contain a Contact header. Some registrars however, do not include a Contact header or include a wrong Contact header. This option allows for such a deviation from the specs. maxForwardsCheckBox &Max-Forwards header is mandatory Alt+M According to RFC 3261 the Max-Forwards header is mandatory. But many implementations do not send this header. If you tick this box, Twinkle will reject a SIP request if Max-Forwards is missing. regTimeCheckBox Put &registration expiry time in contact header Alt+R In a REGISTER message the expiry time for registration can be put in the Contact header or in the Expires header. If you tick this box it will be put in the Contact header, otherwise it goes in the Expires header. compactHeadersCheckBox &Use compact header names Alt+U Indicates if compact header names should be used for headers that have a compact form. allowSdpChangeCheckBox Allow SDP change during call setup <p>A SIP UAS may send SDP in a 1XX response for early media, e.g. ringing tone. When the call is answered the SIP UAS should send the same SDP in the 200 OK response according to RFC 3261. Once SDP has been received, SDP in subsequent responses should be discarded.</p> <p>By allowing SDP to change during call setup, Twinkle will not discard SDP in subsequent responses and modify the media stream if the SDP is changed. When the SDP in a response is changed, it must have a new version number in the o= line.</p> useDomainInContactCheckBox Use domain &name to create a unique contact header value Alt+N <p> Twinkle creates a unique contact header value by combining the SIP user name and domain: </p> <p> <tt>&nbsp;user_domain@local_ip</tt> </p> <p> This way 2 user profiles, having the same user name but different domain names, have unique contact addresses and hence can be activated simultaneously. </p> <p> Some proxies do not handle a contact header value like this. You can disable this option to get a contact header value like this: </p> <p> <tt>&nbsp;user@local_ip</tt> </p> <p> This format is what most SIP phones use. </p> multiValuesListCheckBox &Encode Via, Route, Record-Route as list Alt+E The Via, Route and Record-Route headers can be encoded as a list of comma separated values or as multiple occurrences of the same header. redirectionGroupBox Redirection unnamed allowRedirectionCheckBox &Allow redirection Alt+A Indicates if Twinkle should redirect a request if a 3XX response is received. askUserRedirectCheckBox Ask user &permission to redirect Alt+P Indicates if Twinkle should ask the user before redirecting a request when a 3XX response is received. maxRedirectTextLabel Max re&directions: maxRedirectSpinBox maxRedirectSpinBox 1 0 0 0 46 0 5 1 The number of redirect addresses that Twinkle tries at a maximum before it gives up redirecting a request. This prevents a request from getting redirected forever. spacer5 Horizontal Expanding 80 20 sipExtensionsGroupBox SIP extensions unnamed disabled supported required preferred ext100relComboBox 1 0 0 0 120 0 Indicates if the 100rel extension (PRACK) is supported:<br><br> <b>disabled</b>: 100rel extension is disabled <br><br> <b>supported</b>: 100rel is supported (it is added in the supported header of an outgoing INVITE). A far-end can now require a PRACK on a 1xx response. <br><br> <b>required</b>: 100rel is required (it is put in the require header of an outgoing INVITE). If an incoming INVITE indicates that it supports 100rel, then Twinkle will require a PRACK when sending a 1xx response. A call will fail when the far-end does not support 100rel. <br><br> <b>preferred</b>: Similar to required, but if a call fails because the far-end indicates it does not support 100rel (420 response) then the call will be re-attempted without the 100rel requirement. ext100relTextLabel &100 rel (PRACK): ext100relComboBox extReplacesCheckBox Replaces Indicates if the Replaces-extenstion is supported. tab REFER unnamed referGroupBox Call transfer (REFER) unnamed allowReferCheckBox Accept call &transfer request (incoming REFER) Alt+T Indicates if Twinkle should transfer a call if a REFER request is received. askUserReferCheckBox As&k user permission to transfer Alt+K Indicates if Twinkle should ask the user before transferring a call when a REFER request is received. refereeHoldCheckBox Hold call &with referrer while setting up call to transfer target Alt+W Indicates if Twinkle should put the current call on hold when a REFER request to transfer a call is received. referrerHoldCheckBox Ho&ld call with referee before sending REFER Alt+L Indicates if Twinkle should put the current call on hold when you transfer a call. refreshReferSubCheckBox Auto re&fresh subscription to refer event while call transfer is not finished Alt+F While a call is being transferred, the referee sends NOTIFY messages to the referrer about the progress of the transfer. These messages are only sent for a short interval which length is determined by the referee. If you tick this box, the referrer will automatically send a SUBSCRIBE to lengthen this interval if it is about to expire and the transfer has not yet been completed. referAorCheckBox Attended refer to AoR (Address of Record) An attended call transfer should use the contact URI as a refer target. A contact URI may not be globally routable however. Alternatively the AoR (Address of Record) may be used. A disadvantage is that the AoR may route to multiple endpoints in case of forking whereas the contact URI routes to a single endoint. transferConsultInprogCheckBox Allow call transfer while consultation in progress When you perform an attended call transfer, you normally transfer the call after you established a consultation call. If you enable this option you can transfer the call while the consultation call is still in progress. This is a non-standard implementation and may not work with all SIP devices. spacer25 Vertical Expanding 20 200 TabPage Privacy unnamed privacyGroupBox Privacy options unnamed pPreferredIdCheckBox &Send P-Preferred-Identity header when hiding user identity Alt+S Include a P-Preferred-Identity header with your identity in an INVITE request for a call with identity hiding. spacer40 Vertical Expanding 20 331 pageNat 4 unnamed NatTitleTextLabel 150 150 150 21 Box Transport/NAT 10 transportGroupBox SIP transport unnamed Auto UDP TCP sipTransportComboBox Transport mode for SIP. In auto mode, the size of a message determines which transport protocol is used. Messages larger than the UDP threshold are sent via TCP. Smaller messages are sent via UDP. spacer46 Horizontal Expanding 151 20 sipTransportTextLabel T&ransport protocol: sipTransportComboBox udpThresholdTextLabel UDP t&hreshold: udpThresholdSpinBox udpThresholdSpinBox bytes 65535 100 1300 Messages larger than the threshold are sent via TCP. Smaller messages are sent via UDP. spacer47 Horizontal Expanding 81 20 natTraversalButtonGroup_ NAT traversal unnamed natNoneRadioButton &NAT traversal not needed Alt+N Choose this option when there is no NAT device between you and your SIP proxy or when your SIP provider offers hosted NAT traversal. natStaticRadioButton &Use statically configured public IP address inside SIP messages Alt+U Indicates if Twinkle should use the public IP address specified in the next field inside SIP message, i.e. in SIP headers and SDP body instead of the IP address of your network interface.<br><br> When you choose this option you have to create static address mappings in your NAT device as well. You have to map the RTP ports on the public IP address to the same ports on the private IP address of your PC. layout32 unnamed publicIPTextLabel &Public IP address: 21 publicIPLineEdit publicIPLineEdit The public IP address of your NAT. natStunRadioButton Use &STUN (does not work for incoming TCP) Alt+S Choose this option when your SIP provider offers a STUN server for NAT traversal. layout33 unnamed stunServerTextLabel S&TUN server: 21 stunServerLineEdit stunServerLineEdit The hostname, domain name or IP address of the STUN server. persistentTcpCheckBox P&ersistent TCP connection Alt+E Keep the TCP connection established during registration open such that the SIP proxy can reuse this connection to send incoming requests. Application ping packets are sent to test if the connection is still alive. natKeepaliveCheckBox Enable NAT &keep alive Alt+K Send UDP NAT keep alive packets. spacer19 Vertical Expanding 20 80 pageAddressFormat 5 unnamed addressFormatTitleTextLabel 150 150 150 21 Box Address format 10 telNumberGroupBox Telephone numbers unnamed displayTelUserCheckBox Only &display user part of URI for telephone number Alt+D If a URI indicates a telephone number, then only display the user part. E.g. if a call comes in from sip:123456@twinklephone.com then display only "123456" to the user. A URI indicates a telephone number if it contains the "user=phone" parameter or when it has a numerical user part and you ticked the next option. numericalUserIsTelCheckBox &URI with numerical user part is a telephone number Alt+U If you tick this option, then Twinkle considers a SIP address that has a user part that consists of digits, *, #, + and special symbols only as a telephone number. In an outgoing message, Twinkle will add the "user=phone" parameter to such a URI. removeSpecialCheckBox &Remove special symbols from numerical dial strings Alt+R Telephone numbers are often written with special symbols like dashes and brackets to make them readable to humans. When you dial such a number the special symbols must not be dialed. To allow you to simply copy/paste such a number into Twinkle, Twinkle can remove these symbols when you hit the dial button. useTelUriCheckBox Use tel-URI for telephone &number Alt+N Expand a dialed telephone number to a tel-URI instead of a sip-URI. specialTextLabel &Special symbols: specialLineEdit specialLineEdit The special symbols that may be part of a telephone number for nice formatting, but must be removed when dialing. conversionGroupBox Number conversion unnamed layout29 unnamed Match expression true true Replace true true conversionListView true AllColumns <p> Often the format of the telphone numbers you need to dial is different from the format of the telephone numbers stored in your address book, e.g. your numbers start with a +-symbol followed by a country code, but your provider expects '00' instead of the '+', or you are at the office and all your numbers need to be prefixed with a '9' to access an outside line. Here you can specify number format conversion using Perl style regular expressions and format strings. </p> <p> For each number you dial, Twinkle will try to find a match in the list of match expressions. For the first match it finds, the number will be replaced with the format string. If no match is found, the number stays unchanged. </p> <p> The number conversion rules are also applied to incoming calls, so the numbers are displayed in the format you want. </p> <h3>Example 1</h3> <p> Assume your country code is 31 and you have stored all numbers in your address book in full international number format, e.g. +318712345678. For dialling numbers in your own country you want to strip of the '+31' and replace it by a '0'. For dialling numbers abroad you just want to replace the '+' by '00'. </p> <p> The following rules will do the trick: </p> <blockquote> <tt> Match expression = \+31([0-9]*) , Replace = 0$1<br> Match expression = \+([0-9]*) , Replace = 00$1</br> </tt> </blockquote> <h3>Example 2</h3> <p> You are at work and all telephone numbers starting with a 0 should be prefixed with a 9 for an outside line. </p> <blockquote> <tt> Match expression = 0[0-9]* , Replace = 9$&<br> </tt> </blockquote> layout15_2 unnamed spacer19_2_2 Vertical Expanding 20 21 upConversionPushButton 1uparrow.png Move the selected number conversion rule upwards in the list. downConversionPushButton 1downarrow.png Move the selected number conversion rule downwards in the list. spacer20_2_2 Vertical Expanding 20 31 layout30 unnamed addConversionPushButton &Add Alt+A Add a number conversion rule. removePushButton Re&move Alt+M Remove the selected number conversion rule. editConversionPushButton &Edit Alt+E Edit the selected number conversion rule. spacer38_2 Horizontal Expanding 291 20 layout24 unnamed testConversionLineEdit Type a telephone number here an press the Test button to see how it is converted by the list of number conversion rules. testConversionPushButton &Test Alt+T Test how a number is converted by the number conversion rules. spacer20 Vertical Expanding 20 20 pageTimers 6 unnamed timersTitleTextLabel 150 150 150 21 Box Timers 10 layout7 unnamed layout6 unnamed secNoanswerTextLabel seconds tmrNatKeepaliveSpinBox 0 0 0 0 55 0 55 32767 900 10 10 If you have enabled STUN or NAT keep alive, then Twinkle will send keep alive packets at this interval rate to keep the address bindings in your NAT device alive. tmrNoanswerSpinBox 0 0 0 0 55 0 55 32767 600 10 When an incoming call is received, this timer is started. If the user answers the call, the timer is stopped. If the timer expires before the user answers the call, then Twinkle will reject the call with a "480 User Not Responding". tmrNatKeepaliveTextLabel NAT &keep alive: tmrNatKeepaliveSpinBox tmrNoanswerTextLabel &No answer: tmrNoanswerSpinBox spacer23 Horizontal Expanding 270 20 spacer22 Vertical Expanding 20 450 pageRingTones 7 unnamed ringtonesTitleTextLabel 150 150 150 21 Box Ring tones 10 layout18 unnamed openRingbackToolButton TabFocus fileopen.png Select ring back tone file. openRingtoneToolButton TabFocus fileopen.png Select ring tone file. ringbackTextLabel Ring &back tone: ringbackLineEdit ringbackLineEdit <p> Specify the file name of a .wav file that you want to be played as ring back tone for this user. </p> <p> This ring back tone overrides the ring back tone settings in the system settings. </p> ringtoneLineEdit <p> Specify the file name of a .wav file that you want to be played as ring tone for this user. </p> <p> This ring tone overrides the ring tone settings in the system settings. </p> ringtoneTextLabel &Ring tone: ringtoneLineEdit spacer30 Vertical Expanding 20 391 pageScripts 8 unnamed scriptsTitleTextLabel 150 150 150 21 Box Scripts 10 layout19 unnamed localReleaseLineEdit <p> This script is called when you release a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=local_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. openInCallFailedToolButton TabFocus fileopen.png Select script file. openIncomingCallScriptToolButton TabFocus fileopen.png Select script file. openOutCallAnsweredToolButton TabFocus fileopen.png Select script file. inCallFailedLineEdit <p> This script is called when an incoming call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. openInCallAnsweredToolButton TabFocus fileopen.png Select script file. remoteReleaseLineEdit <p> This script is called when the remote party releases a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP BYE request are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=remote_release</b>. <b>SIPREQUEST_METHOD=BYE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the BYE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. openOutCallToolButton TabFocus fileopen.png Select script file. incomingCallScriptLineEdit <p> You can customize the way Twinkle handles incoming calls. Twinkle can call a script when a call comes in. Based on the ouput of the script Twinkle accepts, rejects or redirects the call. When accepting the call, the ring tone can be customized by the script as well. The script can be any executable program. </p> <p> <b>Note:</b> Twinkle pauses while your script runs. It is recommended that your script does not take more than 200 ms. When you need more time, you can send the parameters followed by <b>end</b> and keep on running. Twinkle will continue when it receives the <b>end</b> parameter. </p> <p> With your script you can customize call handling by outputing one or more of the following parameters to stdout. Each parameter should be on a separate line. </p> <p> <blockquote> <tt> action=[ continue | reject | dnd | redirect | autoanswer ]<br> reason=&lt;string&gt;<br> contact=&lt;address to redirect to&gt;<br> caller_name=&lt;name of caller to display&gt;<br> ringtone=&lt;file name of .wav file&gt;<br> display_msg=&lt;message to show on display&gt;<br> end<br> </tt> </blockquote> </p> <h2>Parameters</h2> <h3>action</h3> <p> <b>continue</b> - continue call handling as usual<br> <b>reject</b> - reject call<br> <b>dnd</b> - deny call with do not disturb indication<br> <b>redirect</b> - redirect call to address specified by <b>contact</b><br> <b>autoanswer</b> - automatically answer a call<br> </p> <p> When the script does not write an action to stdout, then the default action is continue. </p> <p> <b>reason: </b> With the reason parameter you can set the reason string for reject or dnd. This might be shown to the far-end user. </p> <p> <b>caller_name: </b> This parameter will override the display name of the caller. </p> <p> <b>ringtone: </b> The ringtone parameter specifies the .wav file that will be played as ring tone when action is continue. </p> <h2>Environment variables</h2> <p> The values of all SIP headers in the incoming INVITE message are passed in environment variables to your script. The variable names are formatted as <b>SIP_&lt;HEADER_NAME&gt;</b> E.g. SIP_FROM contains the value of the from header. </p> <p> TWINKLE_TRIGGER=in_call. SIPREQUEST_METHOD=INVITE. The request-URI of the INVITE will be passed in <b>SIPREQUEST_URI</b>. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. outCallAnsweredLineEdit <p> This script is called when the remote party answers your call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. inCallAnsweredLineEdit <p> This script is called when you answer an incoming call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing 200 OK are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=in_call_answered</b>. <b>SIPSTATUS_CODE=200</b>. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. localReleaseTextLabel Call released locall&y: inCallFailedLineEdit openOutCallFailedToolButton TabFocus fileopen.png Select script file. outCallFailedLineEdit <p> This script is called when an outgoing call fails. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the incoming SIP failure response are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call_failed</b>. <b>SIPSTATUS_CODE</b> contains the status code of the failure response. <b>SIPSTATUS_REASON</b> contains the reason phrase. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. outCallLineEdit <p> This script is called when you make a call. </p> <h2>Environment variables</h2> <p> The values of all SIP headers of the outgoing INVITE are passed in environment variables to your script. </p> <p> <b>TWINKLE_TRIGGER=out_call</b>. <b>SIPREQUEST_METHOD=INVITE</b>. <b>SIPREQUEST_URI</b> contains the request-URI of the INVITE. The name of the user profile will be passed in <b>TWINKLE_USER_PROFILE</b>. outCallAnsweredTextLabel Outgoing call a&nswered: inCallAnsweredLineEdit inCallFailedTextLabel Incoming call &failed: inCallFailedLineEdit incomingCallScriptTextLabel &Incoming call: incomingCallScriptLineEdit openLocalReleaseToolButton TabFocus fileopen.png Select script file. remoteReleaseTextLabel Call released &remotely: inCallFailedLineEdit inCallAnsweredTextLabel Incoming call &answered: inCallAnsweredLineEdit openRemoteReleaseToolButton TabFocus fileopen.png Select script file. outCallTextLabel O&utgoing call: incomingCallScriptLineEdit outCallFailedTextLabel Out&going call failed: inCallFailedLineEdit spacer29 Vertical Expanding 20 190 pageSecurity 9 unnamed securityTitleTextLabel 150 150 150 21 Box Security 10 zrtpEnabledCheckBox &Enable ZRTP/SRTP encryption Alt+E When ZRTP/SRTP is enabled, then Twinkle will try to encrypt the audio of each call you originate or receive. Encryption will only succeed if the remote party has ZRTP/SRTP support enabled. If the remote party does not support ZRTP/SRTP, then the audio channel will stay unecrypted. zrtpSettingsGroupBox ZRTP settings unnamed zrtpSendIfSupportedCheckBox O&nly encrypt audio if remote party indicated ZRTP support in SDP Alt+N A SIP endpoint supporting ZRTP may indicate ZRTP support during call setup in its signalling. Enabling this option will cause Twinkle only to encrypt calls when the remote party indicates ZRTP support. zrtpSdpCheckBox &Indicate ZRTP support in SDP Alt+I Twinkle will indicate ZRTP support during call setup in its signalling. zrtpGoClearWarningCheckBox &Popup warning when remote party disables encryption during call Alt+P A remote party of an encrypted call may send a ZRTP go-clear command to stop encryption. When Twinkle receives this command it will popup a warning if this option is enabled. spacer33 Vertical Expanding 20 241 pageVoiceMail 10 unnamed voiceMailTextLabel 150 150 150 21 Box Voice mail 10 layout39 unnamed vmAddressTextLabel &Voice mail address: vmAddressLineEdit vmAddressLineEdit The SIP address or telephone number to access your voice mail. layout38 unnamed Unsollicited Sollicited mwiTypeComboBox <H2>Message waiting indication type</H2> <p> If your provider offers the message waiting indication service, then Twinkle can show you when new voice mail messages are waiting. Ask your provider which type of message waiting indication is offered. </p> <H3>Unsollicited</H3> <p> Asterisk provides unsollicited message waiting indication. </p> <H3>Sollicited</H3> <p> Sollicited message waiting indication as specified by RFC 3842. </p> spacer39 Horizontal Expanding 221 20 mwiTypeTextLabel &MWI type: mwiTypeComboBox mwiSollicitedGroupBox Sollicited MWI unnamed layout36 unnamed spacer35 Horizontal Expanding 120 20 mwiDurationTextLabel Subscription &duration: mwiDurationSpinBox mwiUserTextLabel Mailbox &user name: mwiUserLineEdit mwiServerLineEdit The hostname, domain name or IP address of your voice mailbox server. layout35 unnamed mwiDurationSpinBox 90 0 999999 100 For sollicited MWI, an endpoint subscribes to the message status for a limited duration. Just before the duration expires, the endpoint should refresh the subscription. mwiSecondsTextLabel seconds spacer36 Horizontal Expanding 190 20 mwiUserLineEdit Your user name for accessing your voice mailbox. mwiServerTextLabel Mailbox &server: mwiServerLineEdit mwiViaProxyCheckBox Via outbound &proxy Alt+P Check this option if Twinkle should send SIP messages to the mailbox server via the outbound proxy. spacer38_3 Vertical Expanding 20 211 pageIM 11 unnamed imTextLabel 150 150 150 21 Box Instant message 10 layout74 unnamed imMaxSessionsTextLabel &Maximum number of sessions: imMaxSessionsSpinBox imMaxSessionsSpinBox 65535 When you have this number of instant message sessions open, new incoming message sessions will be rejected. spacer42 Horizontal Expanding 201 20 isComposingCheckBox &Send composing indications when typing a message. Alt+S Twinkle sends a composing indication when you type a message. This way the recipient can see that you are typing. spacer40_3 Vertical Expanding 20 350 pagePresence 12 unnamed presTextLabel 150 150 150 21 Box Presence 10 presYourGroupBox Your presence unnamed presPublishCheckBox &Publish availability at startup Alt+P Publish your availability at startup. layout75 unnamed presPublishTimerTextLabel Publication &refresh interval (sec): presPublishTimeSpinBox presPublishTimeSpinBox 999999 100 Refresh rate of presence publications. spacer43 Horizontal Expanding 231 20 groupBox25 Buddy presence unnamed layout76 unnamed presSubscribeTimerTextLabel &Subscription refresh interval (sec): presSubscribeTimeSpinBox presSubscribeTimeSpinBox 999999 100 Refresh rate of presence subscriptions. spacer44 Horizontal Expanding 191 20 spacer45 Vertical Expanding 20 281 categoryListBox highlighted(int) UserProfileForm showCategory(int) cancelPushButton clicked() UserProfileForm reject() okPushButton clicked() UserProfileForm validate() useProxyCheckBox toggled(bool) proxyTextLabel setEnabled(bool) useProxyCheckBox toggled(bool) proxyLineEdit setEnabled(bool) useProxyCheckBox toggled(bool) allRequestsCheckBox setEnabled(bool) allowRedirectionCheckBox toggled(bool) askUserRedirectCheckBox setEnabled(bool) allowRedirectionCheckBox toggled(bool) maxRedirectTextLabel setEnabled(bool) allowRedirectionCheckBox toggled(bool) maxRedirectSpinBox setEnabled(bool) useProxyCheckBox toggled(bool) proxyNonResolvableCheckBox setEnabled(bool) natStaticRadioButton toggled(bool) publicIPTextLabel setEnabled(bool) natStaticRadioButton toggled(bool) publicIPLineEdit setEnabled(bool) natStunRadioButton toggled(bool) stunServerTextLabel setEnabled(bool) natStunRadioButton toggled(bool) stunServerLineEdit setEnabled(bool) allowReferCheckBox toggled(bool) askUserReferCheckBox setEnabled(bool) allowReferCheckBox toggled(bool) refereeHoldCheckBox setEnabled(bool) profileComboBox activated(const QString&) UserProfileForm changeProfile(const QString&) openRingtoneToolButton clicked() UserProfileForm chooseRingtone() openRingbackToolButton clicked() UserProfileForm chooseRingback() openIncomingCallScriptToolButton clicked() UserProfileForm chooseIncomingCallScript() addCodecPushButton clicked() UserProfileForm addCodec() rmvCodecPushButton clicked() UserProfileForm removeCodec() upCodecPushButton clicked() UserProfileForm upCodec() downCodecPushButton clicked() UserProfileForm downCodec() availCodecListBox doubleClicked(QListBoxItem*) UserProfileForm addCodec() activeCodecListBox doubleClicked(QListBoxItem*) UserProfileForm removeCodec() openInCallAnsweredToolButton clicked() UserProfileForm chooseInCallAnsweredScript() openInCallFailedToolButton clicked() UserProfileForm chooseInCallFailedScript() openLocalReleaseToolButton clicked() UserProfileForm chooseLocalReleaseScript() openOutCallAnsweredToolButton clicked() UserProfileForm chooseOutCallAnsweredScript() openOutCallFailedToolButton clicked() UserProfileForm chooseOutCallFailedScript() openOutCallToolButton clicked() UserProfileForm chooseOutgoingCallScript() openRemoteReleaseToolButton clicked() UserProfileForm chooseRemoteReleaseScript() upConversionPushButton clicked() UserProfileForm upConversion() downConversionPushButton clicked() UserProfileForm downConversion() addConversionPushButton clicked() UserProfileForm addConversion() editConversionPushButton clicked() UserProfileForm editConversion() removePushButton clicked() UserProfileForm removeConversion() testConversionPushButton clicked() UserProfileForm testConversion() zrtpEnabledCheckBox toggled(bool) zrtpSettingsGroupBox setEnabled(bool) mwiTypeComboBox activated(int) UserProfileForm changeMWIType(int) regAddQvalueCheckBox toggled(bool) regQvalueLineEdit setEnabled(bool) sipTransportComboBox activated(int) UserProfileForm changeSipTransportProtocol(int) spxDspAgcCheckBox toggled(bool) spxDspAgcLevelTextLabel setEnabled(bool) spxDspAgcCheckBox toggled(bool) spxDspAgcLevelSpinBox setEnabled(bool) natStunRadioButton toggled(bool) natKeepaliveCheckBox setDisabled(bool) displayLineEdit usernameLineEdit domainLineEdit organizationLineEdit authRealmLineEdit authNameLineEdit authPasswordLineEdit authAkaOpLineEdit authAkaAmfLineEdit registrarLineEdit expirySpinBox regAtStartupCheckBox regAddQvalueCheckBox regQvalueLineEdit useProxyCheckBox proxyLineEdit allRequestsCheckBox proxyNonResolvableCheckBox vmAddressLineEdit mwiTypeComboBox mwiUserLineEdit mwiServerLineEdit mwiViaProxyCheckBox mwiDurationSpinBox imMaxSessionsSpinBox isComposingCheckBox presPublishCheckBox presPublishTimeSpinBox presSubscribeTimeSpinBox rtpAudioTabWidget availCodecListBox addCodecPushButton rmvCodecPushButton activeCodecListBox upCodecPushButton downCodecPushButton ptimeSpinBox inFarEndCodecPrefCheckBox outFarEndCodecPrefCheckBox spxDspAgcCheckBox spxDspAgcLevelSpinBox spxDspVadCheckBox spxDspNrdCheckBox spxDspAecCheckBox ilbcPayloadSpinBox ilbcPayloadSizeComboBox spxVbrCheckBox spxDtxCheckBox spxPenhCheckBox spxQualitySpinBox spxComplexitySpinBox spxNbPayloadSpinBox spxWbPayloadSpinBox spxUwbPayloadSpinBox g72616PayloadSpinBox g72624PayloadSpinBox g72632PayloadSpinBox g72640PayloadSpinBox g726PackComboBox dtmfTransportComboBox dtmfPayloadTypeSpinBox dtmfDurationSpinBox dtmfPauseSpinBox dtmfVolumeSpinBox sipProtoclTabWidget holdVariantComboBox maxForwardsCheckBox missingContactCheckBox regTimeCheckBox compactHeadersCheckBox multiValuesListCheckBox useDomainInContactCheckBox allowSdpChangeCheckBox allowRedirectionCheckBox askUserRedirectCheckBox maxRedirectSpinBox ext100relComboBox extReplacesCheckBox allowReferCheckBox askUserReferCheckBox refereeHoldCheckBox referrerHoldCheckBox refreshReferSubCheckBox referAorCheckBox pPreferredIdCheckBox sipTransportComboBox udpThresholdSpinBox natNoneRadioButton natStaticRadioButton publicIPLineEdit natStunRadioButton stunServerLineEdit persistentTcpCheckBox displayTelUserCheckBox numericalUserIsTelCheckBox removeSpecialCheckBox specialLineEdit useTelUriCheckBox conversionListView upConversionPushButton downConversionPushButton addConversionPushButton removePushButton editConversionPushButton testConversionLineEdit testConversionPushButton tmrNoanswerSpinBox tmrNatKeepaliveSpinBox ringtoneLineEdit ringbackLineEdit openRingtoneToolButton openRingbackToolButton incomingCallScriptLineEdit openIncomingCallScriptToolButton inCallAnsweredLineEdit openInCallAnsweredToolButton inCallFailedLineEdit openInCallFailedToolButton outCallLineEdit openOutCallToolButton outCallAnsweredLineEdit openOutCallAnsweredToolButton outCallFailedLineEdit openOutCallFailedToolButton localReleaseLineEdit openLocalReleaseToolButton remoteReleaseLineEdit openRemoteReleaseToolButton zrtpEnabledCheckBox zrtpSendIfSupportedCheckBox zrtpSdpCheckBox zrtpGoClearWarningCheckBox okPushButton cancelPushButton profileComboBox categoryListBox qlistbox.h qlineedit.h qlabel.h qcombobox.h qspinbox.h qregexp.h sdp/sdp.h qvalidator.h protocol.h qmessagebox.h gui.h qfiledialog.h qfileinfo.h qstringlist.h twinkle_config.h qlistview.h numberconversionform.h util.h user.h qvaluelist.h map list userprofileform.ui.h map<t_user *, int> map_last_cat; t_user *current_profile; int current_profile_idx; list<t_user *> profile_list; stunServerChanged(t_user *) authCredentialsChanged(t_user *, const string &) sipUserChanged(t_user *) success() mwiChangeUnsubscribe(t_user *) mwiChangeSubscribe(t_user *) showCategory( int index ) populate() initProfileList( list<t_user *> profiles, QString show_profile_name ) show( list<t_user *> profiles, QString show_profile ) validate() changeProfile( const QString & profileName ) chooseFile( QLineEdit * qle, const QString & filter, const QString & caption ) chooseRingtone() chooseRingback() chooseIncomingCallScript() chooseInCallAnsweredScript() chooseInCallFailedScript() chooseOutgoingCallScript() chooseOutCallAnsweredScript() chooseOutCallFailedScript() chooseLocalReleaseScript() chooseRemoteReleaseScript() addCodec() removeCodec() upCodec() downCodec() upConversion() downConversion() addConversion() editConversion() removeConversion() testConversion() changeMWIType( int idxMWIType ) changeSipTransportProtocol( int idx ) init() label2codec( const QString & label ) codec2label( t_audio_codec & codec ) ext_support2indexComboItem( t_ext_support ext ) indexComboItem2ext_support( int index ) exec( list<t_user *> profiles, QString show_profile ) check_dynamic_payload( QSpinBox * spb, QValueList<int> & checked_list ) get_number_conversions() validateValues() twinkle-1.4.2/src/gui/addresscardform.ui.h0000644000175000001440000000544711127714044015426 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ int AddressCardForm::exec(t_address_card &card) { firstNameLineEdit->setText(card.name_first.c_str()); infixNameLineEdit->setText(card.name_infix.c_str()); lastNameLineEdit->setText(card.name_last.c_str()); phoneLineEdit->setText(card.sip_address.c_str()); remarkLineEdit->setText(card.remark.c_str()); int retval = QDialog::exec(); if (retval == QDialog::Accepted) { card.name_first = firstNameLineEdit->text().stripWhiteSpace().ascii(); card.name_infix = infixNameLineEdit->text().stripWhiteSpace().ascii(); card.name_last = lastNameLineEdit->text().stripWhiteSpace().ascii(); card.sip_address = phoneLineEdit->text().stripWhiteSpace().ascii(); card.remark = remarkLineEdit->text().stripWhiteSpace().ascii(); } return retval; } void AddressCardForm::validate() { QString firstName = firstNameLineEdit->text().stripWhiteSpace(); QString infixName = infixNameLineEdit->text().stripWhiteSpace(); QString lastName = lastNameLineEdit->text().stripWhiteSpace(); QString phone = phoneLineEdit->text().stripWhiteSpace(); if (firstName.isEmpty() && infixName.isEmpty() && lastName.isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a name.").ascii(), MSG_CRITICAL); firstNameLineEdit->setFocus(); return; } if (phone.isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("You must fill in a phone number or SIP address.").ascii(), MSG_CRITICAL); phoneLineEdit->setFocus(); return; } accept(); } twinkle-1.4.2/src/gui/srvredirectform.ui.h0000644000175000001440000002266711127714044015506 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void SrvRedirectForm::init() { cfAlwaysGroupBox->setEnabled(false); cfBusyGroupBox->setEnabled(false); cfNoanswerGroupBox->setEnabled(false); // Keeps track of which address book tool button is clicked. nrAddressBook = 0; getAddressForm = 0; // Set toolbutton icons for disabled options. QIconSet i; i = addrAlways1ToolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource("kontact_contacts-disabled.png"), QIconSet::Automatic, QIconSet::Disabled); addrAlways1ToolButton->setIconSet(i); addrAlways2ToolButton->setIconSet(i); addrAlways3ToolButton->setIconSet(i); addrBusy1ToolButton->setIconSet(i); addrBusy2ToolButton->setIconSet(i); addrBusy3ToolButton->setIconSet(i); addrNoanswer1ToolButton->setIconSet(i); addrNoanswer2ToolButton->setIconSet(i); addrNoanswer3ToolButton->setIconSet(i); } void SrvRedirectForm::destroy() { if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } } void SrvRedirectForm::show() { current_user_idx = -1; ((t_gui *)ui)->fill_user_combo(userComboBox); userComboBox->setEnabled(userComboBox->count() > 1); current_user = phone->ref_users().front(); current_user_idx = 0; populate(); QDialog::show(); } void SrvRedirectForm::populate() { t_service *srv = phone->ref_service(current_user); bool cf_active; list dest_list; int field; // Call forwarding unconditional cf_active = srv->get_cf_active(CF_ALWAYS, dest_list); cfAlwaysDst1LineEdit->clear(); cfAlwaysDst2LineEdit->clear(); cfAlwaysDst3LineEdit->clear(); cfAlwaysCheckBox->setChecked(cf_active); if (cf_active) { field = 1; for (list::iterator i = dest_list.begin(); i != dest_list.end(); i++) { if (field == 1) cfAlwaysDst1LineEdit->setText(i->encode().c_str()); if (field == 2) cfAlwaysDst2LineEdit->setText(i->encode().c_str()); if (field == 3) cfAlwaysDst3LineEdit->setText(i->encode().c_str()); field++; } } // Call forwarding busy cf_active = srv->get_cf_active(CF_BUSY, dest_list); cfBusyDst1LineEdit->clear(); cfBusyDst2LineEdit->clear(); cfBusyDst3LineEdit->clear(); cfBusyCheckBox->setChecked(cf_active); if (cf_active) { field = 1; for (list::iterator i = dest_list.begin(); i != dest_list.end(); i++) { if (field == 1) cfBusyDst1LineEdit->setText(i->encode().c_str()); if (field == 2) cfBusyDst2LineEdit->setText(i->encode().c_str()); if (field == 3) cfBusyDst3LineEdit->setText(i->encode().c_str()); field++; } } // Call forwarding no answer cf_active = srv->get_cf_active(CF_NOANSWER, dest_list); cfNoanswerDst1LineEdit->clear(); cfNoanswerDst2LineEdit->clear(); cfNoanswerDst3LineEdit->clear(); cfNoanswerCheckBox->setChecked(cf_active); if (cf_active) { field = 1; for (list::iterator i = dest_list.begin(); i != dest_list.end(); i++) { if (field == 1) cfNoanswerDst1LineEdit->setText(i->encode().c_str()); if (field == 2) cfNoanswerDst2LineEdit->setText(i->encode().c_str()); if (field == 3) cfNoanswerDst3LineEdit->setText(i->encode().c_str()); field++; } } } void SrvRedirectForm::validate() { if (validateValues()) { accept(); } else { ((t_gui *)ui)->cb_show_msg(this, tr("You have entered an invalid destination.").ascii(), MSG_WARNING); } } bool SrvRedirectForm::validateValues() { list cfDestAlways, cfDestBusy, cfDestNoanswer; bool valid = false; // Redirect unconditional valid = validate(cfAlwaysCheckBox->isChecked(), cfAlwaysDst1LineEdit, cfAlwaysDst2LineEdit, cfAlwaysDst3LineEdit, cfDestAlways); if (!valid) { cfTabWidget->setCurrentPage(0); return false; } // Redirect busy valid = validate(cfBusyCheckBox->isChecked(), cfBusyDst1LineEdit, cfBusyDst2LineEdit, cfBusyDst3LineEdit, cfDestBusy); if (!valid) { cfTabWidget->setCurrentPage(1); return false; } // Redirect no answer valid = validate(cfNoanswerCheckBox->isChecked(), cfNoanswerDst1LineEdit, cfNoanswerDst2LineEdit, cfNoanswerDst3LineEdit, cfDestNoanswer); if (!valid) { cfTabWidget->setCurrentPage(2); return false; } emit destinations(current_user, cfDestAlways, cfDestBusy, cfDestNoanswer); return true; } // Validate 3 destinations if cf_active is true. // Returns true when all destinations are valid (first must be set, others may be empty) // dest_list containst the encoded destinations when valid. // If cf_active is false then the 3 destinations will be cleared. bool SrvRedirectForm::validate(bool cf_active, QLineEdit *dst1, QLineEdit *dst2, QLineEdit *dst3, list &dest_list) { t_display_url destination; dest_list.clear(); if (!cf_active) { dst1->clear(); dst2->clear(); dst3->clear(); return true; } // 1st choice destination ui->expand_destination(current_user, dst1->text().stripWhiteSpace().ascii(), destination); if (destination.is_valid()) { dest_list.push_back(destination); } else { dst1->selectAll(); return false; } // 2nd choice destination if (!dst2->text().isEmpty()) { ui->expand_destination(current_user, dst2->text().stripWhiteSpace().ascii(), destination); if (destination.is_valid()) { dest_list.push_back(destination); } else { dst2->selectAll(); return false; } } // 3rd choice destination if (!dst3->text().isEmpty()) { ui->expand_destination(current_user, dst3->text().stripWhiteSpace().ascii(), destination); if (destination.is_valid()) { dest_list.push_back(destination); } else { dst3->selectAll(); return false; } } return true; } void SrvRedirectForm::toggleAlways(bool on) { if (on) { cfAlwaysGroupBox->setEnabled(true); } else { cfAlwaysGroupBox->setEnabled(false); } } void SrvRedirectForm::toggleBusy(bool on) { if (on) { cfBusyGroupBox->setEnabled(true); } else { cfBusyGroupBox->setEnabled(false); } } void SrvRedirectForm::toggleNoanswer(bool on) { if (on) { cfNoanswerGroupBox->setEnabled(true); } else { cfNoanswerGroupBox->setEnabled(false); } } void SrvRedirectForm::changedUser(const QString &user_profile) { if (current_user_idx == -1) { // Initializing combo box return; } t_user *new_user = phone->ref_user_profile(user_profile.ascii()); if (!new_user) { userComboBox->setCurrentItem(current_user_idx); return; } if (!validateValues()) { userComboBox->setCurrentItem(current_user_idx); ((t_gui *)ui)->cb_show_msg(this, tr("You have entered an invalid destination.").ascii(), MSG_WARNING); return; } // Change current user current_user_idx = userComboBox->currentItem(); current_user = new_user; populate(); } void SrvRedirectForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); getAddressForm->show(); } void SrvRedirectForm::showAddressBook1() { nrAddressBook = 1; showAddressBook(); } void SrvRedirectForm::showAddressBook2() { nrAddressBook = 2; showAddressBook(); } void SrvRedirectForm::showAddressBook3() { nrAddressBook = 3; showAddressBook(); } void SrvRedirectForm::showAddressBook4() { nrAddressBook = 4; showAddressBook(); } void SrvRedirectForm::showAddressBook5() { nrAddressBook = 5; showAddressBook(); } void SrvRedirectForm::showAddressBook6() { nrAddressBook = 6; showAddressBook(); } void SrvRedirectForm::showAddressBook7() { nrAddressBook = 7; showAddressBook(); } void SrvRedirectForm::showAddressBook8() { nrAddressBook = 8; showAddressBook(); } void SrvRedirectForm::showAddressBook9() { nrAddressBook = 9; showAddressBook(); } void SrvRedirectForm::selectedAddress(const QString &address) { switch(nrAddressBook) { case 1: cfAlwaysDst1LineEdit->setText(address); break; case 2: cfAlwaysDst2LineEdit->setText(address); break; case 3: cfAlwaysDst3LineEdit->setText(address); break; case 4: cfBusyDst1LineEdit->setText(address); break; case 5: cfBusyDst2LineEdit->setText(address); break; case 6: cfBusyDst3LineEdit->setText(address); break; case 7: cfNoanswerDst1LineEdit->setText(address); break; case 8: cfNoanswerDst2LineEdit->setText(address); break; case 9: cfNoanswerDst3LineEdit->setText(address); break; } } twinkle-1.4.2/src/gui/getprofilenameform.ui.h0000644000175000001440000000500411146625756016151 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void GetProfileNameForm::init() { // Letters, digits, underscore, minus QRegExp rxFilenameChars("[\\w\\-][\\w\\-@\\.]*"); // Set validators // USER profileLineEdit->setValidator(new QRegExpValidator(rxFilenameChars, this)); } void GetProfileNameForm::validate() { if (profileLineEdit->text().isEmpty()) return; // Find the .twinkle directory in HOME QDir d = QDir::home(); if (!d.cd(USER_DIR)) { QMessageBox::critical(this, PRODUCT_NAME, tr("Cannot find .twinkle directory in your home directory.")); reject(); } QString filename = profileLineEdit->text(); filename.append(USER_FILE_EXT); QString fullname = d.filePath(filename); if (QFile::exists(fullname)) { QMessageBox::warning(this, PRODUCT_NAME, tr("Profile already exists.")); return; } accept(); } QString GetProfileNameForm:: getProfileName() { return profileLineEdit->text(); } // Execute a dialog to get a name for a new profile int GetProfileNameForm::execNewName() { profileTextLabel->setText(tr("Enter a name for your profile:")); return exec(); } // Execute this dialog to get a new name for an existing profile int GetProfileNameForm::execRename(const QString &oldName) { QString s = tr("Rename profile '%1' to:").arg(oldName); profileTextLabel->setText(s); return exec(); } twinkle-1.4.2/src/gui/twinkle.pro0000644000175000001440000001311211151323277013662 00000000000000TEMPLATE = app LANGUAGE = C++ CONFIG += qt warn_on release thread LIBS += ../libtwinkle.a ../parser/libsipparser.a ../sdp/libsdpparser.a ../sockets/libsocket.a ../threads/libthread.a ../audio/libaudio.a ../audits/libaudits.a ../stun/libstun.a ../mwi/libmwi.a ../im/libim.a ../patterns/libpatterns.a ../presence/libpresence.a ../utils/libutils.a -lsndfile -lmagic -lncurses -lreadline DEFINES += QT_NO_STL INCLUDEPATH += .. HEADERS += gui.h \ historylistview.h \ freedesksystray.h \ twinklesystray.h \ address_finder.h \ qt_translator.h \ core_strings.h \ addresslistviewitem.h \ yesnodialog.h \ command_args.h \ messageformview.h \ buddylistview.h \ textbrowsernoautolink.h \ twinkleapplication.h SOURCES += main.cpp \ gui.cpp \ historylistview.cpp \ freedesksystray.cpp \ twinklesystray.cpp \ address_finder.cpp \ addresslistviewitem.cpp \ yesnodialog.cpp \ messageformview.cpp \ buddylistview.cpp \ twinkleapplication.cpp FORMS = mphoneform.ui \ inviteform.ui \ deregisterform.ui \ redirectform.ui \ termcapform.ui \ dtmfform.ui \ selectnicform.ui \ srvredirectform.ui \ authenticationform.ui \ userprofileform.ui \ selectprofileform.ui \ getprofilenameform.ui \ transferform.ui \ syssettingsform.ui \ logviewform.ui \ wizardform.ui \ getaddressform.ui \ historyform.ui \ selectuserform.ui \ numberconversionform.ui \ addresscardform.ui \ messageform.ui \ buddyform.ui \ sendfileform.ui \ diamondcardprofileform.ui IMAGES = images/filenew \ images/filesave \ images/print \ images/undo \ images/redo \ images/editcut \ images/editcopy \ images/editpaste \ images/searchfind \ images/invite.png \ images/answer.png \ images/bye.png \ images/reject.png \ images/redirect.png \ images/hold.png \ images/dtmf.png \ images/bye-disabled.png \ images/redial.png \ images/redial-disabled.png \ images/invite-disabled.png \ images/answer-disabled.png \ images/reject-disabled.png \ images/redirect-disabled.png \ images/hold-disabled.png \ images/dtmf-disabled.png \ images/penguin.png \ images/package_network.png \ images/kmix.png \ images/package_system.png \ images/yast_babelfish.png \ images/clock.png \ images/yast_PhoneTTOffhook.png \ images/penguin_big.png \ images/password.png \ images/kcmpci.png \ images/penguin-small.png \ images/conf.png \ images/conf-disabled.png \ images/mute.png \ images/mute-disabled.png \ images/twinkle16.png \ images/twinkle48.png \ images/twinkle32.png \ images/transfer-disabled.png \ images/transfer.png \ images/log.png \ images/dtmf-2.png \ images/dtmf-3.png \ images/dtmf-5.png \ images/dtmf-6.png \ images/dtmf-7.png \ images/dtmf-8.png \ images/dtmf-9.png \ images/dtmf-4.png \ images/dtmf-1.png \ images/dtmf-0.png \ images/dtmf-star.png \ images/dtmf-pound.png \ images/dtmf-a.png \ images/dtmf-b.png \ images/dtmf-c.png \ images/dtmf-d.png \ images/twinkle24.png \ images/exit.png \ images/kontact_contacts.png \ images/ok.png \ images/cancel.png \ images/1rightarrow.png \ images/1leftarrow-yellow.png \ images/editdelete.png \ images/kcmpci16.png \ images/kontact_contacts-disabled.png \ images/sys_auto_ans.png \ images/sys_auto_ans_dis.png \ images/sys_busy_estab.png \ images/sys_busy_estab_dis.png \ images/sys_busy_trans.png \ images/sys_busy_trans_dis.png \ images/sys_dnd.png \ images/sys_dnd_dis.png \ images/sys_idle.png \ images/sys_idle_dis.png \ images/sys_redir.png \ images/sys_redir_dis.png \ images/sys_services.png \ images/sys_services_dis.png \ images/sys_hold.png \ images/sys_hold_dis.png \ images/sys_mute.png \ images/sys_mute_dis.png \ images/network.png \ images/knotify.png \ images/fileopen.png \ images/fileopen-disabled.png \ images/cf.png \ images/auto_answer.png \ images/auto_answer-disabled.png \ images/cancel-disabled.png \ images/cf-disabled.png \ images/missed-disabled.png \ images/missed.png \ images/sys_missed.png \ images/sys_missed_dis.png \ images/twinkle16-disabled.png \ images/gear.png \ images/reg_failed-disabled.png \ images/reg_failed.png \ images/no-indication.png \ images/contexthelp.png \ images/settings.png \ images/reg-query.png \ images/log_small.png \ images/qt-logo.png \ images/1leftarrow.png \ images/1uparrow.png \ images/1downarrow.png \ images/kontact_contacts32.png \ images/encrypted.png \ images/sys_encrypted.png \ images/sys_encrypted_dis.png \ images/encrypted32.png \ images/encrypted-disabled.png \ images/stat_conference.png \ images/stat_established.png \ images/stat_outgoing.png \ images/stat_ringing.png \ images/stat_mute.png \ images/stat_established_nomedia.png \ images/encrypted_verified.png \ images/sys_encrypted_verified.png \ images/sys_encrypted_verified_dis.png \ images/consult-xfer.png \ images/mwi_new16.png \ images/mwi_none16.png \ images/mwi_none16_dis.png \ images/sys_mwi.png \ images/sys_mwi_dis.png \ images/mwi_none.png \ images/mwi_failure16.png \ images/presence_offline.png \ images/presence_online.png \ images/presence_failed.png \ images/presence_rejected.png \ images/presence_unknown.png \ images/edit16.png \ images/message.png \ images/edit.png \ images/buddy.png \ images/message32.png \ images/presence.png \ images/save_as.png \ images/attach.png \ images/mime_application.png \ images/mime_audio.png \ images/mime_image.png \ images/mime_text.png \ images/mime_video.png TRANSLATIONS = lang/twinkle_nl.ts \ lang/twinkle_de.ts \ lang/twinkle_cs.ts \ lang/twinkle_fr.ts \ lang/twinkle_ru.ts \ lang/twinkle_sv.ts \ lang/twinkle_xx.ts unix { UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj } include( ../../qtccxxincl.pro ) twinkle-1.4.2/src/gui/deregisterform.ui0000644000175000001440000000656710503576707015073 00000000000000 DeregisterForm DeregisterForm 0 0 287 82 0 0 0 0 Twinkle - Deregister unnamed deregAllCheckBox deregister all devices layout21 unnamed spacer13 Horizontal Expanding 111 20 okPushButton &OK true cancelPushButton &Cancel okPushButton clicked() DeregisterForm accept() cancelPushButton clicked() DeregisterForm reject() deregisterform.ui.h twinkle-1.4.2/src/gui/sendfileform.ui0000644000175000001440000001751511131206034014477 00000000000000 SendFileForm SendFileForm 0 0 461 127 Twinkle - Send File unnamed layout166 unnamed fileToolButton TabFocus fileopen.png Select file to send. spacer62 Horizontal Minimum 28 20 fileTextLabel &File: fileLineEdit subjectTextLabel &Subject: subjectLineEdit fileLineEdit subjectLineEdit spacer66 Vertical Expanding 20 16 layout59 unnamed spacer65 Horizontal Expanding 141 20 okPushButton &OK Alt+O cancelPushButton &Cancel Alt+C cancelPushButton clicked() SendFileForm reject() okPushButton clicked() SendFileForm signalSelectedInfo() fileToolButton clicked() SendFileForm chooseFile() subjectLineEdit fileLineEdit okPushButton cancelPushButton qstring.h audits/memman.h gui.h qfile.h qfiledialog.h sendfileform.ui.h QDialog *_chooseFileDialog; selected(const QString &filename, const QString &subject) signalSelectedInfo() chooseFile() setFilename() init() destroy() twinkle-1.4.2/src/gui/dtmfform.ui.h0000644000175000001440000000600111127714044014064 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void DtmfForm::dtmf1() { emit digits("1"); } void DtmfForm::dtmf2() { emit digits("2"); } void DtmfForm::dtmf3() { emit digits("3"); } void DtmfForm::dtmf4() { emit digits("4"); } void DtmfForm::dtmf5() { emit digits("5"); } void DtmfForm::dtmf6() { emit digits("6"); } void DtmfForm::dtmf7() { emit digits("7"); } void DtmfForm::dtmf8() { emit digits("8"); } void DtmfForm::dtmf9() { emit digits("9"); } void DtmfForm::dtmf0() { emit digits("0"); } void DtmfForm::dtmfStar() { emit digits("*"); } void DtmfForm::dtmfPound() { emit digits("#"); } void DtmfForm::dtmfA() { emit digits("A"); } void DtmfForm::dtmfB() { emit digits("B"); } void DtmfForm::dtmfC() { emit digits("C"); } void DtmfForm::dtmfD() { emit digits("D"); } void DtmfForm::keyPressEvent(QKeyEvent *e) { // DTMF keys switch (e->key()) { case Qt::Key_1: dtmf1(); break; case Qt::Key_2: case Qt::Key_A: case Qt::Key_B: case Qt::Key_C: dtmf2(); break; case Qt::Key_3: case Qt::Key_D: case Qt::Key_E: case Qt::Key_F: dtmf3(); break; case Qt::Key_4: case Qt::Key_G: case Qt::Key_H: case Qt::Key_I: dtmf4(); break; case Qt::Key_5: case Qt::Key_J: case Qt::Key_K: case Qt::Key_L: dtmf5(); break; case Qt::Key_6: case Qt::Key_M: case Qt::Key_N: case Qt::Key_O: dtmf6(); break; case Qt::Key_7: case Qt::Key_P: case Qt::Key_Q: case Qt::Key_R: case Qt::Key_S: dtmf7(); break; case Qt::Key_8: case Qt::Key_T: case Qt::Key_U: case Qt::Key_V: dtmf8(); break; case Qt::Key_9: case Qt::Key_W: case Qt::Key_X: case Qt::Key_Y: case Qt::Key_Z: dtmf9(); break; case Qt::Key_0: case Qt::Key_Space: dtmf0(); break; case Qt::Key_Asterisk: dtmfStar(); break; case Qt::Key_NumberSign: dtmfPound(); break; default: e->ignore(); } } twinkle-1.4.2/src/gui/addresslistviewitem.h0000644000175000001440000000223211127714044015727 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ADDRESSLISTVIEWITEM_H #define _ADDRESSLISTVIEWITEM_H #include "address_book.h" #include "qlistview.h" class AddressListViewItem : public QListViewItem { private: t_address_card address_card; public: AddressListViewItem(QListView *parent, const t_address_card &card); t_address_card getAddressCard(void) const; void update(const t_address_card &card); }; #endif twinkle-1.4.2/src/gui/historylistview.cpp0000644000175000001440000000557711127714053015476 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "historylistview.h" #include "util.h" #include "userintf.h" #include "qpixmap.h" HistoryListViewItem::HistoryListViewItem( QListView * parent, const t_call_record &cr, t_user *user_config, time_t _last_viewed) : QListViewItem(parent, time2str(cr.time_start, "%d %b %Y %H:%M:%S").c_str(), cr.get_direction().c_str(), (cr.direction == t_call_record::DIR_IN ? ui->format_sip_address(user_config, cr.from_display, cr.from_uri).c_str() : ui->format_sip_address(user_config, cr.to_display, cr.to_uri).c_str()), cr.subject.c_str(), cr.invite_resp_reason.c_str()) { call_record = cr; last_viewed = _last_viewed; // Set direction icon setPixmap(HISTCOL_DIRECTION, (cr.direction == t_call_record::DIR_IN ? QPixmap::fromMimeSource("1leftarrow-yellow.png") : QPixmap::fromMimeSource("1rightarrow.png"))); // Set status icon setPixmap(HISTCOL_STATUS, (cr.invite_resp_code < 300 ? QPixmap::fromMimeSource("ok.png") : QPixmap::fromMimeSource("cancel.png"))); } void HistoryListViewItem::paintCell(QPainter *painter, const QColorGroup &cg, int column, int width, int align) { painter->save(); QColorGroup grp(cg); if (call_record.time_start > last_viewed && call_record.rel_cause == t_call_record::CS_FAILURE && call_record.direction == t_call_record::DIR_IN) { // Highlight missed calls since last view grp.setColor(QColorGroup::Base, QColor("yellow")); } QListViewItem::paintCell(painter, grp, column, width, align); painter->restore(); } int HistoryListViewItem::compare ( QListViewItem * i, int col, bool ascending ) const { if (col != HISTCOL_TIMESTAMP) { return QListViewItem::compare(i, col, ascending); } if (call_record.time_start < ((HistoryListViewItem *)i)->get_time_start()) { return -1; } if (call_record.time_start == ((HistoryListViewItem *)i)->get_time_start()) { return 0; } return 1; } time_t HistoryListViewItem::get_time_start(void) const { return call_record.time_start; } t_call_record HistoryListViewItem::get_call_record(void) const { return call_record; } twinkle-1.4.2/src/gui/getaddressform.ui0000644000175000001440000005123610616426662015053 00000000000000 GetAddressForm GetAddressForm 0 0 655 474 Twinkle - Select address unnamed addressTabWidget Rounded tabKABC &KAddressBook unnamed Name true true Type true true Phone true true addressListView Manual true true 1 LastColumn This list of addresses is taken from <b>KAddressBook</b>. Contacts for which you did not provide a phone number are not shown here. To add, delete or modify address information you have to use KAddressBook. layout17 unnamed sipOnlyCheckBox &Show only SIP addresses Alt+S Check this option when you only want to see contacts with SIP addresses, i.e. starting with "<b>sip:</b>". spacer16 Horizontal Expanding 201 20 layout69 unnamed reloadPushButton &Reload Alt+R Reload the list of addresses from KAddressbook. spacer59 Horizontal Expanding 491 20 tabLocal &Local address book unnamed Name true true Phone true true Remark true true localListView true true LastColumn Contacts in the local address book of Twinkle. layout67 unnamed addPushButton &Add Alt+A Add a new contact to the local address book. deletePushButton &Delete Alt+D Delete a contact from the local address book. editPushButton &Edit Alt+E Edit a contact from the local address book. spacer97 Horizontal Expanding 161 20 layout68 unnamed spacer5 Horizontal Expanding 378 20 okPushButton &OK Alt+O true cancelPushButton &Cancel Alt+C okPushButton clicked() GetAddressForm selectAddress() cancelPushButton clicked() GetAddressForm reject() addressListView doubleClicked(QListViewItem*) GetAddressForm selectKABCAddress() sipOnlyCheckBox toggled(bool) GetAddressForm toggleSipOnly(bool) reloadPushButton clicked() GetAddressForm reload() localListView doubleClicked(QListViewItem*) GetAddressForm selectLocalAddress() addPushButton clicked() GetAddressForm addLocalAddress() deletePushButton clicked() GetAddressForm deleteLocalAddress() editPushButton clicked() GetAddressForm editLocalAddress() addressListView sipOnlyCheckBox reloadPushButton addressTabWidget localListView addPushButton deletePushButton editPushButton okPushButton cancelPushButton user.h qlistview.h qstring.h qmessagebox.h protocol.h sys_settings.h util.h qregexp.h sockets/url.h gui.h address_book.h addresslistviewitem.h addresscardform.h getaddressform.ui.h void *addrBook; address(const QString &, const QString &) address(const QString &) reload() show() loadAddresses() loadLocalAddresses() selectAddress() selectKABCAddress() selectLocalAddress() toggleSipOnly( bool on ) addLocalAddress() deleteLocalAddress() editLocalAddress() init() twinkle-1.4.2/src/gui/twinklesystray.h0000644000175000001440000000241411151321571014746 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TWINKLESYSTRAY_H #define _TWINKLESYSTRAY_H #include "twinkle_config.h" #ifdef HAVE_KDE #include #include #else #include "freedesksystray.h" #endif #include "qpopupmenu.h" #include "qwidget.h" #ifdef HAVE_KDE class t_twinkle_sys_tray : public KSystemTray { #else class t_twinkle_sys_tray : public FreeDeskSysTray { #endif public: t_twinkle_sys_tray(QWidget *pParent = 0, const char *pszName = 0); ~t_twinkle_sys_tray(); void dock(); }; #endif twinkle-1.4.2/src/gui/images/0000777000175000001440000000000011151327717013021 500000000000000twinkle-1.4.2/src/gui/images/stat_conference.png0000644000175000001440000000152410503576707016614 00000000000000‰PNG  IHDRóÿaIDAT8…“_h[uÅ?÷_þ4ÉMSÓ´5Ýfi»v´q¸neê:-¨µsÙVн¨ æ‹AÅ_öªhŸ”¹‚Œ‰Œ¹uâh·Zuk“.íÚ%MzóÇ&7ɽ÷çC· "ì<|ßÎá|9çH<ácá#G޾ÙÓë6òFá»±3ßN}}ý`íA\<}òËýò¡˜ÈLŠ+éIq%sUŒ§ÇEÿhßY@åþùïÉ<óp€åi›ÙÓ•à~jIZä››Ÿd#hŠÏ€÷ g8Æ-¾Ø¨ë>¸ëè‰ïÄZöá<ï\š¸v¶îÞ ©Ïiòê¸Tã@Á„¤ÇÓÊ.sSÀ¿mÇñѾýÐcQɱ@’Ø{éÙ†KÛ8_~_K ¿ªÔJðPM&³Lbó…èþWÞˆ´÷F'ç  k»‰'éiú˜FÝE¹"_µY+_®þå|µ)nnÝš5-,ÇÁã’A€YsÈZ‚ì!d @ ¯å!mX¤ç~ø È(ÞHçž}CÃ{u¨×5ü>M•±k*¶zƒ@}‘âß!L3Lз…Zg¾?9µò‡“áw 7?5ÓØ±ó¹§žè‰tDT"ºŠŠÆõôynºFY“§Y±gY©Í,ÍPt’–ºs?‰/ï¥PÎÞJ¬eŒ”‰¿ QΩ$SKÔÚâ¯@•ÀqÀ¬‚eBýN9èbPØú»Ÿ?ur¤Åï)ZÊ6nÍA—ûXÍÚ4·ÿL8~( Þ ;¡,«Ôoôé‘×^µ…Eú@Dj„–!Ô æZó ôö£lLd@ >Zc8Õ.ÐCÇåzCJ ’„ÎB Ài©‘!W©™€$Ü$A)%ÀZKU‡Yñ fÌ,îÇ#Ük™J*€U`É \„3 w‡™5€ne-25½ŠM ˜P‘ªØ¿‹i&3C6f´÷²¾TÒ“9­RêžrY‹œIâ4޽üå0Û™ TslÒ.k.g¿¾G\®×aÑG•AÁ²&ª™Á½tñï·Òw  ÇŽ® ]?âó½û_ßdñDPÕˆÈQ,?üG"‘³¶OE¢9"zg—6Й8ZJBîÖt=J¯ßÌ63ÅÝ7³gÏvçÑìvüráÖ{ëIEND®B`‚twinkle-1.4.2/src/gui/images/undo0000644000175000001440000000032410503576707013631 00000000000000‰PNG  IHDRÄ´l;›IDATxœí”;€ †[㩉Ç2„c™Ž½NhAyILüǶ|mè™FhBýÁRsK°RäžìÖèE£´¡Ÿ ¥È1‡Î0–|TÃc`)1íä|å·?öAʬ1• ×í²=6/†¦€9e§â-´®mZ3¸^µ %¸÷[sÙ°çºÑNNN‚ìI×J§ çô½ëöƒO%FÑÀíÅ7IEND®B`‚twinkle-1.4.2/src/gui/images/edit.png0000644000175000001440000000233210643547000014362 00000000000000‰PNG  IHDR szzô¡IDATX…Å–Kl”UÇ÷Þù¾ù¦ï¥¼ì¨H4JT4º0QV&DtãJ£ Dñµak\àBưI|“ˆÑ¸èVy”„˜@Š’Z-¶P:¥ÓÒÎÌ÷¸÷¸ø¦´BÓ"á$_&ùæÜs~çϹßU]ýÂ"íÏ¿Îôn{qãÝ‹]@gW¿Ä2¿9™ˆD†¯:é ¥çܘî”ï::ÏÞL~  jpŒX Ö Ö9¬s¬<ó›—Ìü´SþÞûî—?>Ì &èìê—¤âIÆ Grºû”L@\ßSâ.Wø]®ýV:6µn_°µ˜Œ†ŒQ­©?·›ÜýÀÀa8±zÞ§Å/Ò¼$xXZkÜL­Ž кúÄ£44îKÿ(a~û…¸pŒ+mO¯ƒo–õĭY­Òº{ÁªQ((ˆX£ \ºâ‘egÓ?:RsÌ…@ª@ ¾FÀ ƃb#'*òkÏ"—Y¾çû£5÷‚œúŠ ß>$>àC±‰óÿŒãoÚÁšUm,o]N¡Pxt¾˜5÷À$­üµ2€?}Qò@g¹¸z#þŠ<Î J×2Ø‹HÎ${Ï(„uPñ c¡ØÂÐåq*^ ë{ˆw‹ì…ñïm„j7Žz êéSíÔ=ð$Î9ÄÚÕ¾³5¸¡.Tc$õpUƒI ÒD¹RYÿ9ÏàœBàÖÄ}ŸãçWÀƒŒƒRl#§{CZ¶nÁZÁU÷Þˆùdì,*:²J1h •FâÄnxœ1h-X«@§æS osn^”Îì§þ¾õP «ÌI3½Ý§i}çeD' Ð€`e&€¼²@>’@~xN ”ÆŠ™C Ú õÄÖ2¾æYZÁZ‹V ”‰ ®( í¹©¤Nƒ(p¸æ9¢ÌÙ}˜Õíir± ,$- žïeÙsob4(e°VJA¹Q)—º%@Ë´¤×I£êfˆ$=v)ýŒÊ®‡â˜¢,øC•vV5/Á9—žIH¹T! #b qW#ÅÞì%*3»Õ“ÜŽˆ€h¤™“'iÝú I31Q¦V°±ÅIºPëÚ—=-€JÏþp" gŸ ÂA¬v\´ëhÈ4±N”Ö`"Šy‡ ­Ð‚-ω*aP˱ý{iÙüÖY”JiEZ+DÒÉ™=©«¤Q‹1 3È´ßÞñe´å‘aíÞů~„Wß„µJ©T¥Ò~P õŸñI«›@ª•§uÁñ?F8ùYwQ`íÛ»qS˜Ru–iek­ñ|Çàâåë“NÏ7o·DWÇikìcíkT›,•]Hç~’VkÈúÙ KÆÏär@‘¶Ô¬»rÀ¤§$‰å‘ÇŸ`íóÛ©„ñ”›ª>dñ³Y2ž—ª#‚ü÷¢?{KÌ`§ dŒá±m;Ò(B5ı%ŒŒÑiÓ‰\ƒJ?‡µß|'„t}ßCëE-¿ 2§H·Ö2Ÿîé¸m“›5ïíõ&ìøœ“s|»ì_ütþsbÍcIEND®B`‚twinkle-1.4.2/src/gui/images/editcopy0000644000175000001440000000041410503576707014504 00000000000000‰PNG  IHDRÄ´l;ÓIDATxœµ•±ƒ0 Dψ¯ŠÙù6Ô…ªÕÙŸÕëP™F“”“¼pÉóÉI„¨*Z¨kB x¶@U¥L¦Ù"R ï÷“5# áUøöR×·Q¤ÿ¾­§Õ1Ù¬`Æ+ȇã?]x÷_$‡Šî=Ó0,á}H¶I*–çMSîÞ ƒy¾yóÜøX‹6–¢[qæÛœM!¼©:Ê­Ä©CµF·{ªNœkÞ,qgi¼Šç*VŸ{ÿv?«gœSõŒ¯l*QxÿŠö´ú™~ߤ˜{²ó0`IEND®B`‚twinkle-1.4.2/src/gui/images/penguin_big.png0000644000175000001440000001516710503576707015750 00000000000000‰PNG  IHDR@@ªiqÞgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe< IDATxÚbüÿÿ?ÃHÄÄ0Â@ZÈP‡a¢Ç@ –T [WQQfŸŽC,³û†% T#ñ 3S—Ë{gŽH)–{ J)!PJAŒó<ƒsk-´ÖØ÷µV,ËcÌyÛ¶µµ¦‡cŒ­)¥ëÈ !äD)ý väœßÞûÇè÷ÁŸcÿrÎ!„ð×¾ˆ…Ú‚éׯ_ €Râàà‹‹ózJ—@ÄÊÊÊä3€²ÞŸ?Àj¿}û&ûîÝ;/^¸Þ¸qãÏ—/_žx¯††Æª;wîzýúõwZ@Q5@žPËÆ~Ð’à|ÆÄÄŒe°‡± ¦A 6H”¢deeY?~,úôé$ çã€æ•––žôäÉ“ÍÀò”j˜j@1ƒ,&€bè pL‚Lº ¼¼¼ iv  ttt泄3Ï X,ÃDƒÌAö†,U€Ôd.(`åå倱ÏÌÀ,å ,O¾³Ë9 ùÿ¡©"@¨&Qg`r_Œ“¯_¿‚= ###]]]`Ì1HII1 <`L‚= u°À€,ÅÀ0(5€ô³°|aÞOŸ>ùS?°9 蟔f €";@°Pó:f0HƒbŒŸŸŸÁÓÓ\K€ ª1@XDD„˜B$%%^½z®%@Å6̳È $†e P´ƒáéÓ§à”,$-ÔÔÔäâ‡>~üø’@dözl 77· ÈQ ê4,, ,òH-ˆF °HæyPj¥ XJþÀ$6˜äÁ4(…= 8`©£©©)LEû)á7¹© €Xˆm Â<J¶À:ÜHÏ:äy ŸÁÛÛ ÏÀ<£‘``µsæÌ{@ž03ƒj°:ÜÇ:VóèÑ#°P œ;w.ÌÀÀà-0PÊ©”·þÄ J¢ äLƒÃÆÆÆÌëÀZ#..® ò8È $oii ŽMôÃ@žÅæõë×Á4(Æ#""|}}Á*PìƒÄ@¤”ª¬¬¬Àöœ:uŠáùóç`s@ö=o L ïåËi`àƒj‡¿¤@1ËÉÉ[q„0ÈóÀ è¸)@}î ü ʧ ÂÐÏÏT‚„ë°@fƒò3€þäÉ“`=‰‰‰ À˜„,¥ÁjPlƒ d§­­-ÃŽ;À-DzPªši ôÇ`¶x-ÿDt_äQ ‡C€I0TªÃ *ÇA…¬ÚƒUo 6Ì#0O<,ÅÁ”]DEElll´´´à­H˜Zä@€¨Ù­ªªÊPUUÎv°¬¬&€t50õˆCwDWN Ïáà, $$$ Lfó¥±((` pÒñ‘c=öAæ€ò/°…ÇpðàAP[h&8¿=Na ’ÖPBn3 ,0¯3³¸LU @0PåYá-P ”ˆÍ Ä*™‰@fKoMP| KA±kæ‚æ  ‡ƒø σJý­[·2øûûƒå–.] Î× ½»wï{¸¶¶%5!{Ve‚ìéÕ&.\€Ä"0‚@‘´# {îÞ½{Z Ì D°/í*^¼x1T &PÒY r((‚0,ÿƒÄaù  ä ʳçÏŸg¸}û6<°€Í\†{÷î͹ÿ>ÃÀÙ=Ö‘J »` +lAä.`á(lЇÛ ·êþõ!ÿ ¬e†³:˜\〆‹Zx°úä)C@õ2¨&€9È)äaz(%€RH ”@ùúÖ­[à¶¿„„<0Ñ[‰ õ 9{A4(ù#·O@ö‚ÔÝ ¬5–SÁ5Pâ ”ˆä | `!' l¹…Áª8XÃÖœõÙA Pþ…9†aÒ*ôlmm6oÞ N®À®.Øóvvv਄©ÉÁRÌ.X-“ØåË—Q" ܦ`9%lš»SÁ`@ýº o (YhýÙId (äAŽ9ä9PL€’5¨’yÛ õ°ö$0089ù=ªVÇÍÍÃ0iÒD†cÇ.04442pq³ ²o@ûXþþgdø÷ç+ß߿à½EP̃ôRÛâÅ‹Á `X ÀRP°º^ Àß@ü _ã €X@U¾äÌÿ~@KAž@°¶9(@‚åèÑ£  Ú$’©E¤#Ù€ø°=ñ™ÁÄ„Xâó€ÍioÆ20iÿ8¬·Ø˜‘õÿצŸ¿¾0È3üúË PJ™*G¦M›Æ°oß>x–Com‚ìºSØ`S êt½/ÞZh¨00OÙ€Bä)P`ª/P#0_½zÜBÓ×ׇçwX`ee»›û:°úZ 4“ ìX..&`’‡fQ`Yõÿ°c÷ ˜ªÞ}`xñ΂áG*Ðvp€Ì˜ æóÙ³gáEŽ}X6Ù \~`Ui ´ç4P +¾l@8k§…’6°îV†5:@I¨ l«¯a…áöíÛÁžÕë >¨ ƒ Ë`)¯Tol7c›‘ ZK=ýè¶ŸÀþÃg gž~aøüÕˆá%ƒ(¿0 8¯·µµ19rží`žEï«Àjèp›°üâf•‹°g€b(°B =€c`è3#g PŸTUÁD`j ,Y²„!44< Rk°³³Û÷ÂÀ˜L:Œ¨~;Ð9À²çï?p¬3|ºíÉG†ïoåžË1HK©1ðó²‚tàl*¬oܸÑÄÅ> ƒšÔ5 û>àËÄjx€úî ÐEÀ䮫³ay T€:# N ¬y 5’@%:0ÿûî @9”e@v@:AEÀdý‚…ñ$Ðó< _€îzúá÷s~†§2… ¼j <\ÌÀ€BŒÆ€õ;Cnn.ömÛà1Þ€UÃÐFš$°«/”¾‡/ˆ¤ä0ôž°Zc6OKyK¡ÈÍRP›ä1>PÙàããÃÐØØ®‘ë}ä*b¨FxÌÀò'ƒù;°kûŒ•áßýÿ D˘”½DùXÊ ¯ûamP‡ Tdff2lܸœ²`†¤2Hï¤$tç_`ä¦8qbÐRР Ö@1ÃFsA–!c`Œ&c; h È@Xr‡v h0󠺼££ìPrEòBÆX¦f`Ïñ¯6ÓË ÷ß3<æùÿÊ büìÐ…èÁ:H Z¨ÎÎÎàTõ"W· 6ƒÜ²˜÷™€nù ´óÐ_¡ÍbŒr €˜q”ù@K' bGEXV9”Ïõôô€õù$pjy½zBn¨ ’,³I2üþ*Æðá»8Ã7…8qAN°G@I–ÚÐQA ò$hìáøñã Ïž={æyXç Öoxýúµ°–“ê=äf”@ ô•<@Ü“ƒåsô~=¬O?qâDpwÖIAÏ“è£Cð¼2†W“á7Èá l†êa]È#Ç J  lìù;Q @ <êQ‚ÜR›x¶t4¨¿}ˆßCý÷@!°Db˜ÄÙØªXÇ1ÄÆÆ‚[eèÕº§1Çnøÿ•œ-@žG€y½Y -5AâÀ<Ί°ØGîJÃú@¾*ÐBK –¼ / €` ÄK8_«9öAM_P¾‡•ÈòÈõ4zv€¢ºýö,Ö`j‘ó/:F(¨C-_°éE€ñaƒ±°ñä « ±PJXÄÞÐj‘ €@:w±#1ã0CA“nnnàê9ÉaDf#r ÁÆ‘GƒÕ §Xjµ3@ÍoPy«1`MdäñE4‹ð4P)@ d m—2ãKC6ÌËË \bP¡‡œ5`Ù–D‘‰ìIl1>6€< ’ úã°ÀbP5êÿ¶¾Cñoh¤ h¾Íâ‚ pC1 °@á&±0`>DPç 4 Ê_0GÂ<‰\ߣǹ¯°<Ž.ŠÐd åýUÀÚSPÎ…æ‚녈إ²Œ@Ë>?þ¼ h‰5°ºá@N¶È1BC¦FN °–",5ÈÃÈÕ,@@=RPìéCÀ¾Ành²ÿB¨ô‡€b&eiý‹/îIII±)++Û#Fy1zqèCXÈ¥=¶F Ì£°©oØAØÚFÖóå–×̹víÚ< çAUß'l=[| €˜m¬xýÇÀ rëÉÓß üÀ´/ÄhÇðüÅ+ ø¯ÿBBÌÀ¬ðæùŋ׊ˆÈ²±ñÈ|ýú“áÓçïÀù+0v>3|þŒ! CAù–·‘ÛíÈ%>z²‡èùÄ?Áþå+° šûñÃ'†×¯?0¼}ûéÓ;æÜ¾}}0`ÞAcþ´ñC ‚µhšê3Ðcÿÿ31pqqòI Š‹ÿ~ûö‡Ä¯_Ÿ¸>œ·U[ÇM™“MPôãÇ¿@ÇýexÿHüÍðãç_vV&.6N6`o T…‚:-°Fl‡ ,ÖAžþø @O33ÿaàãådça`c>»áÿ˜^<íÅ %n‹¿˜¼{ûçî·ÏÿþØñ}>sñ+Ãå{ߘ€™õ‹fˆ÷Ú``Qú˜ø¸Dlm•¼œÕ=JJ­4€åŒÃÿ_‚ L?¹À-ÿ}Ž?÷ð ÿ¾³3üøÆÆðé=óg, ×ï23œ»ÉÊðè5;Øó¼?Á]VvvxV€­;øLŸ¿þǸ¨Ðg}Q]}i9A~&f¤Á¶ ìþÝöõžýúùþ织7?¼wí×5E¶Cê"ì{w^ùôøó·¿ „–ÓcC4®F0ƒºº€¯«§³°°”>¨`ý÷2{öÿÿ?H/óPà°Åù Xî|Äð÷ÛsÆß, ŒX˜ÿü‡™áÓG†3wXÖãdxÿ‹›A— >•kDZ_~1p°}eð¶Ç`b*ÁÀ/ít¶Ð ` g€®¿ «Iþíûûèž >žgøýá9Ã7†¿ÿ3üxñ‡áÞÕŸwמz?mù•w³_~ùýZ(b €bádg²÷ç?ƒŠ:WHD´Øb†ï¯9þ}ùÔô8hä<Ç $€ŽùÿØ÷zÿ «¯À‚ï°Pû ¬ ¾=õ蹟@³ÿþa°àffÖýÉ0éì†7@5ü܈e4 ðãçv–Ÿ Éno´•¾ËY†ŸÏ302¿AJ¤Àå?hP@?ýýõáï÷o ?ŸaøùáÃ÷wÀÔó Ïþ2|~þOÙž™¯÷³È?é¹_^WASÖ ›f—‚ Eáã¤1AÑzoퟞ ԋhY:Îèµ£F/µa8÷ðÝßpü )bOGG•n²3sb?1_Ž»SEè?ãé RY؈´Ÿ00bHuŠà !gxÛJÉPamâ'[ØZ3ÃpˆQ5Øo-v>G3Xê„p~ÁDo ¢…˜K¬®w Ý&µ/opÙ.gÌì_Üe*xÐiÒ‚\À+o|~õ©þžÒ¿`ÓÜq† j‡ $J8”4Tkäp'z*n@CEMED rHâ/%ÅÊÝ®g4;»–§ÛÛߨ¥Óýz1ÚÄ•·*Æ#oÀ{ÀY¶Œ§† U&·%@ñf¯/16Hh*úö½çZ?™>æÑÐçÒwT‹tzr†T÷«UËD¬æ“Á¬Öér‰K/eÂjjA¼í>NqêšZŸœP/À£®g¡1`‹ªœ/zöDþä÷2üë_„s&”5Bœ]òƒ$Ju¤8íØ™˜9þüÖóÀì¬ [€À2éÈÓ_±þå?Øó¿€aýè çøòÇŸï§¿|>¶øÍçE÷>~»ÎÌÄÊÄ?ÿ#-X­ââÿÒìRiÆ"IŽ’¼þÌ,¢ÀP‡´@40aü±ÿA–ýþ ZüüÏð˜å¾|ý L°>kžW¿ÿܽð÷ÛªS_¿núþçß+¤F#f2#; £ˆ“.Ÿ©‘,·•¹ž«"óïÿ\Œ¿™AÞø,þ~6‚¾CbüÇ·ÿÿ>ÿøóãÉ÷_ÏÎ~þvéâ·ogî~ÿyZOÿ€:–ÿ#­ï‡­ãaQäc×4ä²Õçã6abQaýËÈËøŸå/°0üóÔÚÒà€f5 ûëŸÀ4ñïÝÝ_?¯?úõëâ­Ÿ?.~úý÷4æ?"µ0 ¡V° BÑÚuXÿÿ›Å¨d3Ý\D‡:È@Šˆ{êûãÕ+aÂ['ò“ÇŒ¨eÅUõÌÏ÷+ »þ´sIT¸%d‡‰ôØÒòkÎK‚3B €‹fhq€4q£»OåZ0±弊ñ4Ÿ=Ùé ^ˆ˜ŒÐÔÀ†Äf:–‰@çéÒÈìo|Õ–¡:V¨=¤ØÇ€fÁ%óDêÆC&¤˜"¤ÿ?RLÿc 0b±ï& ªíNS~qÙIEND®B`‚twinkle-1.4.2/src/gui/images/sys_auto_ans_dis.png0000644000175000001440000000152310503576707017017 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÖ ©ý”äIDAT8Ëu”KlSG†¿;÷úúúÙ $&ÜÄ# ¯$¢¨ ©D *l˰‚.Ø ±è ‰Ç¢R«²Á‹Š‡€¢EÁ‰7´E `â–8UIHlãǽwºQ 63›33ÿ?gôÿsŽBÕô-ù6X9ne?:Ñ{Cs'J5ø5w¾ñP,ØÉdvRlEØò~‰É÷Z7F¶è,þ¥÷ Äê•{c VÂÛtõ»Úµ/xÌßI£ÌÍ:k:«’a»Ÿ»¢ÃÂ$  PÈýUøÚŽWd}¨ 6 4>æÙ`þR±¿ØoN«!¯Ãå/ºÍÞ BøËàaŸVä :™švÝû©¾§”SZƒá×+k.¯^’ÃÀE~Q"q.ØZÈ^å,ufZ´wðšåö±•iâd”mç­YÅëô¸ðÁJi-g?©sûëE¿#à ¨Þ¬#ÅrÖâÄ$ÏŒgÔxÉ$…°f½ÚÞ¹Ãí,$‚W D/•$/IS“ìÙ§Nôü>Xèhöé4Lb˜Œc ’§ˆ“Œ2Þwí³ÌˆŠLöGŸDV|*’ ~f uü‰D¥H‰Ï±~»ðxïlfÞélòêÿè›#^)úð±Œ&Æ!…Nšá釆ÎämXøÖÔýøõTˆ[$‹‰Ÿtpç×hûóø¼ŒbAÑLâf÷XÞÇ,&yÊjhF’2Seº—›°jÝb—Êz<à«i‰ÂÊ]oU¾Ø°{& +¨ÇF"HÖ¯ÔÍ'Už„hèt¢ ÉÓ—ûñ¿L$‚Öí.-„F{[@ Is1q¼ëÔ–—‡-•ûœz•:ûôô#™”1¹çªQ?wCóá³¹a™?äkÃpÕq¬ÿ©ü~¶õhù®Þtàî;.Ûº+ŽÚ3G5´ðN ªîMÝçÒ_ݪ FÃA=X½é,Ýîšÿ·z ¢ÜX4çIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-disabled.png0000644000175000001440000000056610503576707016156 00000000000000‰PNG  IHDRõ,æ¦bKGDÿ‡Ì¿ pHYs  ÒÝ~ütIMEÕ6‘í ,IDATxœ•Ò«NCQÐuÛKÀÕ4)WY‰hƒâ0ÕXþUÃgð ˜\MƒQTeðÈ îm{ú}ÄÌ${Ÿœ=ggáïÈçm'Ñ]e?;AÏ®;·ŽËyUÔžºÜšží8B'Vè¡ÃxŠQœG?DDVÛÒS™Ë°‡QRQ)ž0ÅãR]DÖ.É9¾\£©>îq“ÍSeÕᬯ8±©»¼T3ñ¦––Kœ%[I NoÜ2Æy€°ï ¯t[åsW,yÐÑ…úÝ ×myä¦-k·mZ®^ÝÙÊ¢ù Ø–†&Ê>gÊþÏYoÿ›Gÿ}êè?wŠ©ã/é+8«,zhóš;~wìÉçËbÙ“i*d𠄉œvY÷B„‰LS)¥”R)«Ó©ÜõÚrÝmí|û7¯~இŸœ:Ý[”q$em:”•Z( eONLN˱ó5Y*{²Rõe©êËReæ­Ö†Rö»rû÷wCÛŸ£Í:ëlúúí÷ÿd×ÎßÜ—mmÉ2U©×}J•*®P™òlË$I"•¤© IQ"¨{![㎛6ä{ M÷ôŸxûøcWH eõª[yþ?ßÞ´xaŽÉbáÑ1Æ&&)UjTjuª5× iÊçÐu4!I…$ŠÒT1†¦°nõŠÜ›§ãë+£G^¼Ï%иê›O|ï_Ûº~m gÎ008H¹ZÃ%A¬„Ó¾¤u~#ór&Ž0tƒ4”Ê5â8AÓ âD„ YGÇç-:vzXîàÞÏ&]}û替õû5íMŠëO122„A˜Ú‰¦¼æ|†µí iŠëaÄÐÈBHóy¤”$IJ ¢(!Ž$“ÊÕçû»^…¸0'ÖUÛ_³jÝu“å 2™"I¡ÌD׈“”u+ÛØzírËÀ0 špl›¦ü<šI…$NI"Iâ”0LëD‰cw÷õ–¥?ràrLõ²ñ¼•+7ÝYªÖØsðúÆ©ù:¥ŠG©Rg²8MCÆbÛÆå††T$ª H‰¦©†N’¦È qF ©/Hp½ˆ¥‹ò,X¼î+@vvú’5õ«–µ5³d¾Í{=†'\JUŸRÅ£2åÑÝ;Á¹‘2¹ŒIÆ6É8&º®¢© Ì÷Â>¹ýÞœ5³ó Ü töÿtVil\pmב£áÀ@Ÿ¼û«Û÷æÝk¶,Ðo¾yG›â’‹’$=¯¾uÇŽ¿ qÓâ«ëÍÍyî½ÿ¾ ×nºþ…‘‘ɾ×_ig{ûß0r*‘*Š’Ä]]ÿgŽëÚ¬1ÐÔÔº~çÎ'ut,u¢(N C—ÝݽæÆ+ÍÅ‹áy>RJ,Ë$¼E¹\ñ7lX/LÓDJ‰ãXÆþýGÆ{ìG·CWl!4ÓqÔ\CƒaDÑÌœaè8ŽÆè臸î4i*f4PÒ4Åuëär¦“ËéX–”’LÆÂ¶µ@ËÿD@J·öì³»NضÑ,„LfH ‘Íæó·ÝöåE®[Gˆ€¤X,EÝ»w_¢ë¦"¥DÓ4­P(Õ€h6˜; UfY>ò]ÒÜܼbÅŠUÛ…–¢(â²õšç¹åžžS/>ª/ 37äQæHÉÿG£5á!µaIEND®B`‚twinkle-1.4.2/src/gui/images/sys_auto_ans.png0000644000175000001440000000267410503576707016170 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ û –7IIDATHÇ•VilTU=÷Ý·Í›¥™ÎtØJ[ÛRC¡e+ BŒH‚b «‰ $&å—¢¸$£Aù£øKƒš€¸ÔZŒ-1e§ØBQ ²(] ]†éìïͼíú£B[îÏ{¿{Î=ç;7÷<Ƙ%Hî*'>ZCVQü `-@} 2÷ï!c? 'mʳw- ú^ N¬`–ªÙñ:»¬h,,ÁœK㲌o5A7Û .@š=ÁwÔ]U9ÉpÈx hƒi|ÂôqÍÎko°|irKRÄQf‰Ê$ÑbÙëöæŒóI©¸6s4¼Ê ŸEKç 6 …¸ó}®øYUÛ%èvŠcpɲà”dE€â– ES0,ôñOÍVv.¬¦7ñŒóË¢nd=¢hy2õB`.©;#„Oô@"PS âp€,Uƒ;3Ÿw‚Çü™d8ŠÞD7ŠÃ…¼e[é…‹Ëæ×AñŒXj'`Ä K7Ð!†qùàyLÑ 8K‹AssA8”rþ{rcH…c¸“½‚«3‡º~ÿM[Eoõ[G[Û̳LKÕΨ²ÝT¢ TGàì!ì:ôÂz ä+' È€À1°tLÓ@$ D–A$ ñþ(úºÚpÐì>õqSò¹hܾJ°á¸uããzýµŽTIYQº4$ÇsÉ"Ñ“Äö†=M›A†[Oƒ³5žBÏš0t †na¨«W»š­o{n}uᢵ²Ç2pŠ’—®ÛΜ1o;cΔ'rLbwÓfäºE¸' ¿²C7‡pñ²¾Óü͈içqîúåhc_b]coò³Û0ì» ÆÔ³ö'ñKo·6sÎ,:ÉíI#Ggàv¼ –N„Ñà\´Óù¨Ý°S_ö‹ÙzàÎâKÑLÛƒ1ä–Íá„~í§ý¬®·K͈¹^l}} ÒŽ®a†¶.‚cITNz•5@B,™ê0L«ï¡9Ô˜ZªWä‡TG]¨œ7ŒÝy/áÄÉj¨ (Ÿ5 *{@CI)]ôÈ‹ô¨…¹³ø¥þ…e¥À  P’ƒ‹nÀ¶lb‚'$ŽªÙ´ˆçi™iZc²WRŒe‚,´‰1Ø™Aœ>Ò«îÛ30”Œh°í;4âÂܪ§Ó¥c~™Ö^<™ËÒ©–N=Á{'°Ï?”;Ë ù%¯8yíóòþöc~3™(aª:›¥“e샷]-’$‰c"XóŒüi2bª:™õ\ÊcWK™L¼¯Dž9ßTÿKMEB,/c‡ò2!±pTpJ©°s›£EK„ØÏ?¸ROWKo>ªVùòM¯ ‡/ÿå³û¯Ù’rݨ¢À…¾Ü¡Ä¶¿ï¼T^HçäøÈÿˆ(óf‹uû¾Î‰×­v4J๼[/‰’ÿq¾4ãƒrUy¡ôƒóÿͪ@þ° àUIEND®B`‚twinkle-1.4.2/src/gui/images/auto_answer.png0000644000175000001440000000145110503576707016000 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÖ;¼†›I¶IDAT8Ë­“Kˆe…¿[U×£»ºÛi3‰:…¨\ib@ƒº‰ QŠºŠ•Æ…(ˆ KÅ[ÁMv"âlŒˆ‚.âcb1>hLÄ‘™Œ“™žžîêîªêªú«~‰’¨;=»Ë=÷Àùà”\;¬à)ÀÃ@|Œ§€ðÎA¦?þkÀÔ•rÔ#îLëµÖwÜZ&iýtá×r0ì¹è"ÆÊŒýµF½P!gï%6×|®Z·óû>š=rÿ‚6@kÒßÖˆ–—±©(±HLíLzü>&[6À§4k•RÏù o!ûêK’~ŒAu:8€ÅŸf×T‡²Ê~x@>fÆRbŽ6}y+ Ô^£5¥.¯ôcþ*k) a˜Êjœ™'µ‘sv…̺žs¢Þñö–UÅ$M·Š¤øPLµ{aeÝ^«»4ZÖ¹%ëOO©~Þ[©wÂêðûÚîfžòŠcÔ»2‰¯½ÿ¬lÎ%qu"·Í‹{öÝÖMrtº5:mÛú«­¥›;»™‰”ÞÉkþü4Ó‡O™™ HÁ¾£Ü4§çã†í¥vs””¯Û%–%3ºKfãbº;ÚŸn÷™^îË(¢5Ƙv͵C×sð‡ tIŠ’u;‰ó—6»ëo..-Ìí9x7âû˜¢ LÒP÷záô»óWZrʤ7¬Ö»?$Iþ²:V…ÇýQ”“{|Ѳ@®š%Ë] ‚Ë÷Ï#OY]é~]<óXué¬zqyŒv7Lv¦ãôßpÇ2˜8Ƥ)⺈ç!®K´9à—3çŽ6úÏ>Q­­(€÷V­ïãáäÛí —ækíæœØ¶Ê3M‘—yÉöÅ¢{zå“x':YéòÜ2Ñ?Ÿ à‹7ä8ÐúÛj(˜·³ºÍÿ©?Ķ:Xû.p|IEND®B`‚twinkle-1.4.2/src/gui/images/sys_redir.png0000644000175000001440000000274610503576707015464 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ 8F×Þ{îùÝ{ÎÿŸKÐÅp,  =÷yŠçæö™þ—¾ú>';CßßÜ›Z:↊Xd±tŽt¥¸ø:•]¶äè\×_ ùÂL¯¸…8jÛ½‰–æÈ±s—lÛ#â}+I>> ÒòxeóýÊâà´âÙ›ÓC‚ÃÆ’º…ËÍqüZmÛV“¾T7éüÀ]LÖÒfYiFÛx¯RãHú ðD1u-/³»•ÙÝ-‰<‡D2]Õћǯ¸féš¶U ½[‚{$ÀÒçLÙ×=«_4§þ¼®éeAvï÷Ò)›Vl.êŸW™×ËéöÊ€hwwwú„ †ÃÔ»%˜GÌäXúöà3›^}îd‰dçÀq,õÿW,—;k¯’íÕõ†^×"AÕ8° -…™ˆqí×^Ðù vzŸ€âìô²¡žtšÐL7vž†“üüJQv1Q ¤’(ŠÜ7ImÇbjÜ2“‘ZÅLWTTQ.Môe¸Á0 D^Ãkå¿aBþFÆÁ«Hsº Dâ€×¤*–ÅY±jXú›·à8Ž)¯Ñ­‚PjÂBš;ˆ•s¶Â¸±£¾±9¤Ç5 5Iq£ÃÄëgÙ[ó‡†4Z,¯./a{Èâì–" šžt ‚é±K¬T7QÛÐ1cË–‡špB3pIhobÑ"}OÕ.}N"‰›, ™ ~×¶_< äöŽåø|„a8 I„¯EðYÕfº ÈJœv@ÃTÐÒú7rú]/pÂÁ½Áèô™ÉO6ç&ÂÀÞ3ÐHÝ%kשSF“×õ}‚WXÞÛ­lÙ·n…ƒ".ž i0hhfa™ÕèWX‡x„bãÚðÕµë̉gꌭþw2{¿µZÚhͱãØÝx5>pPÛÓá “ÃG ÑÊ…©ÝÑ|KÁéŠO¯@ŠŸ`åG¡SK¿ jjÕÏÞ/ÃÊ4Ö.þ¸“Îm¼¬&·Ì~<©Áå ÅŸ— Žž  çB > ‚(nG¢çuüþ@?ÌOæhùé~ÕÆ° ʂؒ:ÇŽ—@ KÈϯG^Q¬ä!¶â¡FzØFi7*%…iFA!#-àÂØÞ °L ‹ Da$€„0 ˜íÍql®a˜õ]j&УyIº3&Ja%ZQ}¸Q­ú¶åV¤#Ëj! J+(éÏŽêêïYbGœ;h/‹fÓÖÆtÍR©>7‹™æ2+_‘vÖM1"áUÕb‹äÒ%ï*'DQº˜ü¼´*Òæ§ªšI¯Õ¥Ò“Ä]²D2îI‘>ÅÍÛ¾IQ£~ åÒý?¥&zù…¬N‹³,˯^l;ûé/Û”è°ñ‡å —7ï þÐ…Z¯Õ|ÉGG>#Íí ðŒýrùö§‹ìuyYìp—ËK}!"— s«¾q…æN²íë`“x)/‹™& b #ºû¤yYâ˜û×ÿ›aDÒU÷e/IEND®B`‚twinkle-1.4.2/src/gui/images/reg-query.png0000644000175000001440000000147010503576707015372 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÖ6;w$£›ÅIDAT8Ë}“KlLa†ßÿüÏufÌL[£Ó‹ÑP: ¡*$UB”¦AR ±°²¢‰êBl„ i‘q ±A5DˆF©kµ"™hFMÚ*3f¦gNgÎ9¿U·é·ü.Ïæ}>‚iŠRZ\·¡i²ò²?øÑ$3ËÕÕ—#EfWøub‘é[wo:IB­{Ö,­f5sex]ôŸºzÇø±ûåI§ùŽKvêáМ²Ó«k—K 5*ª‚‰"`¨úË|Xñ$ê}#ähöÐA¿7¬xÝ24ÑÆÐ¸€+m|þ‘ƒ*®rÍ­–ÈkIÁ œSD¿pH$MÑÝoáML‚"‘•ÿ0&”«ZAQÜ ˜?E®,Z› #¸Ñ›…i© ^¶{»v³q£'ärÉ %†[ ¶_›!+GzRI¨ð(€Ã –ͱÀ¡àÌ= S£É}YOŸÙ¶j•r­¡Ñ·€Ê^p¬8´nÃ&‡ßE`Ù€žð` ‡oi²¦ƒñ¤z[ˆDíw-{ôºû‡:b‘QNEZ7Á&ƒ(" (4UJýá2 ÄG ŠÀ¨>iÀJž›Š1Û÷ÚîìÏ> óúÐlx&╌RD¾Åž ‚3=Pd†Øï‡Óühv8¿ô‡Ã#N´¬ÓúMž†ÎNL®†§‹âUŒãÓ÷Ax™l³ç nsÿ$p¡C¹3‘žÅL%Oêóy|´Š'‹x2Ußõ̲(¥¾ß÷ÿI«(gõD89|ýxõZê©™ŽC€…‹=´±ž®Ïëþº:©9ù5ÈõÏ¥üh«v€ݵMjx>3—JVñó§|7óN´+'Ÿš;·Hûþž…çÑÚ‹gÝoÞò§c®ÿvl÷VV°%Ó<¨ØÒ¨’D)8Õø3Ï«ÊIEND®B`‚twinkle-1.4.2/src/gui/images/1rightarrow.png0000644000175000001440000000116610503576707015725 00000000000000‰PNG  IHDRóÿa=IDAT8…ÓMHTQÀñÿ}3ó&S+cД>¨HÊE %Qôé¢Mm¢ ¢H"*°E­Š>‚ HlÔN(* CÌ¥å"‚’,#? ¿qžofÞ{÷¾w[Œ¾ÅuÃÛ–1²Öe0_/Š& þµ' €€Lç{dgG/¾wÌÏs†¯(--s31ð³ŠñWo?t¸±ŸÌ‹¾bÍJPDM°úGxÙÆô÷ž§½ "9¿8);ˆü¡´²œÁ®oühnq\k² ÌÛó_ßܳß9Zp£¾`UqCa¢$‘êñìô-ˆu,V¨ubØ tíqaØIEND®B`‚twinkle-1.4.2/src/gui/images/log_small.png0000644000175000001440000000150610503576707015423 00000000000000‰PNG  IHDRóÿagAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ØIDATxÚbüÿÿ?% €X@Ä’¥Gîqr± }ÿú‹áßß? _¾~gøðá ×/ß¾~ýÁðíÛw þÁðýûO†wï¿0\¼xõã‡÷÷“ÿÿ¿¾ €@.X·þô×O?þýÿ÷ïßÿiËŽþÉžýÿÄÅG`>:¾zïíÿâÚÿÙÙÌŸôÈŸ?ÿøýáóo†ï¿Nœ¿ÃðàÉ+†¿±{íõ»Ï _ÿaààäâñì…¯_¿1|:•“õ?ƒ§ƒ>ƒ¥6ƒ¶ªV~üøÁðäác†ß¿ýñbÀ7?1<ûõ‹ÁÆDhû_†×ï¿2<{ýÌþtÍïÿ¾|þÊpòôu†OŸ>1½6 ‡sŒ Qôßÿ–T†Å˜°£!®“ß½ÌÜ¡—RÏÄĘÁ=ÿ*áàrÇŽŽ5C!žÜZûŸ‚ õÏ@Cþ!;++#3#à‹¾ÿûÅÀøó';Ó!^.†W@±OŸ?Á  °ß@Ñöù;ƒ’ ƒ©¶4Xèr`àþGùò(úŸaáê= ×.]@Ð@„ÄñÏ^½ü tÐf`”|iŠƒ øúõ' ÐY_ýøö–â‚ï?>èã'v†?AÑ O80€Â‚™ hÀׯ ?½û ºà;Û7ØÞùæÿÑ3èû÷ï LŒL@þW`@~ê‚Ä@Acá0éˆ?ÐÀPÿô¬d ƒ 4ìÏŸŸpbÀ§/¬^¾axÉÎÌðSEœáׯO@ ŒZ`èÿFé¯_?€¨é?#Çׯþ}ÿÔÅÈ Ò @Œ Ààç÷¸ÇÄø_ˆñ7778‘üýûl (IƒÔÀÎׯ©ð3Åú˜™”ˆ‘Òì `°“Þ2¨  IEND®B`‚twinkle-1.4.2/src/gui/images/redirect-disabled.png0000644000175000001440000000050610503576707017017 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ5*xïOƒ×IDATxœÑ­RÃPÅñßeêx\]by€4ÃK`èTfRÓ—@€[ßÚTµŽwÀt:D¾nh˜éQ»{ÿ÷œÙY®Pˆ›¬ê2L@YÍGôá)C‡ÄÀ6Xø°@V¿"@*¬”aÆÖƃjÒicÛÄÝÖñ8Á~þ„6niî;Ÿi룼‹ƒÜÒs_xóÞNµP*÷;)žûº €4Ú/ý³ë e(ÀúbÓ•2ôq{‰ëÞ©Amߟe!qùñYŒEgì¬pqàìTŽ^®Ð/2c;™œ7RIEND®B`‚twinkle-1.4.2/src/gui/images/sys_mute_dis.png0000644000175000001440000000140310503576707016155 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ /¦–Ì”IDAT8Ëm”KH”Q†Ÿÿÿg~gƱi¼ŒF“·Ìļe*(¹p!""µèb‹lU›BP‹ lU #• !èftƒ”Ô„T2SMmÔgt”qtæ´PÇÉÎÙ|ß{Þ÷|œó½çH„…6Û“Ø<Õ‰Ê k.ÿSß­¦ßR(zMÜzŸÝVB:áÀ:ô3>ï¯zô1¤ ÆLï‘Ô ŒA˜—t-¬g6;­ ÷vly9ýL0Á^Öèf‚I p˜œyíš  òL©ÅN>=°u1à ·7S§)o°˜pn%Îüªy½H+H‰À8Úb^ôÈ)Zäcžm¸ug@–wÑu?Ì+üżºÂþ)]ný±ý¦=ѪwÞj´*æ}RˆÛÖ#áeêºÎ·RXvÜd|d³,bÛ¢ÅVæ\ —$äø’êÆsûÌHÈ<<ÄÅa,»*¸è÷8NÙ_)×¯Î–á”øCQ²‚`–·$3…ŽÔ­©çK¢Úú©au³ÓËcmߦÕü³Ê<XHÂÍOÏûA×uü¿NÉÂ?ï\8®P\»låŸ~ì¡ë:îd›/^¬”­ß0¨áó³ßÎß¼ÄúÙê_·AYA ¾€û›i-íg¿ýò¢sNMMMèŽ X»låÞ mϘmt›ÐìWøî¼¨ð¨Çqàà ˆ$¦ÕaÑüs]öl$î*×9ã‚ax{ÖŸ~êå§“TINr&ÄÃfóáôrøZ® o¦Á67Ž|²Ž–]å:àÎŽ`ÝŠw ü(yº¸ÐÔ³øës Õ M5}ÁÕ( ã¡ûaVB@ù?àuå„O|os×!ãÐ5Ýh ÐBõ(-\¬\5¹ç•쯴é˜>ÄïÄ´Ý_@ h ðÅD‡ãZìÞ?þjôž;æøuËß}iýü¿tx»ÚõsG×êE¤û÷;ώıf:õï>£WW<¡ÿ&+M¿c¨¯¨y»`Áä(»½ \G+TUúÙ&ÇÙõ”QéÐBöoj Ìúj¯M¸pÁ__¨íÌ€a9Ñ/?;eÒ*Q "A‚kxÔÞSfåMze¨%"N„0¥>e~Ív_)¼_ùXLD¿ÌÌòP¾ô$ôØ„õ/½¹mq¯:P¶qãð¶V!wû®W©7ßøuæÔµÙ’$Þ†‹<ÔÑ£òÙÁÚ}%¿ßÕÑ\} &«f¦Å_òÊ#Äw+ЬUJmÒÖé+ŸduÄÁÑ–èŒÿž‚²‡O6íä­ïââbÚßEý]ѸÁ®ÄL¨2‡5kþ† —?xnÖ“3x^Ïóhlhs­Õ3€¸R^îêúyXxBª£‘™ä#ôYÁû#“>e‹*å¾túmA^+~kK½Ûÿ¸Ýaª‹vY‘BnjôåÏŸ7>5>%~O‰‡$ñÞÚ/Ðîé>e¹ðKɲˆ²¨QÊùR.ÅqÍrð4cŸ…ÔûÆB Hر²Ý‘”ê–¸èhGªóKÁM¿-àå«GجK&Myí-çqêtTEÃ=÷dŸ¿§ŠÌCyH‚Ðq©þV }bàD[?ªÂž—é¡ ¯ÙâÐ7„Ù¡eXœs§¼üPÄΕn96?{ü칫÷ïܹÓ\PP ÀmM¤»©É"Ù§_6bûGHæ Èž†›p ‚ B‚B²†ú†NœªnE cÓæƒèö‡5;c"LΑ¤ Þº2ÿú¥g–% Í::{îêýp þE/ÌÙòÛ‹–zÛ/';bÒn¨²Y ð<š¦Ãïá÷Šø%‚2DA†Ïߣ‰¨š>}:g2a2™°l}Í*«~Ìà?ˆaxÓÒÑ~=9,<Š,@‘9ðþnìþ´ }t ­×›DE–`2ZéÙ0*7²¦Aäeˆrv[|ì Î×zpððY¨ª‚ô´¾2$þfÎ)8l6€_¨ÃU·II6<úØ Ä¹b1lX¼Y‘C÷Ò sÈ` zpkÉ´4ÔUyº},¬¾WQƒ!µĵÃÇÎ&ÕÕ Žž:u4âû˜a·ÑB*÷Ôáð‘³m‰ÉŽÃÁ‹Ë¡ùuCïêëd­Ú¾äþ ï½€ß쀑ç1þáü®šÚ·0SÔjÚ¢LK¿kK~þxqÓ¦o˶ƒÝc²2ï5ŒFEùYœ8Y[—wìýEEE-4McÆ‘,­å÷KIÞñ¯ï}OE”–®ƒ 76œ¢ tsɤeES¨ø¼‚u_$.OŸö`l´Ó‚·—ïSòòœ£_üCá–b@±,XšÍ2èíŸß*rìØ±e!Uýn2‚2߀³ ‹ììlåâÅ ‘{÷Ôæ|s¨.Ÿvré²yKhŠÃÐ`X,ËþÏpø'®0XzGZ×ýIEND®B`‚twinkle-1.4.2/src/gui/images/stat_outgoing.png0000644000175000001440000000152210503576707016336 00000000000000‰PNG  IHDRóÿaIDAT8u“[h\U†¿½÷9séd.smb:™ÉE[«iÚ¨¥)±¡BPZD}Š>1>ø¬ >ëKEêƒD„ mZ± µi½‘Ú⥩­&1äbgš„Ì$³çÌ9ûø0±4Š?,ÖÓÿÁ¿X¿8ñƯ1·¬?)îœ.¯ß‘ž‚¼‹€ëxmB™¹RÙÉkGS*i×á^ÉH4Ö…;͆9§—60«.å²yĶ­S™.ûð¾1&ÉÿȲvTÑ€'nQ4¾‰uînéëïˆ%kãü09ýôùÓß'ݲû,‚¥ÿ²3sçq‹Wš3µoE£==-ôîoÅ5 5ô>–Æ Øýg>ž_]-=ܸ ’¡®Ra-ß ÞÅÞýM”4¸.x¸4lÓÔÒÜ47»´geyíS©dþî ª"1B*”<˜bOo-e R€ØD–i¿gŽu§2ÍgŒ1©»!DÿÁ¶—¥Ð%@‚T` Prs Ð.4§" uu;ŽwÔó%ž/‘‰DhäÈp§ýÑ–£P % ¾‚ªµI:¦_ÃÖ3¾•¯² D¬u,OPK8‚1`I0bk¡ î-Ótóá,©_Æ 'NÜ:–¾JÑUH]rôÌ,,æ*©*&K² : ©Ö8×7ºÉ{ zcÑcWßÄ[ª¡þÀ¹l~ µ½% I‚V%Šg ìÞ&߯©Ñ[¼þA퇇Ôè{5Iï :w§È.Á1_X¾ïO|ûÕ•ÃZë±_îÏì¸?€eCä§·‰,ŒòÝâ>.ž ¾ûdý«‰mŽfj~í$K±¾\§2é!þÒüÜíÏggrûv>ÔÚÐXoœ|ª5 ñ;}âÂÙ§¸öe•tA0ÅJá2…â8Š‹*>Œ1¥dnqáÎÙ©ë ]ÉššÖ¾®.옻Y··£.Þ<Àl6„Ï%É<‚ßoàUÞRÉ|.›Ÿ¸ðs͵骓ÃÛ?Iþu#MûÎ]Ø¢ìêŸH~ÜÒ…—öå p\–„8<Ï¥o4aëQÔV3Àßž¨8˜?1kIEND®B`‚twinkle-1.4.2/src/gui/images/answer-disabled.png0000644000175000001440000000056210503576707016517 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ3lØ©IDATxœ’-OAEÏn&kq$5‹©"’*ü˜ jj‹©E³/–¤j 5U¤†þD’ !ýH@\ÄLÙîfxÏÜ—9sß›øGD»…S©—QäyÐ 0Ø£-2á«Ö$a°Ø#9M‘‡âí®S2RZ´ÈH™²")gr:çlϹî¹cÅÐÞÚ€5}žyi@Ž9díåPsYô]Ë‘¬æ l€.—5Ÿ1~ÕtxÆ ;¥tZÈ YYõÔ“ ÕBþžŒÇ,W\sÄŒw€Gà†´¼'ïuˆWÞ~ÝO9á¢òÌ€“S¡Ï…œÊ?Q!û‚à˜U=þŽüÛkõ[IEND®B`‚twinkle-1.4.2/src/gui/images/twinkle16.png0000644000175000001440000000123510503576707015275 00000000000000‰PNG  IHDRóÿadIDATxœ‘]HSaÇÿç}ÏÎv<›n.5¶Ô5QÁ*jŒ>ÀI+ ¡RZE!Þt˜âEwöA„eD_&XJb¥¨d©!HRP¸Ds«uvÎÎy»É‹jê¹|žÿó{>þÀ*A)M«ô™VÓ¬õuIgwf,þ§ŸöÜ_;ûõK+/â·'‘D…ÒBÁçÝšä2IZSàŸ‡kù€hjFn>_‰gÄð<É,ñfì&D8ÞÍI¶bxˆ²Þ`08­V«Ýé\g@¸ºR—W²Ël6‰”‹XÕR¥“èr06²<µÃSÔÑ¢ R!Gô˜U#h»C¾›Þ¾¶æm$TÀ¢J S”R&Gܬ©åk=¯³ÁQÖqq’-Î;™Kg±X[^´²–FáÇËÊÖæú:áÊ»©t]Uº3žõ€^ãÞPÐÁ>;Ù¹3R'zd¿±yr4] ‡òXûe[WB@k³xijÔ.ª§þ:-—–u\·L<{’æyÞP³G8éÎâKN„ƒ~±Ñ(+‰ŸòÐÞÓ5D$ IEND®B`‚twinkle-1.4.2/src/gui/images/twinkle24.png0000644000175000001440000000234610503576707015300 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ ;É%wµsIDATHǵ–klTEÇÿsç>fïÞn»,ÝÞ>h·°[–Zí“RKÅÖRBm$ ‰#Ƥ1Q1„HT¢ÆD+’ˆ|à#Ó`0 ‰!AÂCÒJK ›n>v÷÷Þñƒ_ ±vIêù8ó?ó;™sΜîÀEQKŠ”¨@eüVŸÿr÷¼dN+3õ2Š¢èØð¸ã©Õ»”ò ytÎAŸ°´ãAW•ËíÀê•ê§Ó)Í) ¡ZبP)‡åËYP¤‰Ú9ˆ¢¨·¬W $—PÖþ€¼vε¼½±‰åjDsɨ­¦e⟠y[ç-Ê h Äê륀"‹³Výv„¦­[Š·•.–E@ˆ BÐ lr¬×TGBB<’$ydçåéL×ó†aˆ–e%ISºcE=-T³ˆ+ßÃäTzÚ%Ë–Ûɨ×òŠT©ºÉ$b]õ"mf!¯pYº3)cüF©iF,3ž€4$ܼÅùžR—D˶b+ZœË[sUIu°; Nœà01:˜Â=ÝH¢ ‹¼2çà_¸5Íý(ðX `ÒˆLš8²;Õw®?½‘þ9jùõ”ùO­ÕUvU(• PBÁÓ7Ðý᫈'Q³€!˜OàfœíoCqÁ§PÝ&"ƒÃ Ø&Æ®G±ùåä»öN¯› Û—(>¶†ÿ’Ú?xÑð—•Æ^/QÈ4"×¢x»ç3øóeør—` `ZBc P>N°S þqÒxúÙé7÷Z]¦…ÈíIŽö]¶ž>mŽ8¥ôÒÅK$J9˜‹bß¡—£‰Ð ["˜6 RØÖI”W÷!娻3ruç.kÝù>ó+|¦*²B7ù™cÇñýðÕDÍÒZº Ë!½Gª1.ƒ•"ÇÐ8Á¹!ŽÖ{ß…G'xïðéíï‡ÛGÆÒ2ꃉHjð›¼søJ<)縱í¹W ‘3¸2Áqê ÁÑ‹QT.؂ʆ 005.¦Mëú¿ÖùL pW U‘§ÇÕPÙ8}ó×âØñzÄ# ÖN€2áðhóŒ4ÓÆ²Z±Ý“KaY8Täú³ñXél‹Ã&&Ñ@0ªêh©(Ò2Ó´2}*ÿBtHŒý&Îa'Çp²w8ÞóyèFt<Û¾ B4,kÐPmÏxr©Œ¶þ~<‡ÇŒb3ñ±áBþÁv6PæÛrÝrɆ5ìÀ™£3ñóx¼ŽÇ¢eüõÍÚ EQ2¥O¬bÝÑ›:ÇKøµ¾ù|Ózå ÊHÑ?$¬æn±kÿ'ZÜ×y8\Æúv~²X—}³N)•v¼æ8‘ˆèü»¯5ãþzåÅ™´²,»ž‘~î?;Ͻìåm÷±ÎY²$è»ßQ§ÞÚêì úhKvö<òßµ±Nîìù8;ܹÞqhV€ƒI,è6*²â¹“G—U}Ê#·¯ÿ*ƒ¡v#IEND®B`‚twinkle-1.4.2/src/gui/images/mime_text.png0000644000175000001440000000234211001733007015422 00000000000000‰PNG  IHDR szzôbKGDÿÿÿ ½§“ pHYs  šœtIMEÔ ,ß!oIDATxÚ½—ÏoTUÇ?÷ýêL§ÐNÛ±µVB!¤1þ 1¢›º¸0q£aÁÞ…ÿƒ+IŒ ²1˜$³ a#?ŒˆÑˆP dèÏéÌ{}÷½{\ 3tú¦í´*'yy3gÎ{ßïùžsϽ£D„|>/adcƒŽªWíst¼ä¾\ll¸yü¥%¬¥ÒTB¡w£âV1"í)æ}ó¿–¢AƒÏ9©–E†úDàù¡¶ªÁc0FˆAjßÞc#ˆFšÿ¾"¾.kUÆUrÕ £‰'/ÃÆà¤ù—Ä-ö¯H`­f]ÿía¦p’©qŸÁßáeû—læ[†lÊ@÷ R© ôoý”^¿Ì¯Ç2tôKœŽl2¾•X |±©ÛŸ£ú®Á=Jïà˜Clî£2ñ[»ñ"BÇI×£áTÇeˆ;`ò*ˆ×Ï1Sœcö=Éø‡¦µ^DöÊ\ƒéÝUÇü &ýì<ÔTr!Š¢æ}´æúG>Ê»"03m[áÖ=Š¥Nº_iÚ/5ù•Rk'ÈþΪó”öY½Iwô¿¨¦Ùk­QJ­@c6+þ Ð0×w§˜ sôø0oŒ!Š¢:øš ,­§š8‹êžƒàˆJ v›aÆF¹m‰AT“}Ý–±æ¿»¥vp:¡è3åȽýIC|ÇMÁ×D ÑÍÓ—P9 ôNÐSàì±(–ºp:²uÉã8FDš‚¯J æM$"X“'Á‡ù^°20§ðÉ‘}óãºÜµÍf9ðf&aA€ã8ضeYÕlü›X=íB8 ÞvÐ%&Æ#z^¬O¸¥¾¿@¥ "d³±mkeµÔjX³Ô¯`S ³ý`…dжKjïþ¨1†J% R 0摚³³óôôt®c/ÐÓ8Ý €žïi˜‹˜øó]ïíY4f#ÊeŸ…ÝtóÑ:"ðrÙVÕ}ý§µK¥cô@Ø(Í¡¥Í°Û—ÈëæÊ9gí‹åùíVZh6BÚ B„p¨NhÔÕÑ d>JvwwÕçÛÎI»R«F`!A€áXônrÝúZc  -¡>ñ†!¯>wyjY½*¦¾´á ë‚ó/L ÓÕ°)–á!)b˜B7@³šÄ÷§É½iñøÞ/0Uì&î&©ÑÙú²+ŽKK;@ñÎIDQ$@!AH¢ŠÏ±cÞ¤BíÔNŽ…{‡|¯«S;¯-ëØµ c¸Õ6V•‰wÐͪAB–yéÙEÜ¿óŠâË4¤:YÖÐLÂYÊë×1ð¦A{Ǥi!dˆ D)u4]!ðxéÅRåž»Ë}wÞSÙâGµiJ‘›/œöýÉSÅsWžÆuÓi ¤†60*Mó‡Gnb¨¸‘¥õM E&3–4]FfÁ£$Òy¤&Ä” ¬9úr…ŸÞå?¹÷oáOr3Ʂ¬ҔRÞÀHøÜ¾þž£¯:âf9³¨©déšDêA„Ц˜î¸cÇVRÕU´fµ1…ë‚Ô® E?ÆÈÉ1:Úþ…æÄQH¢ ÌÌÛ3]þÜè¸úѦ^¡§êu: ‡\^0ë'ð|ð(†‚З +ˆÀ $ùÂBÊ%SªÌÈ[>»÷oÝÞ<8Ä3@øîÖz_¿–<ƇN¨}Ï ö¿ùzhj¬d“©*©IE˜ŸfûÓ[¨D5è@Ř€ï ßÖ8z\PßËŠžCA}Ï)ï{·N>²m»÷Ñ·Õ³Q„÷¿z§ Œb™ã'Oj‡Â:G÷—,íÒLMè;ÔÂ[ÝH©†PðSÁñqÁà¨Ï†ÕwÑ’å#vð»ßNìÞµ·ø¤ÙÁêü¿ÄR%/Ì ŸÐ_Xœ¡gݧMw ZÓ‡Ž10yЙœ…¡qÅÔä1.jÿ×]ÿ$Òq™ ÷?7³ý߯Už:8œEÖÄÂDËâ #D„4ªè\>É-ú=lÛ1É«#k˜õâ4º\sù£¬^Ó‡æ¸á³ -Œº´vÆçùŒº—‹­mQ“ K(¡ÅL²=îèü5å‰_–|´¤‰¬J"e¡Å€2™ÆµõêjÀJó6P[êº:=DaˆÂªÁÖ1$D‚ˆEˆ¸(¡cX=+õ¸®kçAøìéøÏôʺŒúÌÂ…š.tç¿Ó„yй>0TÚ³óÄäàѼRa‘HM ("¥Âfýåqzºô« ðæ[Îl‡ÑèT›¼s_#D$‰¼O>63ýç§yxrÂêknžúÊ÷oM^X¿„^B“Qd!-“K.dÍ‹G‚`à ZïE2Yc.[dÝ>úZJf©B¡UÍN·ªƒ{S•ï~Ý< ¬×ªÖ®Ôzðn÷ÔÉzUÌw¨|¾[åsYõÄà Æ.]e~öt:§mà k{7ˆ¯Ùë’– A…þ#yîýe鉧÷ù·MϨý¼“ž•±)õüÀ°ôËÁú֦ЫˆÐ K«¿?:rèåÊ3sªÀ²f³ç¡ûœWË…zuj ­~~›}ì’ûœádYzçE+µvmwgNôg¢±Áõã[b¯Æœ*ÐÕ!.»ò óz×’î_Þú°óѱ=Â÷Å黆ÑÄÈ(N «Ò©‘°uÕ =53$wÿ%ÚEÑøÙl€õ«¯Þ~‹Ý¿¼S¿è8ë…ïEݵ—Ùºó[ñ!Ó0{ç´raÖÒ¾H~¶ì$óüxdRvSW«q­k»u4þQéÒ«ÄaIEND®B`‚twinkle-1.4.2/src/gui/images/encrypted.png0000644000175000001440000000126510503576707015451 00000000000000‰PNG  IHDRóÿa|IDAT8}ÑOHÓaÇñ·û?]nÃ?KK$ J!¨Œ ¡ ëîQˆÎuèÔá%ì²›^‚ (ÂC§½Aôú…´‡ß,ø2#󽙑!·pþ»ä·~â©æý×û>Å_‚а–œð‡[ÓVüüxäT$t,•E<$o4ÿБˆ µÇ¢aõ§Rõ•wV ¡>¾ÿù  q#5ye¢½§N£Í@ (ã„*¹žk^mjÀ¢¥æ RäÄá’Àú,ñ£i¼ÁAÑÁ(«ÐN;P©Âþ1†äpPt@©â`U4ð‹?õ®– ŠG*VÕC©Ò8 ÔÀÓ¶¦] š6èT 0l0,н®ï~#†]“ôßE† ¦U ›v#lZ 7.ê 7Š\  «ï›6Bxÿr oe¹Í<…íÔnâÀÿæŠî‘À/ݹ[è¿ú÷ÕIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-0.png0000644000175000001440000000034310503576707014537 00000000000000‰PNG  IHDR"":G ªIDATX…íÓ1jBA†Ñƒ¶6¦p n@‘ì EÊtb%VÁíØ»„ôYÁ+’„Ä Š•(ˆiÞ+œ×M`$pOùþf!„Z^ñƒ¾0¿GÄ Ž˜aXGœñT:ä«d[ã-÷ÁNæÝU²U— é¢C²ï0(Ò¸þá¶%'ä‚=zÉþ€mÉøÀc²Mð™’«ù¾S·ß÷¹t,±©¾±¸GD!„ðïüŠ‚ÐRIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-1.png0000644000175000001440000000023310503576707014536 00000000000000‰PNG  IHDR"":G ÂbIDATX…íα €0@Ñ8€ KG²\Çmœ@ Q+O0ÊÈ—|$é¤`úèce`wŠ~¾WvÐå2s!2äè!-Ðl÷´ÍU°ç–åâŒo„H’ô)+“H öÿ bIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-2.png0000644000175000001440000000075710503576707014552 00000000000000‰PNG  IHDR"":G ¶IDATX…íÖOˆMaÇñ‹Ù ‘ØH³˜˜YÈ¿fVlgò'RرD̆¬FM½k‹Ù;S#”¢& BQXФ 3×ây§¹®™¹ç\ÝÔùÖÛ©óœ÷w~çyŸ÷„8„Í8ŽyŒÔ²{ÓËw×Éë€h„kEŽdâuWa¡¥éÄ‘òIczšÝx‚—âë{xg]6á7®ŠB<€ûâ gÅ«¢€wŠb¼€ŸævÖ0Þ‹ŒvˆzºÛ¨8%ª~ Oq¦Ž‘1|J¦Çq°f~®‹³Ë/±}¯ä1RRòî]ZdqÍìIEND®B`‚twinkle-1.4.2/src/gui/images/print0000644000175000001440000000130510503576707014020 00000000000000‰PNG  IHDRÄ´l;ŒIDATxœ•¯{Û0†ßì 81›Å0°a5 ,ôXËZ¸?a£c£…ëØ Ö° ÚÌbw,²ç׳Š(–.ï}ºï,OʲäÒhÛv/"¤iz´nf¨*!’$Á97ÇM/R!Ïótº7€÷þ,æ* ªª3Øi"UÅ9÷yð%€™%èçSø—+ܽ™ ÁÎ9œsGõîë/"gõ½ªXUI’„¶m‘Á¨ñ¸tüÏ(ÆÌÎ:b í“]2÷ªâ^Í%¥ãuU=êÿ‚ëºf>Ÿ“eÙUxoäv»%„°IȲt¨õXU÷Þ{ª]…‚ˆ €Ó¹WÚÖ-eYÒ„†›››}Q¤i:™ôožªî«Êê5€ËJœ¤|íyßÑ45ªÆb1gµZEŽÒâî—¦¨˜rf‹ ”lyã/K[²üÈ©ª¨á€÷~é3Ómxøú@2K®ªìGEÅO~àñìØñ"/þž—ö™ºFã=ÓОžî¯º{:RRîXR"ÜÞÞ’HFk5Ï/¿ !ÎR¦x_Ç~4bŽ˜H.VÜÄñ;s'³Œ˜‘fYÜïÜ™¶u‰õ4cðÍAt±;‰3PâšÞŒx‡øª=Ë9œ³ë¦õzMžç€á•®ëzÿúº¡é¾_Šv¦œ9|5@µ¿ƒ‘/sY,Ã%ô|°RdÑIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-3.png0000644000175000001440000000076010503576707014545 00000000000000‰PNG  IHDR"":G ·IDATX…íÖOˆMaÇñ3ÃJþÄMjäO ™ËY°"e¥ÙM6vV6ÊBÝ’²"Y ,„ …£)Qš$ .]‹ç=¹î¿qÏ=æZœoN½¿÷<ï¯ç}Þ÷<””ü;Vâ2fPÅn`,O°Å=Y…Ÿ˜ÂvL`×zˆY“øÜ¯Å±ñgúed µô\À@ž ½ÔHÆLг^ÔÈÍböÌ.‘™ Ý~XDFêNïÇíÈ*؇M8€W¸·&`·ñAdàÎcùB))ùï©áPó·â1¾àS»IE_h­¸„iÑ¿¬ë§‘qÜwÍ÷¼A†pN¤ô+îúskpoÓ"ϰ¿îû×~ÿ™k¸’×H%-2-8Ú`¤‚çØ+º´«¢F’>šæŸíÂê<&–á7ŒgFVˆ,ì®ÓÖ$}²aþ±ùì íÀâºÈRÆ_kIÉ|ü 7XÅ„k~IEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-4.png0000644000175000001440000000064410503576707014547 00000000000000‰PNG  IHDR"":G ÂkIDATX…í×O+mQÇñ¡ˆ Ô5Qº™H¦$¥P^†‘{Ë+0ô¤n÷Ü2 f201 üI1!¢Î¬58v±÷9αö¯VOûyö~Öw¯ý¬?›B…¾‘šð¥¼A¶p7Ȱ”'ÈNÑÙ¼@¦px HŸPãh‹m!‚´¡ù«@Æb§ïµõ¯iFo¢­Fˆ^tT›´R½â*á»6éϬÆj,T¨P•* Ëû§Uïé›´ÞûB?n²Ü˜6"M؈ɞq„oßrñˆK,—Åñ3 Hš6qŽi aÅÛá.Åø2ñ /ž·˜ø,D'ž0—ð'AÊã]Ñ7S)ÈGŸf­ØKÉQ~ º‹¶=KçYAZ¢}©4i5úä,Úá¼AÎñ¿1*Tÿv °(ì>vqýÏõʪ¡8Ô:qCJ|R˜’Ç }MX-Çj ’¦y¡V^…séŽð;QsýNK̯£ØIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-5.png0000644000175000001440000000061110503576707014542 00000000000000‰PNG  IHDR"":G ÂPIDATX…íÖ½+…QÀñO˜,L( ³É¢”·…$‹È$ÉBв²Èd2ü ²*eTv)¥ÄrË;yÎU—.=/÷%ºß:Ãóœç÷;ßÎ9Ï9?*Tøç â=OË$MX“R¨ ÷9Ïoå9ÇmÊiÆ.ñ˜^'>ß÷È vÐTj‘:a6jP‹nœ`·Ô"ù˜ÂCÒàªÂyhÀuÒछug8Àº°ŒÕ¤"I™ÅaVâG˜+µD… ŽwŒ¥èÿBÜ-Vò8Ä=ÐZqU ‘¨3²"ÌÆ:~øf7èL¯õ3õhî’¾ì»Üeš ¤Þœ˜XËui2Ùöš§o›Å~Ô¿“ööíÁ6æ±—&QZ‘IœbF(Ê&²ˆ~4b Õå¹ ç!¡&Ù(—È'ÇÁ4– ”óWŠvNDù}Û…Jl@ØGʼnšP^`¼Xƒ|ùCdu…ŽIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-6.png0000644000175000001440000000073210503576707014547 00000000000000‰PNG  IHDR"":G ¡IDATX…í×ÏKQÆñvB‚¶!\7B»¶r§iÜEÔ"D„-„(p'm¢hÙFZ.Ú*.ê(jQ‘ÖBà 2L(üQY·Å9ÇAQïè¸h¾0œ™çðž÷afμïPPðŸp·ðËXEk= •2˜hÀd43Œ÷hÆ— kÖÅu<ÑýX¬!Cì–ð ¿ð Ñ”ÝÖÞXÆ8:…÷¢óxœ§‰ª¸Òû„»sl¯ ÖûhÖ…Ò’ÒçЈy×èJiíXŒGnôâ/n£Œ 0”§‰W1ߘÅÃ0QPPP°UÜÅS¬àú… ûkø(TÚtÌ“óYhj”pO¨Ì?ñWvcd>&/ãPàfp mÃWÝ]-f ÆÜ¾´§ãühÂ|7ã|e'#—×g¢Ö™ÐÎE­u›˜“Qëªó:.¦òŒâeRتúVç?â˜l¿Çñø61K‰ùö»))^àìNF…ƒ62…?èHéçñ6)dùØ ‹x„‘hèºqMjç´Ä¡Ã?Íôc"‡ÜÙùétYáÊ:TƒIEND®B`‚twinkle-1.4.2/src/gui/images/contexthelp.png0000644000175000001440000000143710503576707016012 00000000000000‰PNG  IHDRVÎŽWæIDAT8’_h“WÆßw¾$MÒBëŸ ±½‘Á°V¯+»‘m'  "l¥ æe½JzÕ -´"ôÂ{á†P·uU(M>‹½hÑ•¹­£8†ZeZm:M›¶iÓ4ù’wö“Zô—÷æ=¿ó<ç=†ˆð6Õg÷îDýûsG*,§êq*0ñû³m±\Ë¥ŸqŒ·j³»þ½¹¿<`}´÷ƒ ª+MR ƒw¦åìP]4»Ê9¹êqˆF£""Äãñˆ°¾v~+î?¹|#_‘Çÿ•¤àe9'""òhFäTìŸ%¾È}."˜mmmw†††>[ïÆ£$²·nñpuUAo‘É“Ë#E’s>ðTÖ«üÆWÀ+PGGǾï‹Å¢²m[» ¿§xHyƒÖä ܺ§¸:&,dVú„‘¿ÆŸúðûÔ× €X,¶uxxø1lÛ˜&5é¬br~ù ¦góDz¸?mpåNžœcaªú ×륫««rllì'Á¶íÐÒª•~6 µ™œÁ®í‚‡Þ›Â|.€¥ ï°ðÈU{{{`|||@DØSó ™Y‘‚¥À4 •1¹5Qàå’‡ /8N‰t¦p{S@4õ%“ÉkŸìúw„ÕÔ„_­ðÁÎ-B}-ì¨1xáyj5K>u©, ¹¹YÕ˜ÏÏÛóçw§2OüÌ"ÊÏlÖGÀÊ2•L39µx¸ `m¤¿¿¿8‘Hd þè:3ÒøñÝG GMƒàì’qïE:¡T*õÉõŽC\uvvº½ÇC›}Òrõ:Z(šM´¶¶===‰„ÞÌõF™k¿€¯¦ÞÞÞE€†††mk3ƺËTYÒF‹---EDÇ­õÜZDýÎÑ\uwwÓ××÷D)EcccõFWïìHkíojj:ç.@k½ì>¼ÖÚ(çÈ=l¬ï"B8þ5ç‰Ä§îö´Öªèõi¡« ÊIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-7.png0000644000175000001440000000074110503576707014550 00000000000000‰PNG  IHDR"":G ¨IDATX…í×»kQÅá/š Ñ2˜ZÐ@* j¾š ;Al,´Ò€•h¥Ä"i Á"þŠ•HÐB Ô€¢‚`°R‹àû‘kq6x½™;“‡dçSÌÞ³ö¬9çk¨¨øø‚Z“kÑ´.ÃÈf´4ÔŽàÔ2fþÖa§Ë6r¯°¦L˜•¶¦T.ã¡ùgfEÙ‚ïØS¦ ¸Ûe›èŶ–i¢“-ÓDEEEE3j¸„›ø€÷Æêè·Æý[)¡ÝÇG Ôé/â>áAÔwâ^hf1íEFžã˜”À…ðLôGðû¢44õFžb7Ú°bÆ0ºÂÀ…Ðæh¨ aíñE‡s4Yú®¨oË{ñª¼fð›Ð-¥¯» ÐÔó ã“¶ü<Ïçýþà%8¤ƒ "`uöb€Mk•g¥Ô´Ò§×zIMPÈpÂuy}ÇýxŸwDXF¡H˜þšgêÓJÿf 1¸¡ã¡`SÇÝË>\<ÅÁëáFÅÆ§¯:†Çv±²¾óÃͲ7>¼¸:^$ç%:“ˆG:]Ñèæ› fáeRErz;/Ë]÷¿ÿqÚC¡`sǽKFgµj ·Ë ˜Xü§]ïñb#g5}YÕ‡dY~H3"81{çJØ×yŒ¢ÿ¬¿jNΪàÐÞ¥T¬oëPÞª»Á_c]<€n—(ùün†\Ár´œ+˜uc<ó@3ü  ¶¤•£=<€X@¢Èi&8Bj•:@©Ü ‚Bù€”‡Í<ï¼YŠÀ#Tð¸BÈÁö lÊÖjQ·‘Î7×½zE¨ sØ7 ¸,=CyVJ1£P¤ ôP†£ÜƒÈ3Xûê^€¥çè´Ò§¦S#‹6¯æ0Ç[TÄ[T‡ÖîÓ@,37ä7¶œ““~&4¥ÎÇ›£Ÿë¿ü,–1µ”ËDŒÑ›!n-UÝÚy$ZZߟ‰ùNv¶I 5±méÍ]̯¨™peòA˜,O*Š¢9\½÷_µê‰!çÈ­öK:Úxp²BÉÀz¶¼gèêHÈœzâÖEÑ€šß²,»¾™§#í!”Ø”Xz&ÀÒsA~c @^Q”ò_ÿod“û›Ž‚‘IEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-8.png0000644000175000001440000000071710503576707014554 00000000000000‰PNG  IHDR"":G –IDATX…í×ÍK•AÇñO/ѵrŠm¤÷¶ŠÜD!„ˆÐ¦2h妿 ÿ!Ü馂6ÐB Â*-‚ … FAo„X¥äâÌ…Ûír¦’糘3ÏÌùΙg8g¨Ti‡«†xø€ t–™Æ"ÎáÎã9•ù†Ñ&Ûe|- 2‹%œl°ÝÁÝÒ ñ?Å‘ÌarÜ9ïöã(ÆðÊÉQ k8Ûd·(K9©a_jz#ެ¨æÄîGЋ3xŠñÒ ‡1‰XѸŽ=¥A*Uúçt‚È%#%åæš¢z+"RoëÉÞ*JuÛU¬ú= Oá^.HWr0&²lÏ€Ôð—Æ:E!5ØÎY»£©gÒO":ï¶"OS~­Þ.`sAruSÔ&Ý©?ŠÛØ( ò¯Äñô¢?ÁµÕÞ-Æ7Z|³†C ý]-æÝÂQÅ-$°mi ÷Å“áT²Í‹zµ§Å¢ù>"nÙ*.nBrô2-ú:ÙNà¾cYì¼ÕMz€Ï"*•þ_m€dUÝD¤±êIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-9.png0000644000175000001440000000116310503576707014551 00000000000000‰PNG  IHDR"":G Â:IDATX…í×_hÎQðÏf" a°–²Ò”)"v±…’KÊ…ÜHváÏv3EseîŒÈ…«åb-RSÌÅ„¤±ˆÜHíÆ¿åßüÝÖ\œó¶³Ÿ÷ÆÊ» ï·~½ç<Ïù=Ï÷yÎs~çy)¢ˆÿÓÐ†×ø…ÇØ>Dº¢óFÔ`?~`s!ITb3ò3èˆÁÒ ™?eä÷°f‚6'„©xƒnT -Å) ’Ôá‘°E£xÛxWh"9Ìj¦í¸1YDrXŒØ]hÇ‹°V8º»0€Ë()4‘õø‰¯B­”B“(¢ˆ"ŠH1Œò8.Å[4'ú¸Çë„nì@¢¯nâc؃AÌÌø¸‚Kq|IJœ`«p}¯À‹(;Éí5VùˆŒ`[}¿î-1yý*|ÃŽTX#ëÀé([ t_„({„+¿UèÈ*3kšbpWq1£›%lU{žôÅèÙƒ(kȬm²1e¸/d-mÊñEØ¢úÌû]‘H±¢­Î)Û„ž35ÖâÏú¨Žoúße¹p$gvâiFV.ÿÑõP†WB­M*v Yš=ÙDîàÂ߼𱃭ŠvIEND®B`‚twinkle-1.4.2/src/gui/images/yast_babelfish.png0000644000175000001440000000420110503576707016424 00000000000000‰PNG  IHDR szzôHIDATxœÅ—Yl\gÇwî2ãÙÇŽ¯ñÄ qJš&Qš&]hIBÚ´A¥ ñPªª Zª¼€B¨$ÊSûB¢]P ª(]1uÛ¤-Jˆg±‹›Äiâ$ÎÄöŒg<û̽wîÂýNc'…¤·IÀ/@œÑ[%.±Eàþmr]{Â#là=à @Ôs1àÕšüø‰(e0ÍÜ;@¥Åþ©îÑš:Ó†mTˆëW¾HòÜ ü}Þ6d)’vy\µÅþ†:w· žÞdÀ¬y§«Í@ø.nšUí<¦Y>ŒE ˜óÎöëâJ¬å±R⸷–ÂÌãü{õRW%BQR¶H²üË4¼’$!Š&J ¬Ê±¶j°½³ÅWߨªåæ&üÍí7Ê¡ÆÛ¢+Ö?ÑÔ»v[s[é3ÿÂ2k0LçÜ, ü7ð­[·z¥@ôσCï •¥--4wÄ 5uà[v±ŽV²ÅBuìÐÁ=JSçšâL®Ó‹²º·—nQä×O¾¤¹Ý{}ßrúV^G4Æòˆ\(™¶@©fòQªJ"] ž¢;ìe×Ö5,õšlܰžT*yiXG¯»>Sr¸q[ÝŠM¿Ÿòw-Û¼=κ¾.bÑÙš‡DÙ`"§q&¯cÙ`h¹¹F±È×nèdûê8=T8öâÙ®Èìóz9§iNíu÷Œ­—ˆÇã(²rgI‰>wËö{Û¾²ùv®o ’Èå8?=Çù2œÓ˜Ìëh†UÓñ¨Ubb-½ <|ó e˜}¥Ÿä«¯ê¦¦"š¾üGßeü~ÿ½=}ÏÖÇ{Úv~}+K=6ãç™Is|:O®d¡Û –/ŒâñàÕ*´(îÛÐÅŽ» (¹R»ws&“ɼ‘Éü®dYÓ|ª~çú–€ÂbÙlö7ׯ^Õ~÷=÷P/›|øAþöቪAI¬ÃƒÈ¡Fb6þ`e>‰{oZÎ]ë»ñb‘ß³‡ÄóÏ“L&y-“éwÁ§Œ nš{Œ¼^ïC+W®\¾jÕ©é:ýoöóÖÛœ:3I>_Dô7ÐŽqc—ú¦b«×³íþͬYµ ŸmR"³{7êÙ³ ‹'GËåC8="å0û’³ uȲ|<—#‘ããã¼ùÆ|`ûl=s)˜žÆGðÅSx–ŒS BVÔ8P(«T¸J_üØ<‰3 çѧ°l›VŸÂ—ü ¹±£TS³t„Büü©§¸kçNþ¹? È~/{¸ßïC°lˆ”¨ëœÂR*Lê*ý§µj*÷qÖ4z€Í8´Øœp ,˜šÀMÑȃ··65<¶¼™9¯È#“­Ýô¬YÀ³Ï=‡ |×.~öú+Ü!H4}x{ý–©‹NÖʼœÊ×i†ýà%ñ-·îïà >ÛÕƒ½€@_CÃÚÞ¾.¹im7í’Íl:KB³Èçó¨ªÊÓO? ŒŸ: ––…Ü*ºÃFRtöh¼ü¾†ªÚ,²ðp§®˜¢¦¡çËÌ}2‹Rb…`ôÔo à¯ó«‘Íåxó/°Ó祩SÆ¿¹‚·­‚`¦)‘H—ÆUãÀà<0ƒÓ Ê— ð"µf «5ò§Ï#Ó‘ªe6bòúK/òÂô4J} íä'4fS_ÐŽ* &‚b1•6IÎYT«nzG½îç,’87â²^ hÔ¸PÊЉ`i*5Ý ±.À#>›wþþ.ÇËyîi­ç†õ!|_ªXoੳ1LÁ>檆«¯¯L™{a43tr8ý`AíÈvV©Ü‘bI‡‰~BÂLHX$‰Â!ì¥A|-5ÄN¥ÝDô è¦ÀÙ 0<¢rt¤ø§™¤±H»uκÀeØZ ¼€ÀøYí¥´¬~UX] ÅVKØ9[°=6‚lŸ…©˜¢…é(–=L§mö k<\MC¦iϸ©N_ 𼉕ª5z6Z¢Ý3[5 jb„5*Þ %Ù&oªÉ9“TVàÜ4ìVyûýÂèÁCÅßjº}gâMó©Ò/K÷•ìâJVWçYÑÒ,£·×÷xëRiiKsI’©T LÓ ¦×(4B!‰RÙROM¨Ç-=£jÖŽÊ/°h;¾&n6BŠ"Ü'Ëò“›·lm¹íÖÛ…"âàЧÇõž.ÿètRß;—­Z³8×kGt×¾˜8šð·´´´îˆF#B"‘¨‹Å~Ub¡Ê3857øv¥­Øƒó‚iÃy„†]bó@UœöšÃÙñ®Jl×B`þ{/Λ/„ó.´\À2Î:õ?ÏÛ¿†ºLup‹ŒIEND®B`‚twinkle-1.4.2/src/gui/images/twinkle48.png0000644000175000001440000000660510503576707015310 00000000000000‰PNG  IHDR00Wù‡ LIDATxœµ™y¬]WuÆkï3ÝéͳgûåyŒCœÁ™€˜&’Ð0$„„Z„J[©”6ÐÒMK Q…R !1©%P gÄN0±c'ØNüìx~Ïo¸ã9ûìÕ?ž%R Ä&×Kºÿó}ë»{íµ×ZÛrzÍÄq¼RD ÞûY@ÛM`Û ør‹ãxtÑ<ùN©ÈØl•ÇTµÖnÓnÀ—YìœûÀ‡Þ¬~Ã%örDžF®ö›1fÃ5—G/NŽ/Ö/}¡W—-¶Ÿ>-<§´T*E墹ðm×$ƒA)áœó„¾>®ä4„ìiÐl6‡/X+—­^'Æ–,‹8c©Y ¬i7×i°`0:ëÍ—Î]±ºƒ Šˆâ„÷^_±•ki'×iÐÓáÞ½j¥©Å‡1ëÎ[l7”Ëåîvr æqå9ëbÔ†xMQ ¥Ž€Ë6£õZýüv’µ[€$Iòî÷]• ý!ª€ Šcy㛊Ãýý\ÛEØVƘ¾á¾ü¯û£l!¦âA c£b7\¿ÖZ;¯mœí0Æœûæ70w‡'#D@LÊà°2º”5I¤ËÛÆÙ6 cÊ=ù•oùc;"aƃÌ*EÔÄ„EËù熅ËÂËÚÆÛ6 k.½ 8kñÒP°b* JÄ 1*Ë—âÄ]1÷° ¼í(„ù™££æÌÁ‘1áÜO¤H€˜Ä04b[j–Ó¦C­mÖ¬JÞ~ÑťΤ«c+ŒÄ'N­0ˆ Š1ï½®` Iøžvð·KÀÒ•£Å gŸ×‡E0J†÷EPZ@1!&ôœy~È‹¸|µÄÁ«ü¾ ‹"ûóÖwÄ㨂PB)!XP’bL†HD©Çpõ5«öÜ6s»óöñV«Õ°ÖÎzï[Ƙ,ïœK½÷ÕŽŽŽZwwOæ}nJ¥r¶gÏnšÍæ80x)Š+‹qsÁ@—±…ˆ(–Rê|eÙÂ~5š•÷œž?M7=>ôvé×®ÜP|ÍÒÅVº; ¥2˜ÈÐUV*‰!uzº qìˆÃ¥‚!Š $Lb⟣ Ïô¾œññy<º„\º(« tïbÙòã„ýŠMBÂBÎÀޱ#€zr—’;‡æñ9"ŠØ11ª9hÄôö«w4ƒg~eó V϶›À¬¹úê(ZЋ s‚Bq.k Ñͨ¯ñˆ PI€Eñ¸trì{rˆ¯<òçÏ."Žûè,'”ã”îCGÙþ«¯páy_gh¬NÔYDLˆÊžÁ6lX˜+Cps*Ô§ä Ãm·7Ü]÷´¾}d"ºÉ:o°ykëðs;š£g,É{ûGŠ&!&´ˆËbÁ&H`À–[FŒED©Óœ˜åþ—ñ…‡¾ˆ”¯`¨eƒeΜ± ;¡«ÜËtv)m9‡Šü’þáC”Adn+Š"ÈÜžaî±µ‚‘¡AÚhð̧ýhcâöÿt%7NOO±Þ{§Êö_2›·ý2Ÿ¹êâ% ½IJȘ$Tt.%J„‘"B€ŠCh›dû¦…|éþO`ËkYÐ+ô•ŠÒWô#Olå~ºõ™üo›)Oü³¼\iæ&¦ªzß–íùîL×ö—ZCƒÎÄaÈBÄp"“XT¡Y‹™]†Oü÷íÄñ=e¨å*‰bã9#X“õñƒkGï#®b (1hŠj yßœæé- ýûgÇ>óoî[ëõ¹çÀ¿ÜçßÕd;`ëá ýÅS¿Ô®ãÇòEc£UÊ ,ÆH ÐÑ7dà2\½ÁæGùxºõ'ê'[)·ßuý¿™W6íÞçwÝqwvݳÏû›?ü!_\ÿZƒ±¦‚¢ZG½¡ž…xb2Í4R¨Ö¡`!¶ ^$·‚C˜iÓ5C#-Q«wkQâP_göXÀ÷¿“r÷·øé#Oø¿žûu:úmû}cf›)ÿêÿßýÌõצݼ±¥­¸P2ÛòlwÔñ͇߃±ˆžØ-Nðb#š&j†}G {Yk/—œsóY=dÿŽ€›?~|âÖ/6¿´sOö—ðÛ!s*^n§fuÓs;ƒcã{³ Ê%Iæ&ïff“M¯æPcí\.Pi&¸f[ÂLS8:-ŒŽ‡á®‡¹äÂï“t—É›]üâá”Û>?½÷ÎïÎÞ¨Þ97y2ŽÊ i¶ÚpO=¿[wnÞ’-[ÔŸ®°‚q˜(Å«óÄžKÉ|bÀ x…j:6µ†plVØw¦fk\}Á‡9ãìIú8~4æŽ;öM|scõ#žàžf³ù;ãýÕ ÈÓS3öØèˆÝpÁ¥IÙ„k…¡þ½TÔØ~à,ÔV04š0݀ó°ÿ¨gvú¯_ö\û®˜R$øæ,>r¼ºéÉÆmiæÆOÅ¡?dÔ'•ÂÅï»Á^¹â¬86¶„ …BƒÑÁçñÕãì|iŒZZ!Í õLÕ”Ùª§ìŸæòµ·òö·ÞKy8ÀDb”@2^ÜåJ{_àþ£ÇÝöSqæ”ËikmÔYhŒõôEÕHcL¹È‚•5>ØùUV>˦m—°ãȹdY‘A»UCϲáµ?blÝ*ƒ1& “#(6²¬ )•ª€oœ^Æ ¬{?kp¢.Cƒ*j Å t/v\ýÞ-¼yj3ÕÃmæ„`z ˜B&ìD$B¬‚TQ5ØÀ³|”¹Š¹&ë÷fžW% »#\°r¹®êï3` ^SÈåÄI€ÄHb±B¥[Q×B 6AL€  ‚4PI鲬Znæ=ü£Àó'ëÏ)·”å¤yá‚?\,s5ŒZTïê ¨/“k/+H2ˆ‰†ªS¨¶ð:‹j†‘P@D1‘á ¯Ãà-§âÏ)¯@_/²n­±60ˆAT[è$hFžÁÁñŒ#,óæÇtw`C‡2(ªs+h(¢Zǘ&W\Qfá[àX˜4æéPìêbÝ¢e¬A$B¥5Wi:wMZ³MÈó{ÍÎÇ˻ÏX|èu×¾½V9s}´À4Aꈔ@RðqÅrÁÙÙÚold5°åd:Õ4úŽ÷¿3¾îâ Lè”"ƒø"ê¾Þ俾ÖÈþù¶lÓ£›³¿Ùµ¯yçžó]?{¬¶|å°ë°`ÁÖ„¨:PZLi•ÿçþÖUžà$n5OZÀððHhµñ·Ý¯,0aˆ  ñÎ’V«<·uZ?ûéÚäÇþ5ûÜÁ£þ¯Z©ßá\>[mäO:ê¿÷À¦ÖY~¦5¸pćÌu{âð>ÆkŽø”К`ç¶´vx2zÀ9÷Š·š'-À3ö¦×˜?}ç vÐT sµ±X$w¸ú ›~\Ó[nmlûþþ–Ìñ9à7ɧgëúàæí¾þÒ–-ñC}Æd(9¹P%1ŽçvfÝ?ßÚü÷¼Ô6Y–½î†k¹nýå¥r'ˆð-²™Yîÿ^“›>ëî{úYýëzÓÿ—uL¿)"Íøùîuó3Ûò‹*ï]¶Ø&MTÀkH¦Øï“ý{ÍwMd»NÖ¿W23¿7ºqãÝ…¬Uï×F}¡Ö¦ô‘ûŠþƒ7ÄûçnâSr¡Pè‹"{Ë[¯öÿü¢NîÖúìBmN/Ò‡6véú³ ßl—óXk{®XÝõÔOK¾ÕÒ™ƒýú£{Êzñ:ûl! ®¢Âzã’ˆÈUžcŸø÷OÅéø³½ÚœÖ#»;õW%‡€¶‘U×_l{îÉnÐÿø§¢ž·Ú>dÅœÝÙÙójÇ“X+«–,nyÇ[’‰èìKÝú/-ú0 ¯m‡ÿ{þŸ½+:öƒ»KºáÂ`7p#ÐÛðÿkç._>õåOu4îüdEƒ øÜ+}pR›8 C[Íçýä¡lïÖáM.w_ª¯ÚÝß¶VüèSÛ|}×Þ,Ÿ˜J¾•féŽv[æFáCí; +‹Èb ôJ/þ/àÒšÕßXIEND®B`‚twinkle-1.4.2/src/gui/images/penguin-small.png0000644000175000001440000000170410503576707016225 00000000000000‰PNG  IHDRóÿagAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<VIDATxÚbd@ŒŒŒÌ:::ibbb‰lllÊ¿~ýbxüøñëGmüñãÇ ’ÇÈêˆM3Ÿ³³óÒ ð÷÷—fggç|úô)§¨¨¨Ÿõ›7oÜþüùs¨ô)L@¡ 55µùK–,ù>ü?cÆŒÿ@üòäÉÿŒŒÌÿ@e·X¦ €˜ô»ËÊÊ&HJJ‚9ß¿ÿeX´h=Û·?xĤ¥¥ÂãXXXT€Ò@Ì R@,HDÿýû—áܹs FF– ß¾ß`°wØÇÀñƒáÿ u µ «V¯e©‚ …ÇE€‚iæâÿ]]]ÿ¯_¿ýÿ«×Wþÿÿ§ýÿÿ †ÿ¿ïþ¿c×±ÿ|ü /ü† ˆNi ˜7¦ƒ$@8''çÿׯ_ ðãêÿoÏVüÿä~üøíÿ”)3þóððþÒ<§êedÀ ˜fÿwîÜâÏŸÿÿ¿ÿø÷ÿ³g¯ÿß½ûôÿƒ/ÿÇÆ&þÿ¯®®2è@1A]pˆ„……1(++3õ2üøñ‹áË—O _?¿eøúõ;ýáýûO ®®> À(¥#ß¾}»@ ͹@2ÄÉÉ ?¾ƒ5Bð†oß¾ øÈ ""É ((ò¨y0aUÈ€Ÿ &¢%²²r@Û04ÃØß¾ ú b_ê¹ ÄŸž€Î^´lÙº½ï?ücøú™áóW ý ¨øçO¿>~üÇðå+3Öm;?^½ze5PËM>€‚§VVFÑS§fݼyƒÃYAJŠáÓWa†ï?T¾ƒÜÇø”AHä>ÃO·^?^üIïÏ`p|é 33==–övö“ÿÿ[üÿÿÍèÿÿÇ,ÿÿeüxnêÿõ›fg ÄNÿÿ¿‘üÿÿ*Ãÿ£í ÿÙ˜âAúA¾ÿßßúúþ¶µù» Ë%# ÿ üìþÒÍö§Æ¢Òì­âÎÅî36&!üÿáÖþ·Æçûþˆ-gšEŽ,@üÈÏpˆAе™¸ÿþ§™7@|”+ ØÜ«l_}þ0IEND®B`‚twinkle-1.4.2/src/gui/images/message.png0000644000175000001440000000076010640017223015060 00000000000000‰PNG  IHDRóÿa·IDAT8Å’ÏjSAÆI'¹÷6m¤RC‰¦vSE’UW>Fè{ø>‚o ..Ô­±.qÑ‚üSS¤¦Þ4™™s縸 Ò•ø80ó}çÌùæÀÿŽÂÖÖƒ§N£â}ˆ³L !G–ñGžÜ«èv¿ì™V«vssó++Kgîj­çè(%„p½E1I³¿x&ñhäè÷$ILÅUˆ¢2ËËUvv>reý""3f-€³–ƒƒ¯¬­Õñ>CŠª  q±ºzžîËwˆ@šþ†! ¾ØÝýD³Yg¢Q…b ^ N.7/ðâù[8>§Ç)½7ïÙØhàO¹"³N@|ŽÊüW¯Õyòø5å2 Ó¯¶÷h·×)üä9,€;†Pú5o¥rŽí÷ï=£V‹éÜicmaÊïóWçàäJ¥iÓ*KܺÝb±ºÈh4-žpÌØÂ÷!3Ãù¹*épöwŠÀØ‚éõú¡¹ý¡X2† ùÖi€ “œ›¥A§Îz½C1óñç¹GûXð^±6CD±VqNñ>‡sÎ)ΜïÞßýËÊý«øðʵ.]ñIEND®B`‚twinkle-1.4.2/src/gui/images/sys_idle_dis.png0000644000175000001440000000132210503576707016120 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ % eŽ;cIDAT8Ë”KH”QÇßc¾y8>¦tÊÇø™Ä|+(I "³h‘‹VJE´)\Ô* k-Í ZHÕ"¢×" Ì(#Äñ…(fš‰ŽŽŒ:ãmÂä|‹9«{Ϲ¿Ã¹ÿsî]3ZÒ/Êñ[ÞùÛ¡Ô½ˆ¬çTÍÍgî“q®ªc¥É>‘`ˆ(>W @µG®ˆ PuÇ Èä›êOÅôV§ÉHX9Ô×j|ûQ)sk1J){ëQë.\ÏU%R¥O–Å_’Ý`'9ÍäLXW#!©¼«"Ý’äж’ 6³M±: •l²@)ló‡-‚l"#X=~5¬iª³˜Á ïÑp2‡R2 x4âoS>|ÚÂHd‘ÁAqŽZÓ ÙÕdDB¢£wq…0™rмº³dj¨µÉVé¿Ör«ºóÙhd …zŸQï¹6ÞSâ£hí3eüËPØÑµ1*ÆÅÃ3;æ¸b¸:0!¬W^Žöjž3ïÞî ŠÚöÀàì\¹4âjH–ö$²”µß]=ý*0™\mš]ÿI-ÍnÙ]ÿW·¹´ê1ZIEND®B`‚twinkle-1.4.2/src/gui/images/editcut0000644000175000001440000000032610503576707014327 00000000000000‰PNG  IHDRÄ´l;IDATxœÍÔA€ ÀÖøªžy6çýžš ", Ñ^L4í¦Aȵµ>šYyOÃ+õ˜‰‚k]‚` öò®ÙDD”Ùãd§øv+¼Ë‘ÌÉŒcÊŸÀŽy·f11t€p íá·p -háU¸‡2øfÑ^ í1“í\Vkº}ôç¼ëVdÕ»"w6oêš©»%a­¥q©3IEND®B`‚twinkle-1.4.2/src/gui/images/sys_mwi_dis.png0000644000175000001440000000262710541072237015777 00000000000000‰PNG  IHDRàw=ø^IDATH‰••]H[gÇÿ眜Ĩ«É £&&Û\´~Dejë¶ÌZ(RØ,,•n0Ø ŒŽ‚°›2èE¡„Ò7®“nÔaæ¢+õãÂÚ’952RšÙmšxNLâùØ•"Ngû\>ÏËÿ÷<ïÿ}xW–eu%%%_‘$ÉT÷ù|W}>ßµ½9òU‹åÓK—.}g4ß:¨n³Ù<6›íÂñãÇvrš—×h4Ú³gÏ~ÜÑÑÁ~ǃ磶¶¶2o+Šò.Ïór¹‚@4Çqp:ÈËËÃää$AèðãQhîÞ½Ë.--AQèõzX­VlnnâÉ“'E«««(--ʼn'PXX’$ÑØØQ„Ëåò644”ètº£ÑÈär¹š¦iµÚcEéÍf3J¥N§w<$IèêêÂÜÜ’É$NŸ> Š¢ ( $I‚¢(¸wïúûûY–Å–––Γ'Oê´Z-@–e¨ª ’$!Ë2|>X–Åöö6¦¦¦E¡»»™L¹\²,C–eär9$ $“I¬­­ýF½xñblzzz2›Í¶;Î|†a@’$4 ‚ÀÔÔÆÆÆJ¥@QŠŠŠ±X f³Ç!b~~333ˆD" Çb±¾ÙÙY/@M&“K¿„ÃaGYYÙ냤( ªªâÖ­[MMMèìì„ÃáMÓˆÅbˆD"–ew¼|>ßÕxfggÿà8ÔC7#‘ÈàÌÌÌ*Ã0M‡CÏ0 N:…üüüÝ.3™ xž‡ p¹\0 ðûýË}}}žùùùŸ¨F£‘\__ßÚ 9‘Hü~_YYqÕÖÖ–Z­Vbhhv»<Ï£  yyyXZZ‚ÛíF]]z{{ÿ¼qãÆ™x<>»#”N§ÕC÷ •J-øýþ‹çq]]¶½½CCC0™L ñx¨¯¯‡ªªH¥RK’´rà;?l***ªF£–¢(477£¤¤Á`¢(¢µµ•••`YAÀf³½w˜Î¡€ÚÚÚ3EEE$ A ¬¬ ‹Š¢ì>a’$¡ª*jjjlæ I’ÂûuÛd²¼¼¼s§CUU‘ÉdððáÃôÀÀ@|cc’$í‚\.ª««Ï$´ßdÇqï_¾|ùsžçÉd·oß^¸~ýú…‘‘‘k‹‹‹¥V«õMžçÉ?àùóç…Á`ðgY–åÃne7:::~…Bj$QÇÇÇÕsçÎ rgÙÛƒÓéüÂëõ¦çææÔ……µ¯¯/c6›­GŠSE÷ôôL,..ª7oÞ¿>ì,Ã0•çÏŸV€ÚÚÚzñ?zûÆäv»¿ÿ§···{mmí×l6{ @–åD(ƒkƒ¡mcc#/ õÿïÇqåååŸ0 c8rÜ=a2™ê¬Vëûóÿ†URf†ÚµIEND®B`‚twinkle-1.4.2/src/gui/images/conference.png0000644000175000001440000000071010503576707015555 00000000000000‰PNG  IHDRa~eíPLTEÿÿÿÿÿÿøøøôôôíííëëëêêêèèèçççæææåååäääãããáááàààßßßÞÞÞÝÝÝÛÛÛÚÚÚØØØÖÖÖÕÕÕÔÔÔÒÒÒÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÄÄÄÀÀÀ¾¾¾¸¸¸²²²¬¬¬ŸŸ šš™™™™˜˜™——™–––“““ˆˆŠˆˆˆ‚}}~||~yyyxxyoopooonnonnmlllkkkjjjiiihhhgggfffdddbbbaaa___]]][[[XXXTTTRRRQQQPPPMMMLLLJJJIIIEEE°Ü¤•tRNS@æØfbKGDˆH pHYs  d_‘tIMEÕ;? +TIDATxœuÐË €@EÑ™ZÔ…ÐÆí¿T>êK`q`Œ¿`I 25{ Z·¹€5‚f&—‹Ý¤J&¨´@'^D%µg«Ø«Óikó³·&_Ï©9ñ 'ÓÄgÌIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-a.png0000644000175000001440000000035010503576707014616 00000000000000‰PNG  IHDR"":G ¯IDATX…íÓ¡j‚Q€áG› A4í  £Í+X3.­WWwFËðD VoÀh^€A(jø¨«ç ||pà+/œs!„n pÆ•œ!S,pB/WD¿eÀã\!oþ®dˆj9BVø(Ï ìñš:âYñ.^P/çóÔ!ŸŠßr=G<¥Š¨âïh_Í£T!}к³ûÂ:Uȳv]ÅuRÅ„Bé‘©‘œ3¹PIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-b.png0000644000175000001440000000035410503576707014623 00000000000000‰PNG  IHDR"":G ³IDATX…íÔ?jBAàÏ?ƒEÛ€!§±Iål<†wHaçU,¬%uT^ÁB-Þ&ÈCCž#¤™–evø1oy¤”RJ?Æ8ž­=>14íî¾”ýoxÇ ‘@M|Oä\¯ÔF·6LdXö>&Ø`ùA¾jç…*Ôî–fí@VY<—Ú*Я±KoWê™HÝSäò=ë^1Ã:¦©úí€-æªÏ“RJ)¥ßœŒ n¼Ò%hIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-c.png0000644000175000001440000000035710503576707014627 00000000000000‰PNG  IHDR"":G ¶IDATX…íÓ1jBAУ…¨]Tbc%dîBp ©-ÅΤÌì²Á&`%BR©…¥A-~!bï´™¹ ïB!üPÃ+–8`‡)¨¦ ñˆO| ‹'t0ÂYª cÌQ¹0k ž"D {¼¤xìš6Nx¾÷ÅÅÏîšÂñí~äïX¸\Ó‰–ZXa†ž¼¾†ØHX_hâ _8Ê›4Aå”AB!„ç ‰mqk “IEND®B`‚twinkle-1.4.2/src/gui/images/conference-disabled.png0000644000175000001440000000056710503576707017334 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ4IöÆ\IDATxœÑ!OÃ`Æñ_Š!n•,0|BPh$r–¯€C‚D"I5 8SC ®„@xGHŠXWÚ`8uïÝÿž»÷ŽXÔ~Œ«¹—ËZ™…6°cSSçT0š#»F(]Y³ŽÓëÍ=#÷ž\(-JÚ®Z톂©¡%¼wW{M 4+"²¨‡Âвg§>ÄBûwËÞ@,xpéZlU@ü }ÕÈL!–¶ThV3q¦/­«göÚ]fpeEÒQ˜ã=Ž£#|ú–Èm9ð[XÈ¢z™³@ž=vÖ{‚qµïÖ @Z'‹ú,õLÇ‘Š /JîÏçzyãgÌ?ì„TN ±]Ë}IEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-d.png0000644000175000001440000000033710503576707014626 00000000000000‰PNG  IHDR"":G ¦IDATX…íÔM Aa€á'I†dìÀPÚ‚ŒmAÌØ‡lH)K0³ŠÌ0ð3Pþ¾+Rç©;¼§÷ž¾ïB!\µq8?{¬0EÅÔ¡ù A5äPAóÒA › s_vÙÈ­ #âQt±KšK­¹c.ñœ|:äÞ¦žútHÛ_‡”0Ä$åå,×·êô!e40À£ 3ßrûC[c† ߊ!„þÖ+waå¹-çIEND®B`‚twinkle-1.4.2/src/gui/images/mime_audio.png0000644000175000001440000000363611001733035015547 00000000000000‰PNG  IHDR szzô pHYs  šœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFIDATxÚbüÿÿ?C~~þEEµß¿ÿür¡à?œ‚ ¸@ŒŒ (¿žÿH0Á¿¿¿ÿ¿xñâò”)S¬ð4)Â0ÜÄ€èü‚_¼ž<ømµRS“zÚdYfÄ{&ê—uîh©6IÊ%~a k¥ŠžWq¥/ľUgkMµŒ¥±ZÚÁcžç±îþ Ìuºï½øËÀÃñŸáÕÇ¿@Ëÿ1ˆò11Ü|ú‹AK–•‰áÝç¿ />üføtÀ–³~þúËðèÈß@Í õ úטٿÀr ±@}¸9Ø.thÀà €X` P¨~úr-D330œŸ¼ýË ÊÏÌpãÉo6pг032¼ýüj ¬,и² ^°IŒ!¨© ’ ¢ ³ÙY™ ÂŒàX X‚€b!Õ/>}úÄðîÝ;†¯_¿‚ çäädàççg``eeeøõûXÝhö€…8ýþ* ¢ðýûw†ëׯ3<þœá÷ïß LLL ÌÌÌp þüùgÐÔÔdàááaøùó'4Û2B£b9LQ¸sçÃÉ“'DDDÀšAŽxøð!×/_Àsss3ÈÉÉñÇÖ­[Ç ££Ã`hhwÌ,,,(!@pᆫW¯2hhh0œ;wÌ jøüù3XÝ•+WtuuLMMnÞ¼ vŒ½½=Ã?PB^€| ²Ô‚aË–-àxÅ3È¿ÿ‚18ÙC„A–Ü¿Ÿáõë× ~~~ /^d¸té84¾}ûͱ¨ ¼8|ø0ƒ¾¾>Øg ÃAñ ‹s!!!0ï ß¼yoPz8}ú4ƒ¥¥%ÃñãÇÁâè–ƒ@átÀ³gÏÀAÇÎÎbQQQ¸ÚÚÚ` ’%HPZù”HA¡R9„‹‹‹áîÝ»à„ Cw@átÀÓ§OÁšA†€R4(ñ€|Jˆ  V£@Ù’———AAA PYRŠ2`ÅŽY°„Ó _ƒ|Ã,¹Á†‚+. JÈòë×/°H-€ôrpp€i˜ÏaÙ„Ó|||àÂÂÂð ò (zËX‚…˜¼¼<Ü ã_½zŽ>ñ¥€ÂéPž~ÿþ=8Ï«ªª‚ƒd)È¢{÷î³"Ì0š™™',ä@–?yò„ÁØØîtŠ@–€âd°˜˜8N;fËÈȀ㧠ÃO:ÅðòåKxŽå}° ß‚rH (m())õb¨(ƒ †v£ˆ5ldw›å§’¾«C‹WŸ:(qwTº3»DA¦€œðž„”‰ÐÜÐÌ`w‘™×#bIõŠ@’°b¤”ÏãââæÌ™Ã°téRpñ P¥ ©üø1¸à¥P).AAŽ‚=zÖ4SŠg---†””†Å‹3lݺ\À€¢ä8PBP9J˜ øeIP”…„„0˜˜˜À}Žn6  ¬šÄ& ReQQQ “'O[Ê °àé¥PJE(îÀŽ9 =ÈÙ©v[@,Ø|Ž.ÒÊ߉‰‰ +W®¯””ƒ²²2¸„“””«½ššÃÎ;áƒé‡9”ÈAíPDÐ JÉ  Êã DJÝ , +°@Ár(ëJKK3œ={–!==œN`ñA ³½½ýɬY³üg̘Á@Dµ@A Jù 42äc… Ÿ€Jå ¢”s` ŽAeJGGÈr Pi2 €ˆ d€,'(TãÖÒ6ȉÔ`å–––ÇPËŸÁôI€©%@dõÈM/†5Ñ@Å3¨\èìì|‚n9 9ÐÈ Æ*¨šîïïÇj9É!@(t`Tb‚jM`ÖE‰st@(@n­R@Y T(S9^ËA €AÁ˜““sØÈЦh`ÇO¸ ŒÀ&<#0Å?›9s¦%Pè ¾( Fhâòu Ý¢ÿ#ÔŒØâÝTƒÅ…êcsIEND®B`‚twinkle-1.4.2/src/gui/images/no-indication.png0000644000175000001440000000067410503576707016212 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  @¾áAtIMEÖ':/ó\¢IIDAT8ËM“QŽ@ «$"±9Â;oN´¹SöËûJåÃEB00ãîv·ñóó÷/ìm\À•\²ë¸Ð7q)ïèÛx£ßÔûÏ××u(aP*E>»¥òz½8¨S( -‚(@š @à™ó±Ešw–s+F SHð12l¹A§• L›ÕʼÛ;p[Ș­ÁÌ~Ä=Úׇâ s«šœŠaõ‘MÔžbZxDÉ4 K8¦²§õ®ƒõæHÎ X“©D׋¹õùÆG>©¬ê{Í"ŽuÛ;«4´#<—Ÿ7Ðgš†=œHÛb±xRXûããöw¨–7o)ëÔ!ü¼§CfÆ ˆþß“`…rçm~O[µ\32Fwz3+3Hxº;›æÃ2ÀÖ ?1¶¿%Gôã¶ç¶z„û3ÝϨÍmýŸÅ;Œ,ò8xIEND®B`‚twinkle-1.4.2/src/gui/images/sys_missed.png0000644000175000001440000000270110503576707015632 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ:.GaÍÍNIDATHÇ•–YlTUÇÿçž»Íé´¥ít ¥ ´Í#´´B¡¶–­Åà ÀDHÔxÑDËõ*Q‚A  («êŠaEö­ ”aèth‡v¶;™{ïñÁd8ç÷åüN¾ó}ç‚’$)ö ,t·iëuC=ÉlÒSfŽáêy‚¹*p·p=Â<îEsôù+>1™iàÞÌ™Þu䟿ŽÏ]ûyÚÜÝp{Ô@¼!aÏó¦Yo™æLzÍ* v7ždï6°ª]Û77¹ü!×=ðz<èòº°À‘ǘ2ÙZlM5aÒ8eªÙl35Ø"ÛÐâ‰ãNK3Ú¼Ýø<ˆø}‰ F•p e0PQ!;x)}ÌnôÉv"¦è稆M‰!ØÑ0–˜€çy{õ8~'É œÇ *×¾"N{ÌûddUq, 5à‡¤û`RøÚZ@EiKB‚R'«=FÎ$TˆÙ*¢´„¾ €›½Ö—ÇAû€Êi(tǰáe¸xùd³T¶&$¨ª”§Û²SÀqbœ ååB¡$òÃL"‘hŠïå ´Þ÷ÂÝ|©Yùû,|”~v¸ÑU5YUœ$‚1 §¡´B&³?ý~ŒØÀˆ¡EÁ âÌáƒÈà ´]Ý÷!ðcÊ”úÊrÚOI"Ö¬4YŒÅ£VQÔSÍ2M…À,™ÙŠP2†C´ËöV q- ÖÌ8ÎtÖ!µå@×´x$ÅŠ³‡÷")½/–LÛd5—ï~ Óm^7ôpeµyJEM†"(V`ÄÁˆ xˆ5íÜ˹î¨=bJ*Ü×âôöxp:áë¹_ÏÂÐX&VnAÝÁе¸¦ßj?«†Æœ™vÕÄQ ¶|O£Œ'ÏA Èp:á(}*[ACA!­zf#= Œ,åkÓ2(t=Éx3¿†Î` „X@8 ~—Ñ|ž§Eš¦7&”"\ÁLdù¿cb F§¸ÔÝ[Ú}F'€±`ä( ʇÒÚ„_.E¦5WO¦°p(‡…C™×Õ}µ\n,ÊãÇg¤Š¹³¦Ê{/KÓ‚¦ªe,,buK-§$IÌœ ¯vØ™ªæ²{7ÒÙ‚ÒÏŠL²Ÿ‘‡¿Ä/ޱѢ†|væ÷±ßJïɱ‹yÏ]œR*Ôf: ØÙþ,¡—Ë¥ž+мcñ|áðÍ‹} O³+/z®@8ûú/”îU›o8òhurròÿ"Êè2qÑîï’ý‹f˜>W`’Ù‘ÇÍ•D)íE~}mr±#Oz½÷ü¿“r½9vRIEND®B`‚twinkle-1.4.2/src/gui/images/redirect.png0000644000175000001440000000060310503576707015250 00000000000000‰PNG  IHDRVÎŽWJIDATxœ­”¡nÃ0†¿Tá{ƒ±àGí+L{†¡„L#ÓÐx€ †ºW¨JZ2Ô*Ã~ŠòJ7à6»¸êªtRr¹ûüç—íLDøÈSª²\Á´m6TÏN¦M-0 Œ@UYJ 0ìÃF×@‚¢ø÷Gˆ6àÜå ç@›#,°Nq;·ÜÝ«?Ás‡uÃÞ£,«’{`:ý`½'"&Ë´rhuS“É€ÍfÃl6FiÅCñÕ½÷4Í[X´šfG]{¼÷ìÆ´­•ÕøÏ¨·H©}ÃÁ'eQ*<m{õÐÛ÷³©­TT¿}HÕ{F "‚VJDB¾½"m{|N$Ì„ùQD]­Ï/ŠÅÜá]Æá`•PÔ©ZÒ­˜Ìe¬FDÎÚw‡»Ñ±O[KõŒ:{h‡€§qñ5rmüåµõ¹[ßÏIEND®B`‚twinkle-1.4.2/src/gui/images/gear.png0000644000175000001440000000143710503576707014373 00000000000000‰PNG  IHDRóÿaæIDAT8u’Kh\UÇ÷9wfn®Ó:Mb®LZMmÐHŸ)RHWbE¬ˆ´"DQT±ŠŠ–.b)ºpáBj¨©­Äšš¶“ªà"ÖÐ Ó„<œI&óÈdfr3÷q\¤Zm~ð­Îù~ç;ÿs$®á…SÕ¶yCþD^ñ\ÿ·/µl{æ×õG~ÚO²ÀžA§9ðÅ«ž+Š' ã3‚ÖôJ®d(7)5_µ“—žúýÀ¶ë ºO¯Jh»šK>“1k´„9WAÖ¼–(æ²_mÈÖ~aɹòçÛ‰7ÿ'è~tß¹º@ÞýcåÁDcͰ¢jÁgSeiº¶ø×{ÎÂð‹’š;¾EÏ©fÀÖ©†®¢4ÞóÐuwè:¾|ŒóBp^mÀí{û>ôúú}~oïHÿÑÌ‹î3UaöV„ýÑìDü±€¼O½sí”?wmÉ«Qý ÝP‘ óòTjîÔj²äÞ¿«:ðrû†R– ¤cM­ïø&Ûóìñ¥x]¢;Lf3P.CÅn¾#ötÿîµWèêɘ3z$=¦5˜õÁíaÏ»9"hºâ]©ãbÀfò¯å¯ïß©¾xrÎ6LŠ@0ÀÉHŒ4•×¥ÞÚÂ"L\j2€ï‹A;]LYÍ[¦¦§-¹ wâjݶڈ€hr–PßÙ#ås{zÖ¿½ÕRÖSÛíÞ3ïN¼‘x¸é‡‘}f¦¨nˆS„­lð´`¹6>Ð Ìßàg¯ÒöZjsCÿ¢àJ 6îOMÅ=ø|ä«´:<ã„8ø:°–•z#ï '/©…îuÏ=Tþô„eu”ÝÑÃù•ɾ‹@yÝÓÿCèj­Ë¿YÌ1Ï`)IEND®B`‚twinkle-1.4.2/src/gui/images/editpaste0000644000175000001440000000044510503576707014652 00000000000000‰PNG  IHDRÄ´l;ìIDATxœµ•Mƒ …ߘžj7½–ÄEƒ×ê¦É\kº@-ÈPÐÒ—˜ ?óÍIDðݾ 2³ûD„ZÀ´9¶  Q/V±¡jµ7Yù@À?<ÀÃÍnÅ.ã¶5?vNô8I^õ å‘3x Bƒ!žQ9oý*|2‰Gn§yø3¿Þ¹˜j°+_‰©ÖÍ+ÃÝœ'ÙJ7Ï\ã£Õ©ˆ#Z :e‡'[ãœhÉ qÁ_TäNÍŽk®-x7ÇGxÇVÑŸ[‰–¾kÜͱ¥ÝÀzÑkùñzV€Wªý󘟅ëý»ªà«z 6ãç&èØ™IEND®B`‚twinkle-1.4.2/src/gui/images/password.png0000644000175000001440000000634610503576707015323 00000000000000‰PNG  IHDR@@ªiqÞ ­IDATxœí™yl×}Ç?oföäµ"%Š´(ž:¬û–ìÈG”Ø–â« œ‰›ÊŽSQ#-úWŠ œM´¤5Z+ƒ4-b[vd£ŽdUr…P·¬è2%Ri¤HñÞkv®×?Þ,wI‘ŽSXæxxowgßü¾ßß9o„”’O³h…V Ð2M@¡(´LPh -ÓZBË4…V Ð2M@¡(´LPh -ÓZB˧ž£Ð ü¤ªX”ã“`KO2x3)ßv/ñI8ª/¡;kY×ãž…U¬ EKCE±-ŽxvÆ4“#×ñÁŽó]œé¤ùðUŽõÄåðÇÙ{JÐP!ô-óyô3uüIm]í=±¦{Ã3¬£tNᘎn¸¸vsØdäú5†.¥¿íd¦½½õðþvvîkç­Þ¸BhRJo¢{LYX(šþ` ß_´pþ«î~Z¯ZµŽâ™7Á¸V8½ ã ]РÅÀ«&9PEÏÙ8×¾åýúüùwþë,ß=Ô) !4@Êq€§$ߨ îl)Ûæ|æéE>NIõU°Þó2¸H Òð2 Ó “@Bkˆß\LJº¹ðÞîŽWŽ'¾ýv » ¸ù$L¹$øõâ/¯‰þ´éáïÌjÚ¼Á«0|¤ i>h x yàH@(xfR)):Â’/>DÑì/7„Bo¾·[xB'K”"à±åbÅÓw/Ïì…Y÷Í…Ôv°S@p@Úpí D (/‚Á!†ª ˆx)E‚L ‘yƒ†;— kŸ‹=iïù‡T¼ïЇìGá¶a õóf‰ÒçñOµ›ž›ÛøùHî;è 8H ú{!>º ‰Ü/¤s›yysâ<µ«O°xÓÒÊ?\e|wv óC¡Ã"`ëJžYºö®MM_¸¬ÿÇV?H¸´Õ¬£ÜÞ3A¸ I?Heýltg×.é¤iãMV¯®ZûÈí< „ ð3cÁåŽ:Q»rnàOkîû¡Ø¯ 3€Ši;oXàY KŽJzÒÌý¨aC0ÚNýøìÂÐWêg° ú˜°¶VD_Á_ ©s=Æ”‡lhe×GDÞµñ_û–ÒkÜXW¹Ø€äû 9ÐÒQ36]øŒLN(ß(pSRÙx“·k5Ÿ»zèGG2-€3JÀšZyn;–®»ë©êõ#4×Ï´ »»÷»9ø¹+¥¯«ÄÎJjkï‚i1÷£$dGF¹¼–Ͻ¸ç×!3Ž ¡b0"€Z(Ce£ÆÒÛŠï‡ä+fÆÊkkEÑsëÙ±pÕ=__üÔ?žÙ'‡™(Eä`I?î<„t@zHé ¤ ÒAxŽo=ÿóèÚ7;‰@ð$ÛÕ==ßâÒV ¥å[ÛÍö= ÏÚÙµv.7CWKÈM™d,f–Ö­r¨Y®®)«ö¨­¤qþm%ug;úoËçˆÈŸßÉöÛ×ÞûõÏüŠO‘ˆ·0Bcœ%Àó•v3àdÀM#œd‡TŸí$8)=Ž£ÜÑU¹ Ïçн©­iª±q|ð~Ìc©º©Ü^·•^ÙL/r³çBË/áÐÁØ¥7[´Ÿö¥é\V]ýðõÔÈDYÍZˆ–ì ;V¢Sœ4¾½‰5­}è+˶þ-”¼c^¡´¤üVä£â)Å\MÅ–ã€ÍM¡)—ÂOÊKò<¬å4@èªÑ‘v¼´€ŒòR~ÛkªÈO.ZÎúC­pñtÉÐÎSƶ—úšÔÉŽà¾`pæpÕûî_V-ÈèÁbÒ˜Ò·ÐÙ%ú}euDÊ/“6¯SRR’·û"tU’„zÅÊRnFäùâ)/Á³ÁõüØõÀõÝÀs 4®9.æ}ð2 >­î­“#@(àYu3Cзµt§Ï+—aÏ|¿½÷G—•?kÛs+Œ¢V!é‰  /ž,~j+;ÿ-iݰåeÜÉ øVúE$ädzǨK?Û¹YÚŠlƒãš>¿ü¨ÇKxY$hA( ¤Ë#†§'a–Rf6ϱh¤<¢…ÀkEJhÚëdžÞú—fý¹3¯ÿoßåwþø4Ob~é/žÊžãƒñcÖõ“VÀSðÁIŽæ5²ùÂùà=ßkòÁ{Œ%@Ë[gë˜ eµkµÆÇ楾v[)±¢ κ±àÁùüÕìU[¢Á˜âÕLRê!TKh ôݮѿéíß&• _ØâïšõÃ'Åá"] ÕHJåÒ£Vwü fsãÄE¬‘ÁaªWªJ(í\]ïùqÏ8ËgC/?<äy,ûýå‚ |bÕ™ã+†’VGSUñÊÆ[š>» aþ;é Ó¶S€‹tž’» X>+þg»ÐDeýæÍ£àS}7èÜ{Ê Ñ‚—~±—YËÐðÀFÕ™9~‰ÓAâÐöö!š_;Ó}¥Çiß°¾z}庠^œk‚˜=[õþ2}«ÛçüŽ*?,—òÙ°aë—XÐýàJ7£­ ΘCE­‰>ü`üõYªó9®Ÿ†3Å4·%›ý$dŽ!ÀE™ø› ;ÖÓÙkfz‡ÌÀr'Ž®Üurøgº1ÃzBœÚž²°^<øÞ±öø!ÔùÔ€åì览 A':€‘½iÛ:Ø5³bÞqë‡åóÒõ@jò¿ä*ÂD$d%Ã× ãtÈÛsIc žîF dnQ(G‚´›[›¨圹&Aºú«Gwe¼ŠäPÂi:§ @Õ+ ÿ¿Ö8›ä‰'ß8Þ÷‹+Ê6”îÉl]ñU`”\(LFyŸ'ZU¥mÝ/8p¡xÏÞsÃïú;'™ FIl!„Äý¯ÝñGËB‰tÅîc½ïøD…P̦;ïðñ#:+uH—2MsqmÉó·•–7w÷m\ü(¢þn“Ÿ($ò%¬Ú {áèù²³?9‘zÙ²¬`ÄßÙýÈ3A)³mܤ¿K!„ªÎI¸Œ;yýMâï£I)Û×̯øÖ·´Y/yVßÚyHJªPör¸ÕÒ“× $z¡ý€àð©XËŽf÷…k}év”Aã€%¥”¿³cq!ÔCÿo|‚=t€%õåKžYøÞÊú‡7ÚT/=‚Ê>Y"&:ÑÕpÓpã´ p¸µôW/¶þ¹³'~eù~ %¥z6åÞ ø$håeÑê/­.}ò¾Æô××'æV-r™Ù‘RÆvêYõH@t·è\êˆvïi ïúÅéÄî!•ôâÀ Ì‚‡)HŒ’` ôÐ’Ú’Õ›æoUµýùºªôíå³­@ÙLI´Œ€Ä±Ééô÷펮pûñ«zóvkÿ¥®äEð’(ð£qŸï¥S’ÿÀ6€z©®ˆÖΟX¹´:°¬X3tÒBÚ"àÙ„FœðÕsÝöŶ›ö…ÞÁÔ Ùª•@å¦ |B^eÅÏ+~JÃPCD0È£F—–š±QÖΖ_g²Ü4¥ ÈJ*4rÏìùÇž?üÇL>F5úD/>Ù0¿±­ “½ Ÿp¿O¿k™o† )ÓZBË4…V Ð2M@¡(´LPh -ÓZB˧ž€ÿÊaä‡îTlIEND®B`‚twinkle-1.4.2/src/gui/images/stat_established.png0000644000175000001440000000147610503576707017002 00000000000000‰PNG  IHDRóÿaIDAT8}Òmh•eÇñïuÝ;ÏÙiÃãœmvF­Ýu% «)Žèጠ©eÑ«X©µá« z‘¯F+ ÜÈIæÐ°ŒaM2)˜ÄYº–mmîœyžîsß纮^ȨÿûÿçÿÀO¼u(µ3;?ý®ŸËvêLð L¨¬ÔeÊå@gŠ¥¼*x"á(RH<ßÃJcíA:®}°:\u͛ξlqBöç[w¬ÞÜÞ|Jk½ßðÿek­N‹²Ú‹ÇÚVGÃO¬­]Y¥èÃB6ÿþ…±KÕZ›wþøëjêcй}O¶4tl»Ë¶Èæ É][Иç¾»hk­ß––\ÈÙ‰ë2±&Fòéá°E€€Ç<û|;[·µí×Êôj½ô Ù”¨ëõµMD"­AÊ ` °lðò W:òÁ ‰>„9l´qî›jihŒ.N¶-¸.do—8qì{Ö¬qà½í$»Z_×Ú (¥£‹À|¶ÌtŒÇK²0¤çóüõ­õ<³³e`Ï+é~ù¡=Bˆ£Jéj959sòüùYÒy0Âa˜ü#ÃÑOÇX¿!ÁãàààûðR÷FÞÜ»½+r¾¹ln÷Ðg§‡~ºp$LüžæÈÀ­m÷óð£÷â•@ u(Е\ǪU±ÇlÇqJù\áÅ#_ÏÕÑss*MËæuljKP*T~¡$(Â…*§²©W,ù¶1×µüòŸô“¹»±®÷¹îCX`P¦Ò”Îøœ=“âòo7PÖòC‹É°l‰¢ïò¥ë='Ž£TðˆDA•¡\\ü1E)(27ëoj¾R`Ûòðø/׺û?ñ¼lŽÚ» \ u03s‹ù9UŽÅën×ÔFŽ/ ¤ÀuÁ«W&w}øÁH±˜ÍPW þÌÙo¯ŒŽ|õëîS ûܰ—dÓàºöɉÔßOõõY[³<4>þçA+V®ÈØËDòÖÌì4ó/—YÀöîêIEND®B`‚twinkle-1.4.2/src/gui/images/qt-logo.png0000644000175000001440000000121210503576707015026 00000000000000‰PNG  IHDR‘h6 pHYs  šœtIMEÖ;›–Ý)IDAT(Ïm’OHTQÆ¿ï¼÷|¦>g†išÊLS‹¡h_Ð_$ 1jQ [¶Q¡¢6A›te;qˆIÔ&Éh×,Âeîl f`”ÊIÇqæÞÓâåáÂY|Î=¿ûã«L  è?pUÃ#ªÿ§pæT¨PYXõ>°ùÕ*àô¤œsüî„QUR €á“T‹wÓÎÂ|ÅÔ­Ò*(ðij—†‚›÷A©°9Ê·ÓLÏ–:"-W†ƒSž]^âÂÜVz¶, nŒ*`P€…Uoa~³=â>ž:|ñö^÷‰íhÜéJèéx{”é¹­µ¬P© „[fÕÔkÃGTŠþÄhåå“â¯õÚÕ[ÓÐÌǪÂâËV89àne£ýÅX9¿Rï9æ÷¥¼XÜ€šË¨€VöÉŠÒX±åbçÄØN~¥®¬CEÙP‚$p òhÒùú¥eyIºµ|µ7Ùª8”ËnOŽ7úOwØ“r Hká[ëÓ‘R[‡óh*þs½Ö—r:9^ίìÖõøl&ޕܤù—ÝÉúå¡à÷æÞó? ßµ\j”Kþ3¡‘XKõLsաᛤ_oÚ†* k¢1¿¸Q¼»~Wå¾|”ÚVÈJf±šË‚½Ç³çDýOïwïøâî–mU4¡ ’€*MhDÈ0î¾…  %´¶IS  U×?óú‡®ÕçIEND®B`‚twinkle-1.4.2/src/gui/images/presence_unknown.png0000644000175000001440000000126010637222546017027 00000000000000‰PNG  IHDRóÿawIDAT8u“ËKÔa†ŸïwgFS#aF³‹C:PØ@—¨ iU”îܹpá^Z†ä¶¹p•m¤Y¶,#Ô$hS"‘É[:::·ï;-tF*=p6çò¾çœ—£8ú†$$BTJ†Ô܈JŸV§þ Üy*} ]‡XS]¬lºH–4có£jâT€»ÃRm„ÉP­Äw ]­Š\¾€1àº6Ë¿ ¯Þ[|]uÚлðRíXe#L¶_ÒñáGpµ¡D¡XàZ“¶fõAE¸NxÖcó –‹0Yî³Êc_¨–øÃN‹í=M$d ûØÈÀÏ-8´¹~ÙG¾`¸;@´QÇ#ÒWP0ØÙ*ìçù¢p¾Æa÷¦àË2Ì,æ¨ Ú¤w vE#0àt Iȱ‰Õøëðl‡• ø¶ ë@¸Ñh˜]2¼ý¬0âQ]E¬¹_BŽÑ€gØ9´àðhž×Ž÷39žtCKØÏâšajŒݽÊ-u´céßÿëÛÓQ¤%\CjÕð| ÚBë&8FHe‹ŠÌ D!F µÉ#_„ïE­p킃œ€HÊšQéýC’Æ KmkÃ̲Cb´Qx6G„¬$ׯ´  c[{†s*^S¥ñÛ9.Ö© òWnu³„ˆ«È8?ª&~lÚ‰ÝÌa¥¨Ú§¹×¤£Í%TÒ¼±e)MbmÜ›pÊ;iCïôwÿäÍB.~+bã<Þ|ÏÇ‚ “çÓ‚fvÅK€ôžùL-ÒçY¥ÁHC. ø!³Ÿe1]•Ì•¬±2ó™ekî—‰bÔÚ¸sê;ÿ‰î¿'uöIEND®B`‚twinkle-1.4.2/src/gui/images/bye-disabled.png0000644000175000001440000000060510503576707015775 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ,'^š&IDATxœ•Ò1JaÅñß'‹­^!ÍVÞ@žÀH&…½‚²â ,‚¹À6~µ…’2‹0›]V¾jŠÿ oÞL²¥£ø®©«Šm`ú³#:°øF¦Ê­©SˆE"ýEp2.-ÒfÒà2ð[ ÎbæQíPc‚ä Ù3˜ÛiÙ™Z¥–ݵŽÁÄ9öì0ŠOTjOž ö£¨Œ5›ÞóìãÓJ¡:Íp!ã¬:OTvU²RJ¥µAf¥QƒpÚ­ìÕM—SVÊ> 1vNe<ëÏÒF9ÜXo\c—Ý™G±Žˆu¬#"b/ñËXÆ2ºŸH-vmŒ½[õ{vÏRÀ]êC6ï¿èŸúÒhjðâ-õIEND®B`‚twinkle-1.4.2/src/gui/images/stat_established_nomedia.png0000644000175000001440000000102310505044710020444 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  šœtIMEÖ & “N—à¤IDAT(ÏUÌÏKQÀñï{ofvukÓ•~DAý V‚"’<+Ñ F $!(è^ $"Z‰;X$DTÇE uY$(HÔÝÜ­Ù™÷ž—ýž?|ÅÝ ¥›ÿNÿ×I}ÊÄñëšH!¨a™Az£©ïKQýˆ÷4;}ø•´lÌ13æZæØ¶Æ“™vB*·?¤ÍÐz öÌ-öw¥{š ‰ÙKåÄ\£ûF¢1@ùCîä ÄçÉêa³v»\!…A"(y`DŒYwßN„D¡p©ðœ­Ü »ßŒëÍr™I’“ìç†<—.‹': j·ßÔÙŠƒG‘éÂb‘ødö}ñs²š+L|BPä1>G ‰±DDœ¥= Ž[¯æ-è_ø¢†‡Bãáb Bp,ÑÕ‡åý(ê –2o™EÞ  #³SlB£„,Ò1ý€D}î»_«²…müf)nYnžZ ñ ß.Þ ª´ðŒwï_æ~^O´‚³ ,ïE±ûÖdSòë(ãmåDÏüXÜ#—àƒÈñIEND®B`‚twinkle-1.4.2/src/gui/images/sys_busy_trans.png0000644000175000001440000000247210503576707016544 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ  /à­gïÇIDATHǵ–{lSUÇ¿÷žûêm×Ûm¬»ÂF;mg÷Æ6†™un.¨@ð,‚a’cbFH4ÁG!1"#jÜ0QÂÄ(ʦŒM3 ˆ,3# í0evësk{ï=þBlDžó=ßÏ9ç÷Ëù`!Š¢ìÈß ,ðD±›{ý‹Ö¬é¹*Y8Ó5ìL…Ǚ֯6m|áE«Xìa^ùÏ'»xÅrkÙ8áæYÓ*²R´boB's_f&æ›6mZ+Ë–žg`S z¦ïÒ¶®®î6 “GO$:=úЀ†††´¢(œa·Í²Pv»½oûöíËèà¬ÖBuEš¦ýk†a`bbÃÃÃÕ{÷î½X­Mãc(€(ŠBÜn7***`6›‘L&áóù ÚÛÛ°ØO3ð¸Ù8ŽckB¡q(ŠŸÏ‡þþ~Øív466BUUH’„`0èlkk;ÆdͶݙN—Ë­ ‚`Æ[)ï©©"óä ÆúH¶$¤ÒI« è™f‰d‚§–Ü<™ßw ¥¥088¿ß‡ÃÚÚZÔ××£«« „¨j.ÌhA¦m `ŒSº_ê2§z¼¦Î¼â©ú™—­ ÀˆHƒ2fPhøêk+àõz122‚ááa?~ùùùÈË˃®ëà8ÖœWQ´¨z\Gokjèâ¥t¹Ð{ÏökçéT¬~Q™‘AD†ð`‰ ,C@Ó£8zl%‚¡›`Y^¯ׯ_Çôô4‚Á JJJ ( dYF*%!>Õ÷ÞN~÷ñ'ÉÆ‰°q™ ¡°~í§“©ƒ¿ÿsÄÝv;ò 0ID|Qì9ÚùY˜œ¼‹Å‚¦¦&Øl68Ál6C–e„‚£tËæC»ºOê[4 w$4:tÕ8rîœö§™O/~¼ˆ·ކɑ(ÚŽµ@Í­…MºŠtz7nüêêj”——C’$pMÓÐÝÝ÷ý᎞bÿ˜’»ªF¿5F/œ:oý7¦ÊWü k„éé-G Z «\žºÈGï?FG‘˜J"è=?îܹ«åï&ÐûÖg†Ù´ ¯[M$zöD1­m8OëÖtùJŸ_¦ìh¡£v:1î¦Í-Ÿß³Îï5QâN•æª K,XXBÛœ58uº ‰ˆ„ÒÒ+ðT„@$+†Âå&µ³,©à–eçèz 2r\ V\ƒ¡SŒ†±€a%€ £¬’p)Ô4ýÊLŸ Öõ(Vð’t;M”˜Á/=þÄ¡ö[£Ñà cÀÆ‚%OZPµ€,›qç’%R?xÚFã±ù4{ŒŽøçÑÞ—®:¹¥9™‚cýKÒá ?gkш‹&•4-¤ïn³ô‰¢8³Vºî9éÃè˜J õ Í¡¯­È“w‡D*‚Ûzð3K"Ti8\H»:æLÏWçÍ !üžwL}S•~ó¥%öL•øæ½´‚Ày¶næO\ú5Ë\µÓ¥OKÍ<«¶î–'w¾eò8I¢d1÷ß#WW ͇>UÂÍkM˜$^ò8Ù&Q³góã˜k—ÊÿL*ëvâÙàP£µ³S-È,²µn’[5 ®ú/&S¢Kz»}B !/š+¼Ý @Á¸­žú7Kl“§IÑv¯>Ù[1&医ó5?Aí{ãNkâ۞Mú†ÚQ}‰ãö0yͽw#}¥¹óyKÝJNÅØ?¬?6¯Þm`"ÌÊG=žž)¼±Ü'™ 'Æé§FϨÑf—ãÔ ÚËă 鑵‘ÊÈ1¥jPÖ˜¤íEp‰qŠÞS©C=á{Ã\â2CÎ@ÂNô8>Ä©·¾ló*õ­\ ÆTT"„h"8Øœñi³x?—Sû:½}Z ÆcQÅ9M:°é À‡¯GÖ×@ÁA˜Úª|Ì÷{iK5 ɇ+Ëå9½qðç,͘{$~—²x¾ùƒÿÓ/Ù’ì(®@yIEND®B`‚twinkle-1.4.2/src/gui/images/sys_mwi.png0000644000175000001440000000261610541072237015136 00000000000000‰PNG  IHDRàw=øUIDATH‰•UklSe~N¿žžÓÛÚ]º•mîÞf¸ cW8„a 7D4‚Á˜05Ä `@DH@åbL$F%H‚(bX ? :&lL 2G cëÊ6v‘níiOÛÓžóùËØÜx~¾ï›çùò~Ï“xp§KOåÞ$*¢«ïرl·cÇÒ½#kªGÈN“7|ô¾~_R"¦ŽÕÍÍyÁ<5÷{Úþ¢kêÉ’«ÕjíÚ•Úu —ÆpÇ~ð­èíCË’%'Voœy'-¬2–ñQÏœ˜TÅB4[f7}:ÍPò­Bb&+Ÿ£©Ø³gyÝ´’lUsseøñ¼ü`r²Ñ<üÝzX§+àÌ:€è(€ ÷Ãõ‹ïÖ„ÄûöÕnkh¸ãêìì‹ BˆJR”Ž„ä¢ÝÇÖÒH“™Òq”¶ÆÑèU#½½ÛV¿:ïõéþA0(•ÛíñéIIf¢×s „@–)C@Xe†vÞg¼*ÀàŒHqäRUíI‡Í;¡€Ëåý ðxDtw{ ø€ >üÀp[ ywú›æ!šyª²&¸k7¡3lyo2ê3gÞåÚÛû + 22­?œÎN~ôv `Û¾â,o‡DÌP—ŽºÐÖ³‹u+JIŠÎÈÄL‰ç5R$£ÑȱzžÄ‚¥†¤ÔÛÓy ½oŸÀ@aŠHˆÙ¼×. …°pQ" (@4 È “ˆ²¢–+jY‘sõ‹gUZt¬.€(>PFE‰ õÈQ¨¥TÐP¡óµVÇQ²ýSC„B,¢ÿKÅÀ@^o]é§H÷=ù·¦ËÑ«4诜Q  GÀ*¢…Š!:×ðá0Äak„’œ  TN¶r)èrûàt¢¹¹½wkP_WÓæîѽÖ,´äç«Ô_lÙ¢{6¿0Ž^ ŽE Úãpe52çÏG@”àk¼kÍ!ˆq©¸µ~)22nÁ–y·Mþ­;¤[Êž«øÄ<:ÉÜŒ<²îÚW½œ`Õèв*Š”'_‚¿»áŽh‰–epÓãƒv{S=8{Úå:þcäÕëŽð”e¨"‘Í % ÷ Òæúüìv KŠÈcæ¢^¦é°Y6 LÖXÌ:°&#;_}…³|øòÀÀ•]¼U=ý‘?ÿ³÷9:®M=>éö÷§hµ»C ™òÍHzë*¾9ãůç‡qñ‹c—“qof3æ9ÀÀaÁ#•ïŽéóñg“ò“¬¢VE (\8„)YÇQßP ÑÇ£"¿ ¹E> C‘c#OÇ3®@Y‘º*ÞB Ë~Pè`É1á¹Ì;Pd …‰‚a `T<ÀxQPL2ÕjbFå¶Ñ<ã%Y•“…Å,Ï ¥PBýø½Î-ž<Ú7 ÜBQþÃP6Ó€Òi¤j¼Ç>O*[Ì4àO£6íw§ÐC»ø6{†z%V“¾vªùB|TðåPQ,¦ÁNw¾chä8nÌSú^|†ß/ Z©(¦Ó.g}m wZÇ3©#FøÂ'Ô›N|mý÷­ÔëµÓs?%„Ò¬šŒ É !ìÁ´AŸ•Ö7øç”r›Ç›ÕhÔ¹›6°ço^Sîµ'ÒOñÕ hX•õð^Ýðžmzgn™k2ÅýïY%„Ñ•kªO~eòV¯ÑžP@˳|n†j=§áâ'äD¾ 7ƒ[>ºþ7˜ Vƒ³aIEND®B`‚twinkle-1.4.2/src/gui/images/1uparrow.png0000644000175000001440000000111210503576707015223 00000000000000‰PNG  IHDRóÿaIDAT8Å“ÍKTaÆï½w'lrÒ ìËrÊÊM’Y‚D•¸·È]ÐJjÕ²UÓ.\„k7­ü Z¶h… ´P+£œÉçÞ;Þ÷¾-î$"‹<Îây8ç9çk-» gWl@§^ƒ›$0°h¥nÒòÌDׯ?ÖQôBÕCb¿ª‡ÈzˆõŸ;0JOD^¦<|s°õÚøÅÖ¨%S62žø·Œ.ù&53x¥?]¾ÕÆóñ,—ÆÎ§›š±Z—ÄßloC;sÇÎîºw5ǧuXùS×;95:ÔÕˆ™Ã˜^„Ø! @X›SÊÌîé9^*„°PIàpçFJEëY¬Íýp;î‚­ôK•ï¾]:A>#XÝ€µTÞ™îK_‚£ryù ÆÌ[cñš®= ³& }'Vðá[² h“•i2##ÔW+“λÏÖM=ñ0z,éé°P$4ï¿os6cX ˆ€”‡¸<ŠYYš¶ë•7nnàþ+¿Ð×­÷î£.áçf‚zLHµX iZ€T® ·}¿§?.žñD&ÛŸ?Ô‰Õ` ¨æ-¹"ÛMß²Þ>ËÒÛÃý~­šWµ®lg;˜æFšíoÅǃÊâWtµZGÆç¸®[àèHcc‰– #&V£eœÔRaâé7L´á?ÿý‚Ä'Ël¯¿IEND®B`‚twinkle-1.4.2/src/gui/images/mwi_none16_dis.png0000644000175000001440000000143110541072237016257 00000000000000‰PNG  IHDRóÿaàIDAT8¥“ÁK#gÆŸ$3cb2F³4HPÆ1‡%‚‚ †º²=´Ù“®^d-ìŸÐËö¤§â?±ÇÒ{)¥.Th`È@°Æˆ ¨‰šøMb4Î7óÍ|ßô •îe—Ò÷ú¾Ïïðãyÿ9±ÿr¼¼¼ü|ssóÛ¶%Û¶¯@úT`kkks}}ý™ªª/FFF^hš6îºn¬Z­þ~rrò•ªªvvvÞ¬®®ænoo¿›žžÎåóy5CQD"PJ!I&''_@† iooïû¥¥¥o …Â3UUŠ¢@–å'h†B ÜÜÜ —Ë¡T*ý³RJ˺®Of³ÙÄðð0b±8çð}žçR J)®¯¯Ç!IJ¥VVV~•ÎÏÏÿ°Öëõ „@:F$çœs!ÀC¯×C±XçÅba€Büqqqññq áìì WWW ”b0€RŠããcäóù'ØØØ²Ùì;ˆA`X–å !J¥055…ûû{Ôëu<<< Õj!•JAQxžÏóàº.t]ìišl~~þ•iš†aàààF ¨×ëh6›˜››ûÈ c ÝnÍf³/•Ëå¨išMÓàû>ªÕê#9Ãöö6\×cìÉ c „ÜÝÝ…„@’eùkÏó¾´, £££˜™™mÛ0M³³³˜˜˜!ívN„}×u?8ŽÚ¶ý>²±±apÎõÅÅÅL¹\†ã8¨Õj0 Éd…BaŸsþA±¿»»»ÿïâe2™´¤( [[[Ë!P©Tpyy I’ ëzxttô[­Vû1‚SƘ¥ë:cð}¾ïƒrK$¿zž÷RÓ´/r¹Òé4’É$Æ/–e½6 ã¯v»Ý%„„Ýný~ƒÁŽã<ºjµZ}Y–êt:©~¿ïB.>==}[©Tî?÷¡ËŽt0àInIEND®B`‚twinkle-1.4.2/src/gui/images/knotify.png0000644000175000001440000000226710503576707015142 00000000000000‰PNG  IHDR szzô~IDATX…Å–_lSuÇ?··Ûº¶[Ç6:`C â艈AÍ =ˆÑà‹Æ?‘ðèƒÏ>è«oÄEcBL4f38 l Â`XÇŸým×uýw{ÿÿ|¸-T6HÇjv’óÐû;=ßÏ=9¿{ŽÄÿdÏ´}ÑalÆ´ÚªêBå¾ê'Íx‚±‘ïÛLJîRˆuø®CèF»Ë"¨ ¶y*ý­å/n ÐòHuAXßÝ_ƈ¼;ðð6Ìeì©·Ýh¯ÊB¾Êª6O¹·Õë­¢©©Š¦æjÖÖA°66:ñ©4$Ó0cuÁmÏ’ä= ¹,€Î£ç{ƒÕëžö•{ÙÐà£!è¡¶j×8oWh†}ÁÕ0Äâÿ=«ko>>þÚ¡ëÄ'@¶h_™oÍc­M„ZŸÍˆÜ¸ ÃWˆ¥Ì¿}3 ž­‡ÈÐ$‹°45‰ÑøÝc®_ƒHôÞy\ž ê·íÚÓrቇÇè›+ ³0O:ÑØpÄ¢ (ÅåªÚµƒ¦ ¡Î1ú. `kÙ³é { éö3ae€®.ŽWnN! ÈŽO€m£„¯+F™v->t)¢£ÌÎ0üà.@2…PU“ŒéÆ-:7‡d 23³H¶@™œÆ´•멱±ŒfÄÖ¡fbÚèEÝN%FÌßF 0pî¿d€ô²´tM-³CW¸2Ðõ•®Å§³ÙÙ©„žžLý1˜" å<ÿÛÌXùØâ›PMžAˆ·$KÐ?üÎgÀ (Ðs‰í!«à™¸3oѲ-Û¶® ÎDz9€Hà’"÷2WÑ–ÙøvV%'¦æ\Ï,K|Y§Î¿Ü+Ù¹ü–½\•–¥jœX ‘ÎcØ ÌÕ©¸8§[«`ÄV¹V4.,AI›pÉïÀÁç­Á0JZþåô ½ä®˜0Ô³À^©„¸Ðñêï›\oºm×sê½X@¨Íg™¼9h)ñÅŒ"‹T ©ÔØwäÜën!;øTsàpgµç0?øæ¢ÆŽ?ú ç£?±“%Øwä\G¹ìùôèá„rcj‰ÜVÆÁ[Ù´µž¯{àÖ©’ͱý{ZV»™ž½w°U»ž¦0ÚS2}ܹ2ð˜œ^:@1`jæÓÕAìx¢t²-±wväB³€h2Ëe¾'Òñ‰ËÜçðY Å¢‰HÄ ”•¹ùY#œQà½ãÊðUt”΢a®Àe¦ÏŽRáì¸Ï UK¸×ÐHþÐK˜þnœ•ê.Ëwñ&wõ+wïus{cóZ|~™J‹ÜŠF?ÑÍH´çøENž¦nëþ;<Õ}ªJoqE/ÝØ"eU¹Ë@ÒìT’ÌØ7Nö3ØõíåË©ŸÞÿ›o~&p6!m¥È÷• TÁ¶šWÔˆ »%Ý1LÉ2Õô CG8s§W#À °Â·/g0U>ÀÓùaeà쀩œ°N nÀ¿çÝ$Ï CÅIEND®B`‚twinkle-1.4.2/src/gui/images/log.png0000644000175000001440000000205310503576707014231 00000000000000‰PNG  IHDR szzôòIDATX…ÍWKo[EþnÇ–ór@­¥M–jÅc…Ry,A,ø lY±Fê¾þÙ ±«.JÕB¤R•BL Žã{}ïœïœa1×÷'ŽYFÍÌ™ñ=ßùÎcÆ‘÷—Ù.UûÿÀRSðåÞ^„§ˆ"€T„H9ÖçYë2EÿèOÿ>ÁO÷?‹Î°·÷£ãÍ› j†ë×6yRûÑKÏ]ŸËʯ¿:Áí·>ñß~s·¢@H¤™ N2PK¯½[WzètZè´[¸ÿÕ¹ìÿÖ‡ªâö;¯bkëCpðE¢@ªa'm¥ÛÆË/îbs½‹ÞFw.å@p£ªÁ9‡¥¥zØ-5R-tj!_n-aëj½õ.zëÿÕ0 afµ½„š&*¯]ÙÀÖÕÀÊÜ„Šáñ ÆI ³zÝ9Å€Ò@­»àƒw_ÁÍçw°Úmcu¥37€Á`ˆä$FæÍÂw*©ZP6iŸ~üÞÜJÀÌÐï0Ž $ÄÉù. (T=„UïaæaÞÃ磙Á{ärƒ÷¾8c拵ˆàèÏâ8…sI¸™ ä¾'ÃøóþAm­y€VÇ0À©¡øœ cÄ£¸,`B 'r~ ™Ó¯E1:K‘6€dN$q’WÂPMÃ7óµÌ`€9Á:ÕbVÀd™C–9Œ“Y&¥b!(¥ò‰aâ8+µ¨ª†g7WafPóÅè2Aš:ŒÇ)ZQ íÅÝÖbP"Z¹r¥$?éƒ\0#XXGÞ~ý…bOÕ$²ÌåT8ÀjE¦§öï~¾—›•¹åÍB”e‚$IktUÍK¸Nݯޔ”Y.²«† i$S?\rö¾A n¹˜ òŽFcÜ»÷{ÈÕ"0ëc©|ÚÞîî3 4‡™A8¹ “8Eš vv6~¶†Ï›ë:“ŒÐ‹0@!¨†ñ8C2NAƒAR±°®ð¬õd®ªX[kƒ”âe5“!1%Åsj0×h­R]uM]^Î;Åü–½ÑPTœEáqãÆúÔÔjfÂYA›0UèLN¦\Æ¢˜òÇÇ#8GôzÝâiæ½Ï; ëërÞ”åçò»è\ÿu»ôÿ†—à€pï 'C§.IEND®B`‚twinkle-1.4.2/src/gui/images/save_as.png0000644000175000001440000000150610777476057015105 00000000000000‰PNG  IHDRóÿagAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ØIDATxÚbüÿÿ?% €X@Ä’¥Gîqr± }ÿú‹áßß? _¾~gøðá ×/ß¾~ýÁðíÛw þÁðýûO†wï¿0\¼xõã‡÷÷“ÿÿ¿¾ €@.X·þô×O?þýÿ÷ïßÿiËŽþÉžýÿÄÅG`>:¾zïíÿâÚÿÙÙÌŸôÈŸ?ÿøýáóo†ï¿Nœ¿ÃðàÉ+†¿±{íõ»Ï _ÿaààäâñì…¯_¿1|:•“õ?ƒ§ƒ>ƒ¥6ƒ¶ªV~üøÁðäác†ß¿ýñbÀ7?1<ûõ‹ÁÆDhû_†×ï¿2<{ýÌþtÍïÿ¾|þÊpòôu†OŸ>1½6 ‡sŒ Qôßÿ–T†Å˜°£!®“ß½ÌÜ¡—RÏÄĘÁ=ÿ*áàrÇŽŽ5C!žÜZûŸ‚ õÏ@Cþ!;++#3#à‹¾ÿûÅÀøó';Ó!^.†W@±OŸ?Á  °ß@Ñöù;ƒ’ ƒ©¶4Xèr`àþGùò(úŸaáê= ×.]@Ð@„ÄñÏ^½ü tÐf`”|iŠƒ øúõ' ÐY_ýøö–â‚ï?>èã'v†?AÑ O80€Â‚™ hÀׯ ?½û ºà;Û7ØÞùæÿÑ3èû÷ï LŒL@þW`@~ê‚Ä@Acá0éˆ?ÐÀPÿô¬d ƒ 4ìÏŸŸpbÀ§/¬^¾axÉÎÌðSEœáׯO@ ŒZ`èÿFé¯_?€¨é?#Çׯþ}ÿÔÅÈ Ò @Œ Ààç÷¸ÇÄø_ˆñ7778‘üýûl (IƒÔÀÎׯ©ð3Åú˜™”ˆ‘Òì `°“Þ2¨  IEND®B`‚twinkle-1.4.2/src/gui/images/presence_rejected.png0000644000175000001440000000160010637222537017113 00000000000000‰PNG  IHDRóÿaGIDAT8]“;h[g†ŸÿÿÏÑŶlt$jÇ*²cYÄŠ3 ¡M°M’]Bé’Щ4C–’Rº: Joì¡Ä¡I†gèÐÄ4®å\œøÒ ÉG²u³Î9Ò9‡Ä4ôÛŸ^Þ÷¹\žÿ]ÜóÜ ß÷O–Öš ªR²hFØÕZ£u€ñ:©uð®ëz_¤Ó铹\†B@£Ñbmíùçkk…%¥Ä—Rª;Œñ¬/F諳gßïÍçg9vlŒÞÞB€ç ›Ü¾ýëÉ›7ž¯ÕìϤ”_ˆ\.ÖA^)óÖ¹s˜ùü4†!pÝ _=Ó41 ÅÒÒ®_ŸëÔëÕ3†¡îªd2Óßét¾9ujvtvö‚ ËÑ£il»ÆÖV™F£mï‘ͦèé aš”2ÕòòŸcZëyéûIËJžö÷˜šÊ‰„™˜!S,ÚLM3<œ`p0ÎÓ§x^—xÜ:áûIeY‡?N¥RÓétšjuRiññ7‰FC '8t(Éèè×®ýÀüü/lllã8û¸®S2¤”–‚×õØÜüÛ®pþü{ÄbÒé7Ю\ù–……;˜¦Â0L"‘(BHËö÷¶·‹ø¾ëº€ \®‹¥h6ŠE› ðQêe3Aðr 2‚j«Õ R©P.ïÐ××ËÅ‹’ɤÐ ‡X,ÂåËŸ0=ý6žç¡”ÂuÛø~·ª,k´-„ø(‰ÒßßÏÕ«—Èf‡_eþŽÅÅß8~|Š(33o±¼üŒR©L­VÁóœKôJ»Ýº>áp˜BáZkææ¸wo‰‡ÿâÆïi·=Ö×ÿ¡Ývèv»´Zû VD&3ƒÖ~>é»uäHÎbh(Á“'/Ïë09™egg­­-=zÐi6ëg¤Tw•e „|æyÎn£Ñœ ‡C!¥L’É8Ñh”¾¾‰»»5677X]]i5›µO¥T?(Ë@~wœý?J¥âáz½žn6[!i6÷yþ|µµ¯.9Në‚”êLJD&3s`"A µŽw: )ÕéPÈ´‚ÀÇu½ªïw•R`÷uƒÿŒß‡Ñ?l<¹IEND®B`‚twinkle-1.4.2/src/gui/images/filesave0000644000175000001440000000034610503576707014466 00000000000000‰PNG  IHDRÄ´l;­IDATxœÕ•1„ E?††Ä‚óÐÌÅŒ…ñb4s ’-w 3† bЄ× ¾|ÆA3ã 48ç¾5¥Ì¬´Læi‡ðÞ‰ˆh{‡ˆ]¥ :¿ä,>ý²Í%©Ml‚… 6yKµ”RÎKâ»dK±Ov•Ç·'NjÒñêè›´×n퉕Üyµ®'fVâÚüE6+È´šäGIEND®B`‚twinkle-1.4.2/src/gui/images/kontact_contacts.png0000644000175000001440000000151010503576707017006 00000000000000‰PNG  IHDRóÿaIDAT8¥“Mhu†ŸïÝÙM“lºÛ$Db—ˆ¶M4Ô@[CŒ-…ÖhD„^"=j+"âE‹ Á †‚x(,Æ ­=„H1¶Ð"Hª!¶„Zšl>ØM»ÙîGfgggæï¡©§zò=ý.?ÞÃû<!ÿ'‡ÇÇý‘¦ÄÞ/w¼|D l³×.ÿñöé©“ëUÿ*Pþ»éëUmúÔÈ%¿–BT„(Αþ^\{½ +!À<Ù„ô¨_ =ªíÛø•¡@= ØyØ(óÜ =ï>såÓƒÑîÕ½/õíx/*OL]<¶xï P<¦‡ý›cB,O‘âö7¢>Z,};*¬‹ß‰ñ„(­‰úì¯âDïÎó@Pe3âÞëØÊ›Ûâñ-®S¤V«K'w5Z½nʸŸC xâ±§Æ~œœs|±¢Lô‡;·êÞžE±KÔ«‹ù$»bCP΃ï€ïá×l\¦©T宲ë7*òñà“Ç~8õj÷HlÍI!}òá¿É=†—V!µ€ÛÔŒï{øž‹aùùÂO™¬í.Šòtgï©}‰®XX­³ÇÜôÁ¼\Dg‚_–K¬Ï_§·#ƒ>¢\deÝã\¥ßÒ£ ÂÎݨFÎ*½Ö Ò¨lÔÐõŠ 3¿Äôo3°–—¸ug3Fêì¦=áüäÜÂᄀd iµ>O¶º†!GÕ4Ò«ª¹£ìyÖ$¹-A{_MŰôÀàîÄ]}'䬫Ōí}´±¤<5Åß7T‚Ò0¡f™û6”m°(Zp·© äÝɤӤX—’]ø}-ÕÜ>²¥#ت5øz-+Œa¥ùN‚€¡² }Ý«– …’¯+€åí³¹köT¢@I‹jÞåÏ룃­t”MlVæÖ¹5ýÕõ‡2I€€ Èžßnk}§eçþskGƒ¢‡áûÂ)åÂÒŸùìÍñßYžüׯG$¸‰kÐh›EbÓ*ùÀ9b§^u$HIEND®B`‚twinkle-1.4.2/src/gui/images/kcmpci.png0000644000175000001440000000454410503576707014725 00000000000000‰PNG  IHDR@@ªiqÞ +IDATxœíš]l×ÇëõGü‰×dicPCìÆ¤ iÚHQCUêR!RZõ¡¥¥i«’¼´R‚BZ…—(}h#EJŸŠFm ­ú$eÓ2`\Ç{³ØÞÙÙ¹·³3;wfÖ^§Ø«éêî½sçÎ9ÿû?çž»3)%w³TUZJË2•V Ò² @¥¨´,Pi*-ËTZJË2•V Ò² @¥¨´T¼öÚÏ‘0ÎqèÐÓ@BJ™k’@ °Hê-žX§àj³{ötÛ'&4NœØ\bK®áII4ª) µµóMòYþOÁfÀÀÀBH¤”<óÌ„( |'ðÙµÐ-ï ¸u5ÀK/mïÀ¤{û+¯œ:.¥wUþ„péÿ[–è·Ú!¹š~ñ-rÙ<Ù\ήGª#ŒÕýÛ' ÷Î9}æ¢0¶Ä5çï蟗[WìK:k-»Ý4Š0=ìB²ÊTJ~ áès!½}mùµôÅ¾ÍØØñxœx<Îìì,Ukn"zæ7¾»¡îú>óÙ…±’"øÎòþäI&ÓQ¤‚(nmÅ€¬…ÈË/Ÿ* 2§I†y(°YEñzÁh‚¦Èµãw@¯#‘H044D,³Ë­ªˆ ó¯|w}»ïÝ«Ìé÷<)á_Ó&RQ›!~Ríî(")½ýA¸lœäb~ÀVNJxô¯ðÕ¿y'wÎð‹šcùMlÕ÷“H$ìÇÑõ ”A{kÎwÇŽ2’*2ÆÁºÇ;vòøÊ]÷( Ëp7¬öŒ˜dÔˆ(>ß…†‹þ°äºnŽÍç‚èºN2™T@Èd²Ô”áóRšÈޤ†¸øúüƦ>Å ­þ ½ pú¶€­ÕûìvxUíþhqeB³ÚÞ܇Ь¯B×uâñ¸½ú‰DCÏPUfÀ“”Â6H¸rù8pô uÒGk÷}î)y _Ÿ·¦ÙQh_¯ðæúç]¦²GºNsM‹ðÆèòŒ/0@–0Þva¼s” €´WÖ)„¨1Ä©ÔÑbÄwú¢pÕv·þ@1Ò2ÈÉ,?ã~žàƒd³Y³ eù©ø-Ù:³}Ù¸Àëòç„kÎ1@¸ ³š¶Q€.’ŒäT?”?Vr‚B­5'° ‹U”6^Èy. ^b||\q«L¶Œ!¾©.€D €¥’Õ9‚ ×,J aj-%l®ÙÅŠª°ºï‹¢Cz„¡tÄ^é sk;ºétÉí³a¦‹úe4M#N{J¦.£&C.H †±@ø¹€2iaLoÝN¾PÓ罯`„!àj*¢¬‚“!WS‘¢_[9€z2[ÐuÝ6XÓ4»¤Óiô{2j6*Ô¹ ãSÅ\´Âa°”ð»X1ˆI áêõì¹|Þ'>¼>r`ÞôöPèmt=ï»úš¦‘iÈxs…½–ñŽLpnDÁ:,Ú£2Àw](Æ5ƒðürû¿$‘nÌ3³j=”A×%“!]¯yâí®Žà\&ŠLðe€#¢:û?_À“~µ²0öPßñï ý^]¬9Œ/ €óAÅ~” ÌS(kkûl´¯iŨïŒÄcé!Å•”€'@XƸ®÷ÖyÒV¶«®—P0Œ! Ÿ7Ð4Ísìýɺ#–© ;WÎÙ·&¿Žkú°o i÷µ­æùÏ)s–+å'B>é¤Ñ}öù¼4÷m'‰D‚ }EýjêbõJ"ä.­F+_lY_6íç@*µ§ñ~klÞP`åð/\ئо&öœVæ¾±y©–3vP}õsoÙ¸W?Nsnü,Ûo³Ýv_ϾO@q ó@Â[ÃŒ~¶t† UÃÓ­û8;{’©|TÙçooò`wA™¤?°™Ñ™aNÝø'¸}ÞgŬó‚uýÇ£/"Ú@„¼ûþ|ûü‚(µ ZÙßùG ôÀaBv†ör%aRDm„„XÍ«ºÛijü¿`¥ÃN±ðÄ‚a®¤>*f‡BUÐImçöé\ÁöÚ0›ZÌA†fl Í¡kçÜ%˜Ãø…JY™`ßšÕ|?ü$pôë§ëÙÓÔ@{ô?[µ­öIV_¢Þ¸ÍÛ¤>'YóÉ1¾ÛÒFçÔ1ÖÔØø•ƒ¶òš 3vŒÿ´yñ½?ráã1ªñžk‹€wlml ·qC¡5 Ò´¢ËlêÃlªï‡Æ|ügÈÙÒÚ©iˆ~HskLÓ\"ÜÖ_|1 3Ãô¶ôÓn ÷/`¾¡ÊÜAûü$دûKü°ð„âH¸Â⿊ÏžøþyÀHÓø‰¥|hY ˜Iiœ¼j6Ò ˜˜‚dáÖé)ÈC}3ŒMÁ=iÈ6«ã¦ý–LÛ÷ΤÔo–RÊz3cÛ¯Ï1ÍiWûx‰q~ýî{—V|wωÊü¨`æ«åÅ%8-•ø2 ±±ÖÙß,¢.JpZ*ñeÀáÃçp~?ŸÍ¯ÂJIÀí@;EºÇ€«RʘkÌ’)¸XbÙí@-ÐŒI÷,>ß þ_p·É]ÿ©ì2•V Ò² @¥¨´,Pi*-w=ÿár£L¨v¼ëIEND®B`‚twinkle-1.4.2/src/gui/images/sys_missed_dis.png0000644000175000001440000000145010503576707016471 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÖ;vxD¹IDAT8Ëm”KH”Q†Ÿÿü—¹8š¦#š3¥S*æ]AÉ0º€™TX¸h‘P+[¤YD‘EتÚÄØZHAeкPA™£i¡h)I:yÍ™9-B4ýÏê{ïóññ½œ¦ÇbO<$Œ9u)ê“ï³|%ïÉ–a$í¯oŠMŸS®'/kšd˜ Ÿ) Ù*÷m±xwýSWÊnæô!éâØîÂÍ9‘lØ¡Œce†!`dX£BQšÈøI"AÖâ`ih®õ[u©ÖÒÝ+Ê$¿ cç;F‹ ^^/Pp°®qÞÃ!+äò´k&@qu* ‚\¯‘mø¦¢fôÓKü3íÚây´’Ò2 (ä+Ç[Ã)Sv;iF‹ÿ<¨~½ý´=¶¶8Ã@AC`ñ 7Õdr‰Þ1 !z]Ë9©"ÃîŸïòç¸ÉWî`á¡>111 ÒG@اvO7¸ò¬×¨ð; ~ÐFýèØ0ÐÑÑÑ袳GîÒÛ›" ­á,¨:{ R f0Æ(^2€a¾DF®ÉSÆË¦ŸÐ±íkk}º›WŒg :Ú¬-Æ%µ»)ðqù¥›J.žó›yb"Î<Ú‘`T"P^•Å8‚\fG¢  )›«ÍïšÔ$:­øªÓH¢´E.~b‰ÂJ«DCsM¥KA¦åýášãËë/¿µâTVmI3RÌÙº†N÷ä¦+æì‰Š÷4FÞÊ÷²9êÍK’«ú¡ûÝòô¯eû³Fá¶[7ãeåî$@÷Öííô­Éœ2´ª}ñîáÍ­I€iúj wê’½(¯f2þgéýN(t¢IEND®B`‚twinkle-1.4.2/src/gui/images/filenew0000644000175000001440000000027010503576707014315 00000000000000‰PNG  IHDRÄ´l;IDATxœí•Q !DuÙÛÀèú^ËýÚ…-Kúk (£W S¡ˆÀÝ}™5²PDp5YEU6"r`‚=‘ ¬ˆ¨”òõ™Y-[RàZëolÁSàÖÚPëá)0â29ð› o³T*":à>à…Ì+y <á®?o›mT3¯Œ¥IEND®B`‚twinkle-1.4.2/src/gui/images/mute.png0000644000175000001440000000052710503576707014426 00000000000000‰PNG  IHDRVÎŽWIDATxœ}”ёŠE¯;¯#¬&HùØ&´€Ô¡ÿRû‘gÔˆ{g˜Q£G0€SUXbïͱVg­v€¢º½`ªêcHk%U­iž"ÏþQ~Ÿù=&Øù@XCzk {R c7ž½ÚxÔä 0Dü°î¿ÖõÉ4!¤Dˆ1"%‚ȸO@´õM"´~Ø^òÈ>¼jÝ÷îäbï5?"¥¾¹”bz–¸'æ3ù†Ä9çN§;ˆV@ÓyžÓÚø6+È”RRÂXØ 2†EÛo13B$þ^ú*Z3!¯ëÂq¸® 9g8ç&/ÌV2UBМ³æœ{¥‡0UºeîÝØ˜Ùnh1š ­éÏËK˜n(ŸÁIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf-star.png0000644000175000001440000000036710503576707015357 00000000000000‰PNG  IHDR"":G ¾IDATX…íÓ1jBAÐ1›ØX¤—4bio,R™•$=¸7!bg“5DìmÄ"…JLŠÿ7àSDðj¦˜ËãÎ )¥”Òe«àãSª‹—r½/Ù–ûÞQ?Ç ÷`Š6~±C3ôÐä†ÜáKE+[|â9i6øÆ7¸Å_ÑA":øÀOŠ6Fxà C<i¤‰‰â}LPU\Ï­rm:ìdß·zäù=ñsì )¥”ÒÕø”"ô”’åIEND®B`‚twinkle-1.4.2/src/gui/images/missed.png0000644000175000001440000000124510503576707014736 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÖ;;3§g2IDAT8Ë‘OHSqÇ?o›ÛÜ–.sKi#ÑþhQD=/ué’ž¢ŽÂKuéjÑ¡@¤SPL)(¡ƒ…„Ø"Ðê QD‘+mfsîmsïm{ïíשˆ}ïßÏ÷Ë÷+ !$‰õtúŽé=~ÀÒk“茫0‡¯Ë„¤R7†—¦ôÄû–‰cÈç‰*•¬h6JPWXȃ÷zZv47²B ï?-2U y­4€šI"9ýDt¾Dgpø[0%ašXJ¤ãóTÕm§`ÙÒØ†ßU ¥ª|µ²EäQÓ)f‚r—‹D,ŠÕîè_wÄ“}‰€]*L%—S^‡¤R_mg|b-§Sß¼¯mÝåe„5-ï5ôVK‘Ïs‹ÌÏ|`cmphørSdMÀ…L˜bAÖT¢‘G`ååØþ`“âpW„€Õ_è ¯Ïmôæµlg*­bè9® ^=dCõf|[=¹¶Gùpö4Ô îLÆ |KfÉçó¸+«™zz«ÕNpסÐã«»#¿<’‚›Ï‘?¾ëÎfy|t„ýgÈNÒ¼½O™ÓE°å`èÑ•ý†Z “g'ò­ÞëÜA¦g¿£cGù1Çäțꔆ½GZÿ6ÿnpnYÓ `èM-‘˜›&6ýׇ?Ø<ätW„/Ö)«íeØ–›‰¼Š9;mº–Åéñ*­‡ODìåž¾Û§¬‘5BÐÞÞ“„£—øý,‰ú@æpoyIEND®B`‚twinkle-1.4.2/src/gui/images/reg_failed.png0000644000175000001440000000166610503576707015542 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÖ6$ kßCIDAT8ËuQ]L›e=ï÷~]û•òvý£c]Ù‰ˆA…ÄenƒÊ"qÙÙœ»7záï­¢Ñ`41juŠ^,l™Êp SDCª-fÛ4J+´µ¬´ßÏã ]‰çêyΓ“'ç`×› .Ý›À9÷>Ú¡žÜÌ]vãÀ´_eàz²è™ÕèJRå8tL¬z€¼!Ô¼ü¢â`ŸM©Ð+Ÿå?÷Ébñƒ#ªy~D¹qHWA¸ð‰/üW³éÝto³øð´†¡Ô^Ù2úc´Ò饾›”aL“-)±Åï<ÕcY·¾Z;¶mípÛ¾muª“c$È^Ýn(÷DÛjnshªQd‘M b$…2RÜ>¬Ùq¸;ÏÕj3Ô}PhÍ]èR]Ò§‹ˆ/±ûbíµà$ÀÈd±8—1³Y:!p\ºN"ÿµŽ*Éx§‡ÕhÊÎË“»ò«—)µW¡R_Œìã TzÜG ÁþRb§B¡°€Àú8¿>Ôå®s¹T·ÖÜ·ªºÃáK”‘~«€»ö‡!˜€‘É"5Ÿ=«Âõ¤Ã0úfiQ~ç§c5¿ÞÊÇ©Tn¡b¶…–/h6ê!{¸™ì£12ºý´ätmL#ÓŒPnÅC¯¼$3&h®ýò»W>ûæûAú­U&㙲֓ݦ… §ÙçöPq=LÉ_ôõÞá$†­ø(ÀF“qù¶g㉴äôqçk4{ñ ýpz×r_ˆ÷lÖ•aZÃÐýºôüîö$â02Y$ç2ø&öŠi4Ä~ÇJîߥÁ¿¬‰s ¼¢c3:˜eb@¯UÞŽ¶ÕŠÒFU©¹ \§¼Ð{ݰV9MBòƲÕù`Ú÷½mþøc@Q°Lì×¼ü½úö°(ÃÈä°øó?px –¯~~¦ðÓºóp4Ýíæ:ø#M€Q ˆ@÷)(“ÍšNåF ‹óiÈÃÆWñþò]߯rÙ25Ö—¨Ú® vÉ`uç×ÇÿÈ,À”úU˜œ¯a43â4žîU†·¯ç­ŸŒºSgª ŒùÏnmaRïõ&>ˆ-øÈÇ;Õ—÷ˆÒÎ ñþÂN0^)ÈEIEND®B`‚twinkle-1.4.2/src/gui/images/hold.png0000644000175000001440000000075010503576707014400 00000000000000‰PNG  IHDRVÎŽW¯IDATxœ­“½OQÅóvf‘þzZÈF‚…öj…ZcaABB"…ÒR ‰ÑÚXÛ …‘VM(¶[¾dùp‡yof®ì¸ë²£Nr“—Ü—sÏ=÷^D„ÿ‰—Ï—¥(oS€Å…i¿Ÿ<›¶Šþ^XÁßa‰Hß"mEÿTS¤è¼ê êRXàÏÔV–æd||”ÍÍõ­=Ü#Ÿ0<¦ÅÄÚð+lÑ8ôXý´~¦_–ˆ0ûtF=¼Ë›·ïYÛø¤æÌªÍf„»S§ZÛí!ëÚ£û÷îp{ê&†Ë‘ëãûûû‡Ô·~²½w€H@ed87¶Mš%Ú¤):6h£ñ¼ß‚&Q¬É²”4Í›œÈ‹WF†¥ZÛµ.lö«×ïºÚˉì²Ãààˆ#sº J%ÊŽƒmŸD?tµf—††®b’¥,Œ1¸n@–eˆ¤}‰Àü‹ekúÁ,’ JY(¥ŒIˆ´¡ì”8ö<¾}þ’Þö«k³§nÝ…ùÇ„­:Ö¸®OõëwŒIXýð‘k×+}½ê9‘ÎÑvblr¢ÇàN\Ú­ýê qôªë-IEND®B`‚twinkle-1.4.2/src/gui/images/mime_image.png0000644000175000001440000000354411001732757015540 00000000000000‰PNG  IHDR szzô pHYs  šœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFÚIDATxÚbüÿÿ?C~~þEµßþürÄa„P0.02‚yPA8 ¯Ø(ÁÿÿÿýÿüÙ³+S¦L± 8##{aa'ÀË÷ߪ ¹@l€bAr7ÃÚã¿LU˜x8n¿øÍ ÄÍÄðäÍo†?ÿþ3üþûŸAR€…áþ«Ÿ ›Ï|bøùç/Xì×o dÿúóŸáçß`60!r@þ¯?ÿ 4PÝÏ_þ123\ïÓc`„Ú @,È.izüæ/Ð0 !×ßÿbø wf êŸ@ƒ¿ýgcaŠ3B£D3Âã™`Ñå3‚hºÿL ÿ™ QÄ‚O:¬ ÿ€¾ý Ä E¿ÿ23ÀŒÿ t( 0M7Uæ; ”~@êÁøÿ?„ˆ‹1@å@jþÍeffaàçdË@± '. $߀3ž˜üyÿ„ âÿ@$"¥b&&&`” ì RШ/A˜‘ 0KþA½† ```ee…›@8ðë×/°666°«aŸP‹þüÉðå˸e0‡!;GügàääšÅ ׄâ€?~0¼yó†áüùó .\¦æ? òòò `‡ þîÝ;vvv¨Oÿ¡ø”ˆþƒhp°í¿¿ oß}dÐÓÓ…ë€BqÀ7„……444ÔÕÕÁ†ñû÷o0 Bˆ/Ab GqqqCä+Pˆ€‚$þçÏo`"f`xÿáã/f†/_?30|ÊðõëW^^^¸„âYYY° (Y ƒaŽøû÷/Ã÷ïßÁA/"" **ÊÀÁÁvHÍëׯž;ÌrP°ß»w¬î+0nÌŸÇðâÅK;;SK†k×®Cáíûàtõçï?x.BÄ„+#cX”€¢¤¤pˆé¼¼b†»¯¤´Cú§­f8x`8•?þ¬äPH¢—0@(!€÷0>Ìq àÅû§OŸÀ¾Ú±uýO² Ó$Ä8dŸð2ìÛ?‰ÁÑÉZ°hƒ• ¨E.S@ €°:Ã|K' 1P‚åäâaàáææo ߨ888¿3psqÁƒ¤T®€Òˆ 9wwwŠ`yÃB–Í@)ýýû÷ žÞ W¯ÝbøúpÇ_MÎó ¶1ÑÀ´ñ‹››l(´@éVˆ¡G@áŒt总wï2HHH€ ­¥eå ×®\dø ´È9& \çÿþ q¨Ð…(í€Ôò22 ôDˆîX€hfPpJIIs¨ E…²ª8ÎA¡Œi å\`KA9䘥Ø!@¡89ëaà G€²ÞÁƒÁ¥¨%,Å „²T4ƒ,YþXÀ<ÒÍÄ‚-Ââ d È' 1 +ó= Î’âÀ9ô@¥ä‹/Àiä@˜ïA!rzA@,Èu7¨ÓÓÓÇ5ÌÇȾ‡ù–¢añ «ºA–€JÈ‹/Â-‚E'ÌÒÙ³gÃrØR€ÂH„ DËv `ldË‘„œs`…H ØÔ'DäPP Ò¶¦¦æíÌ™3#f̘Á@(…(ÑüGé0 4FC xøð!8`Á Pz©««{ ì8…o‚ä£6äç秨Ͳ”^@Ñ«]A>¥›ÊÊÊ·“&Mr ]‚© lm>J¬!r¨qJ˜õõõ Ë]€Ò‘Õ ­z?°¢”=[ZZÞNž<ÙÝr lqLi€ôÀhù¼»»§å @(i¢%:Ï'NœKp—p© FP|åææ^SSSÓDoV“ bXR¾:uª#Pè2¾´@`S¾ °¥êŒ7&Pï™ÂŽ`ixH]!”X |!Æ¿{±ÇIEND®B`‚twinkle-1.4.2/src/gui/images/mwi_failure16.png0000644000175000001440000000160210543701724016112 00000000000000‰PNG  IHDRóÿaIIDAT8}’Kh\e…¿ûß;ïdò˜ä’æ1™&&5IKÛ ­¶¾RP ˆPß»(,]ÔG‰ )®\)XmÅ´F°iSÑ6Ï&“„˜Î{&ó¼ÿÜû»¨†ºé·;¾³:ð/+»Ñ> nC×õÀC^q{÷s}¢–ÀY¬ô£õ†æêªuæ»Ø^{ÁS}ù•ºZ¸5¼{à£Úf½*}þ±1/[FÈMÃð3Žùú«ªçÎt+: ååÉç7+ß¿ûöÈèÄøÂÆçÚö=ºÝƒ{}^ÎŽºiÑVúÐÂ×QÕïŽi§. =ÖÙœJYG"‘3i®óy]%YÜoÒµ¯—Ò±S~Ÿˆ‘ɨ vúôèñƒ#G:ÛjÌúP­ÏãqaŽrBGÙU–Ÿ}„p0Ž®2‘åÚ•4ɘe¼hÕE©dèí u6†>À‹nä ª¶N©XfnOö-9ÃÌå8+Nstàã“QUËKÑ_•$3›¬­%ÉåÊØŽ‡Í¬Åì`3=:q9Ï0»Ý ’¾A„0œHÇJHȪg,Mcšø|n¢Ñ¯'Yºo{õ ¤ƒÎ13•$|q)%MM44ÖœX^íÏ ¥Ü“óóÉJÕ~:#ÛPÃì2!_„|™k“qZ&3Tl/Å’F¾`ÐÛkÞúÊôô—ÖC}‡žlýæ“¶ÜùÈxš»î c8v*Ç_—bøF38ºN¥¢S±ÜT¤F"Qbu5›5F ã‹÷òzO3Öòt߯¥td"Í\>‚:·„¥\”‹ ¥@JE,V ›µU"ž¯šÛýxCzõÍùUv<Æ¥2‘æúåÖ;§°Š¥Ù¸™gc£D"^/—ª E©‰Â§Ú/‘þ+B‹ï z„2ñ ÌéHeR¨ïàüÃÇ.V«ú˜ãˆñ3ìçŒÔ¶Û/ØàÉ­¥ x3Sq{ŸÂ04•ºûú«ßÞ×(ÌŠþ%Ó<ƒe9XHé å›Yí,máö}wë//ï²×oÐþÒq~ŠMÒrÕ9·>5{ø0k9î€ð™«;ÚnŽÔõvïX(&ýM7+R³Ñ·ž«.nÞIøfÁ„tz¥´IEND®B`‚twinkle-1.4.2/src/gui/images/sys_redir_dis.png0000644000175000001440000000154110503576707016313 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ %:ðwAòIDAT8Ëm”Kh“Y†Ÿÿ’?—¦icƒ­—i¬µ6mjíT«v°£‚%›Š—‚¢((h])Š.„ ºDg1 HñθpaêB¼€ÖÇÑñBMzSÔ¶DkmÚ$&òÿÇ…S“³úÎùÞçðñ¾œ#‘c픃E#»V_,O½Æçd¬ÃüÖ“²å›ö@Áaߢ钕áDøÞÀ™‰Î?’“]å{ù:·ýè’# s«%/Å”ªÓÊõ¦Áhåã ™h)æÄŒ­ñdoÞsé±>šÒU(Ì‹Ö|zYÑÊÌ?,ÖF:>š+—2‘þýl¼"eÓIä¥õ›¡€<0—‹Ý÷;ëí¨TYm®+ÁÔ:ò£6àøA \ÿî¨/–1y޲Ù!ëÄÐpVŠ{1SBœíRCë TðÉ|ƉÓÿ˜{²FBUj\iA p±w=C)$#¼{ö±½«¤ÚS‹g9\MwYÜv·â,±Ô‘$Œ‡B"tò “UxBªk¬pØŒà wÐ(a75làCl š(»CÛ•ðÝ'’«ªò5dT$t®b¥ŒYäóEøYÁLÂë¼Ü:R‘þWzæ•VÉ ‚03“bòÐ ãÅ‚Äíèã]{ñÉà&®ý?¨ý8Ï©1BNlXI3L‚ bœ{}®5t ‘™´1òßÿÞÖúpH˜ MœQúñáá—m~ÿlÒÆ [Ç{¯·½I䳃ôñ”BªŒ¿H¿Íð=3„¹ ¬H”­œTæÆß<4¥ÌÆD ##¨.Sç§{rŒ„ì X‘$èŠ_}?FL- š3DßJ[Ó2·Œ Â…Þ#-'êÛÿ & ­V-ÇK^s²[ ˆûbý5Ûì¯7Tí=Š^q>Q2'K®X=è¿Eëögžj¾-·o™Ų¶,ÀRÒ>¶¯ÛÛTðÝ· 8µŽl¼‘ØlÞíZ9×ôš9-“õmæGC~[ IEND®B`‚twinkle-1.4.2/src/gui/images/cf.png0000644000175000001440000000116410503576707014042 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  d_‘tIMEÖ ”ºnIDAT8ËÍ’;hQ†ÿ{wfgggfwöÅnVɈ² P4 ¥¥’•€ŠDEÁTŠXXˆXˆ…M°Ñ"ˆFERX(‘!M‚EÁ ìK3™ç{ÇbI×W§uNq>ÎÎük‘ïãlDe*¡P·™­XŸº‚§õH0¸¡ÛºFÄi­PÆ¢¤jûû¶ÝZ¹¬íÌ(y3®CÒ¹·\·žÏ·Ô›ÞÑè!»MüÞ ‹L6É/ÙÙÛ1¨æ6mHÀP»lŸ ,Õ]<™]mÜ™-^f<šÀ]~ н2¼±q0¯ùí…vÑrB9ÚZhéCÚW)› E–àù̬~zñ.}’ÁcLêQׂ`gºûÕÇÌu÷,!¯·Ó›§1²«b]¨ö§ÌlP4³lÄÙh;À3NÀý= Ò)ú“z°n®Öldzî=­t¼ðø@)!{ ˆÑ`ÜߎZÓêùº,ÇŒƒ*—t#­*AHÄ- eE°Wpßš£?Ü/á-pç†!;(¤ÆË²×…„=ÁN“ߦddɈŤ«©´y¬”ו(:¶@§Yì€yòǨí_È€Hçµta\’måsãmÄìQLUßüú½ˆ4*»ç<ÂT•ÿ=  1Ⱦ¬ ÿú 0ÄÌÊøIEND®B`‚twinkle-1.4.2/src/gui/images/sys_mute.png0000644000175000001440000000246710503576707015331 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ  ߤzÁÄIDATHÇ•VklU=w^;;;eÛívJK[`»."ô…©X©`¢!A hUJH|ñCI $$Æ`ü¡‰+àEëã¡Áò(b[-K!ÛBiw·ívg·ÓîcæúåÑZ»L2Éä|çžs¿Ì¹‚x mw)9î/…ÜêrFPìÓIH| E˜ñ¡1ô¯9#¼ûœoy÷¿cHºâ¥[Ϋ4©Wógº6=aÇ¢Y,‰Ä“¿wêØßÃU°ßjô­ýåÓ•'Ò6(ÝÒ&SÖ²9yžWž‘aåþ“—4Lìk£á·À€¿\Ò´ÿ¹^.½ùÓjŽË³y1£­Ú´ºD4]¸‹­®RÐ2³:®é;kkk·MÚAéË-"X±oã2ÕîÍc°¼Ìq§ÖЀû°#Íaø:|‡Ã1×HcI:T¢lwX „†Ìû ¡¡Ô8òG´¸Œ…ÊZbfU:îL™AHK%dŒAr9š°^a8w:$a°è`!p÷|i*$>‰WÇ ·ÓC@fq®ÿÒWrD§¸2àÄŸ¬q=ÉçÀHÅALý&·¨\Ú[]ÉæIDÉÍ…D2®‚á°‰¬<•j=¿«i-¢¦j+o€0’¸寛;8Ã4†«kl«]’-ñ’ÀL @”Ø@‘BÍ­Ãh æ!ß%¸›˜ÙÙá¾îbEv 7ƒ:TæçHO[¦¸PXúâFáÀKÛœ¹‚¢€0 aJ`Ä{°ãÝ]87Z‰^™vá;Œ$Ð|¡c”¿Q¿nV9Ì ƒãÚѦÄÁ«cnÏôáb—‹0 Ç$­+Š=ßìCE¾W‚}à8Š|§VÈ“;¯…ü½Ãh¹Ø¥¹RmḬ̈œôù|:{oÂÚ;ÍCÍÍ©Ÿ¬xh/³ü ¢8päu8+æf ÓðëõôÑ8F“&†b ø{£hiÐþËÇs̶کÜõfŸÏ§;¦C£/D[OÆÝþ‘ÒŠ2vZ†¢‘ã' 'â1xäŠ ¦q6tûBÇ>¨gÑÓö“?p¥yÃ<çÍ3ØH§ÏçÓ'MC†Í:ïL£ªëz!=wl6]¼¶…Ö¬7éÊ ”._¡ï¿ý ]4Ü_Lë6Éû'ÌùD…9ʼn¹9ªneXW â€s N®„®‰˜;·Þ²A°¢B(ÜÅìâ6XXÆ­ÈÊfa1PHÈvÛ±zú5˜…IR DaD€D0¿œÎq¬'•2:ÆêL´’÷ ¬âEñöo¢æhgwëõŸ÷£#0Í~# DÆÂGdTÎcW¤}4J"»äÂé)t8V@‡c3i ;~øžØá)â–f;„ÂgŸ¿m=™•Šjnªëåt8ê¡;·Ëg,‹–ÁúeâÑJu½vµ;é ë,‡$‘äßCKK¸­?“õØ€J#møÎ9Z  E“г,Ëï}ÇzfDSé_ȱÇ+-¯MÄλõyþØå?2ÍÞN]ú˜X7©À3ê'{¤¡ÝoÙÚ½ElÝžIþBDª*êê}öHÝ:ë‘ÉwC‘½EÌf‹`Éz+ÍT—8ß[dyz,þ7ñÙÞ"+IEND®B`‚twinkle-1.4.2/src/gui/images/package_network.png0000644000175000001440000000400410503576707016612 00000000000000‰PNG  IHDR szzôËIDATxœÅ—kŒ]UÇû¼î=÷vîé0ΧíÐVú€Ž F‰!-•&LƒH4â#ÊK¿!!?JŒBˆñ 6ÆX†­`°5XH(Úi¡Ú™ét^¹Óû<÷¼öÙ~ØçÎÃ)ôƒ;Y9'çìsþ¿µ×^{¯-”Rü?›õq:ÿ~Ĉ•¹3’k"eú¡Až 7ýèhirüà³w¾$ê#z&>J¿¿•âjê¡ÓãÉv)TÇ'%$]A$aÊ3(®ŠþÚ˜Ÿxfï=›_¢K|(À‘˜ö0R{Þ;ß"cØš› î[ÇÄ<´Ù°¹q㜜W)ÎŒ¼u.!Ÿ«={ò¥=ùÍ'”Ròc¼E×”›Æ¯½ ƒIÆÄ²¡èÂåÔèÊÀÙæ(7¡êA¥ ²Jqn"`´žš:ü§oþå]Ç>h4Œ‹‰øþ@¹,LÍ08#MBÀ¶Á²Á³ÀÍCÙ•ÑÏ3Øئ¶R …,íÙÌ•ƒ_}aí wlœ‹i­(C{ÛûÆæDqVš˜Xé Út*(C?7Ô©…¢L¯!z·|óÉçN!„}I#IúÝ¡hpÌ3!°nú èàHP 8 µÐX~ßj=9¦Ï%o|løa („0?`Ê÷þüftß´´IèÍÃÐjèvÀˆÔ/DB,AJ‰ö^*HH¦c*B{ýÝw?0¸BqQ€Ä¶Ú7‘Ë›¬k‡­à˜©°ÒÂqMS1ø´) ^Úh†(N4@¾˜áÜ;%ÖìøÎ÷€v`a–-D/n1]‹¼ [º…Å’>©Åca S!4|8ëC­ A Q ‘Ôß‚…êtµmÝMÀj  Ô—À±XÞzbBÏOlú˜¦þAËb•†Ë0߀rC§^­ ¼@{ïG"Œ •tJ)‚zÄÜT¼óé€\+ ^ ‡N V¬¶å q©À‹tž—=}­¤5?…5D3ÔYÐjsã5Â@27^£}àÚÏyÀ^IcÇ\)&“ìŽù×,4å’Ø+hs `-hj«5¡îëPxøá¢÷ë/ƒòx…8L¨L7pò=@®þ…9ðÎH(1AS0;°ß¶9U5Øu¹ž`J°õ2ã ¾^NWõû©ç^¨'`«½u¸„ŒÝŸ\…çK¬\±Ȭ¨6ÍZŒi „ˆ‰#fžC¦ÁÎ>=ÃâªîES:A A¤S±ÕVòÞh ËLŸ«Ó{EP"Õ5–twÙøa,N)އ9JÅw7êoe„@/<Å L^Xî5@.òÉY1†TÌN6èéÏ3°©[Ÿ³ @¡*HE½¢RD¾d«íRm8ä²éè,ÉË¢»(žÈ„ÚœGi¤Ì-»:˜/Ijµoî#[p¨yЍ~áßI’(¶_×N[Á$c ²ŽúŒ Y\Ü%×»oíä‰×ðÔ#W°iƒ‹)àôˆGOŸÃý?XÏÕÛŠ ]ßMiô­ƒ©¸·@)¥Ž½üüS×}¡«æº&•j ‰.4[`›àºÈÚ{ׄ¬ }×}zŽ Ž%Èd·­‡Þî ½—gùòm}d:3Þ±=÷>‡Þ¼Vu´l7|þÑ»f¹Ç¿qÇ:^úû,2L0MiL–ÐÛ²cha×Ô@VúέâEÐÛ“ÁH •ª´;úò+gMó@ÐÒ\ ”’ÏÜÖÿ¸Ûe¼~ßýÈÌ… Ç@'¯‘ 9©µª ‘¾o¥i˼Øàý±ñïý|÷€Y ²´H½XMèúíOoŸð“w« I«ž–%J[”šTz™^裯Õ@ðÆhuìŸ}åIà<0“fÀB[q0QJ%Bˆñf½¶»ùíïݾ¹8´9«–àÕ7kìj#H«Xií˜2QH©¯þqüüÛ~rÓ£Õ³Ãg€  ª”Z¶f~`Y.„p€Õ_|âø#Û·Þ3öÆ$û÷Ÿgˆ†€þ]ä*àSëslXï²f]Ž’opàdè?üÚ_^ydçžÔësÀ¼R*\¡óa“´Š-nÜýÀÐÀ®ïߟq»¯Ÿõòsã5ªuÉ@'Œ”tß®þ6Öo]åÕgß9øî ?Û7ùúsï£c>ƒŽ{tQKÍÒ*Ö:€ÎÁ;ŸÞÞÖ·i‹é¸•$"õÊè›gNì}ðÐD§Ú|zmþW'£ÿ€hm¡Ù&—Þ/C1z‚y©ù€üŸÎ†—€YØÓÓ–¤ñG=ü®hüµuÝk¥IEND®B`‚twinkle-1.4.2/src/gui/images/fileopen-disabled.png0000644000175000001440000000075710503576707017027 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  šœtIMEÖ39AäØn€IDAT(Ï}Ê¿KTàï½{æieŠ9r´YPA”@„[DAc¸45ÔÐÜ"4º´ÕÖbƒE Šd vêù£¤:ï×{÷î½Ö¦¾ù rÿÜqQKî³s†Ä’Áþçśիö› –…ÿîLûzéÝÝéûç£g5ŸÌ9e3ÞT¦ÓÈ…'ß(J\»÷f6šË<ɨéøjkwjt\KC.ñòãÛÛy…0ªŸRtà¸éѲTW(óKùÊé©Îp>uåÖŒ¸ Ž ½òÍå¥[«Ý(*˜·'ѕʬ;4®¥<°</F™Ð’CrMGêÎ*ÙÔ¶-„Ý÷Q¦®ê©¶Aêöý°gËÏjØ_Xˆ"KJNªX³ç»»vÕ$¹,¨X Y1á@ͦšTâ·D¤À`þ%Ûˆ¶ÑcDæ>¹^m-­`çÄþŠ4ÚtÉQcšš- M‰™Vu15MèÊ$R±XÛz5Ÿ'ÊÓ×鬮\G"‹%:b‡ÂFî/ Ó´jãdIEND®B`‚twinkle-1.4.2/src/gui/images/conf.png0000644000175000001440000000057210503576707014401 00000000000000‰PNG  IHDRVÎŽWAIDATxœ­”½mÄ0 FßÙèÓ*¹6©¤êê”7D*i„ì È™˜BöÉ:ßäÃ"õLÒ¤Áèõž¡¤tó Õìpó@DL+K‘¥ˆÐ²5?‡}>wئVRŠ\Azœ†;´2Gw ˆòTÛÁ^¶æÉ3@ÞEý²furo? ¥ÌÞëž{D®ã§Üükîðy’À¡yàûd ÑHZÊÐuꆜ×Ô²¶vߨ‡fP³^" ` våÞß½T»iÔ@^AÐRÂy,e8~¥^ƒE«€ƒLK†‰AôËòÖ#ú>ä2èÛŽŽP„Y„)*„eÅÛ{ïæ·wÂÔ÷+½Ó-Ÿ@fëhè ‹ˆ3+àÜÁ–çQÙÍYü°‡ÕqîÅyÀ¶gïía–gزžíV÷®¸}•ÜýU¿R¶RË:HIEND®B`‚twinkle-1.4.2/src/gui/images/missed-disabled.png0000644000175000001440000000063310503576707016503 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  ÒÝ~ütIMEÖ ²çDÕ,IDAT(Ïu½KqÆ?¿KìÒ^J z»­†—æÎþ€¨­Ñ[û¬¡$¤% šÃ¹!/hh³Ö@"ƒ2=<áO Ñ ž=ëóù~ŸçA¿Nµµ´’px£jŠAÀe±»e“.ŸKƸˆ­ yÄ£=h¢R¡ÄÐCñUfñXb”ä bHz„x%˜ó•LéJ±® "ÜÑb9îû̺Z…gÊLç­>à,Û3\<ÀbÁ™ü]‘ÑÆÒn¢A‡n˜d~ëØþrúŒÑM6õ:mƹfˆ¨™²„äÊ(%£ÀÀb˜¨y”û: @· rÀ*eæxçE[ïß Éù“§{4x¡Ä‹ù°¹kÿ6 €°*‰-Âöº¥žìX}»%Ûuuõ ñgH¹PIEND®B`‚twinkle-1.4.2/src/gui/images/sys_hold.png0000644000175000001440000000233710503576707015301 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ (ß dlIDATHǵ•[lTU†ÿ}ö¹Ít:¥78\[ì%#{¡ 7E›¤©"(F$(*$Æ51 †ˆ‰†D^”„K X¢ijhŒú"­”{ Zl*m°-鴥휹Ϝ9gùPÛZè蟬—­og¯½öAŠ¢Ø³f)ïsË£kû¿8Fø¯4/O|÷ä¡´È &š#$jEѶñ%ÛæÕkœÊ<[—hKÄtì›Ýäv¡­í6º{<Ò †ŽDðÃô¢þ÷+ÿª'NVü“íoÑêgWà»ê:\lj™Æ„>N@IŽFW;<ì‘£zmÓZX–"s P}x ÷ȉ¦eW”%U./Ï´Kv' °| KÂ\Äó«nâäñ} ‹  ‚ €ˆ`qDbd‰#äõ®»€ªs*Š—ôƒ÷ôšõ—.Ç›((/.²’¹ÂÁ¸Û 02úÑÞ¹GDyÙ˜dA–D0Ý=½Pe ×/5£ ´ÓçÌ‹ñ½€ë+ĺ¦g<âÏ&ØO1ÃEýméä^ Ÿ•ähÆ–××Q$¨ÑϵªÁ pBë†dûN¼²õ"A†ãßß©®1Þ¼Öm06 |Àô PóÙFüÔu'\²h!Ÿìô±3õŸ«çÃŒ1è!À3Èp½ƒP¾ôK¤k û÷èWö~­WÜí3n$ôØ ùbþPKU]¡ˆ<%»ÞþkFçár'CC‹…³?Fá’`Àë´q³û÷|"ÍÏ‹LÓB6;P¸lÇ3Öãl£!ŸŠ‚‚v¸«N0FÈÍãÏWy~}¶Ãq^Q9!À««Ô¯ü…BYô×­ ÚºA9mWÙ¬û,jÉqÛ÷G¡À FºžO¿þ˜™£ÉÙ“çœKvÛ·}Õržv+<È+Ë¢kÛé·?®¥Y½·§ÒʧԪI²$h‡öÙ½ŸïLºåÊæe))iìáböe¥rUÍ‘½jƒí—I6UR]ÙÂЬ¤?Ê0cªZäÊVÖŽ_ÿ'eÝ™‘yPjIEND®B`‚twinkle-1.4.2/src/gui/images/sys_idle.png0000644000175000001440000000234610503576707015270 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÕ ;É%wµsIDATHǵ–klTEÇÿsç>fïÞn»,ÝÞ>h·°[–Zí“RKÅÖRBm$ ‰#Ƥ1Q1„HT¢ÆD+’ˆ|à#Ó`0 ‰!AÂCÒJK ›n>v÷÷Þñƒ_ ±vIêù8ó?ó;™sΜîÀEQKŠ”¨@eüVŸÿr÷¼dN+3õ2Š¢èØð¸ã©Õ»”ò ytÎAŸ°´ãAW•ËíÀê•ê§Ó)Í) ¡ZبP)‡åËYP¤‰Ú9ˆ¢¨·¬W $—PÖþ€¼vε¼½±‰åjDsɨ­¦e⟠y[ç-Ê h Äê륀"‹³Výv„¦­[Š·•.–E@ˆ BÐ lr¬×TGBB<’$ydçåéL×ó†aˆ–e%ISºcE=-T³ˆ+ßÃäTzÚ%Ë–Ûɨ×òŠT©ºÉ$b]õ"mf!¯pYº3)cüF©iF,3ž€4$ܼÅùžR—D˶b+ZœË[sUIu°; Nœà01:˜Â=ÝH¢ ‹¼2çà_¸5Íý(ðX `ÒˆLš8²;Õw®?½‘þ9jùõ”ùO­ÕUvU(• PBÁÓ7Ðý᫈'Q³€!˜OàfœíoCqÁ§PÝ&"ƒÃ Ø&Æ®G±ùåä»öN¯› Û—(>¶†ÿ’Ú?xÑð—•Æ^/QÈ4"×¢x»ç3øóeør—` `ZBc P>N°S þqÒxúÙé7÷Z]¦…ÈíIŽö]¶ž>mŽ8¥ôÒÅK$J9˜‹bß¡—£‰Ð ["˜6 RØÖI”W÷!娻3ruç.kÝù>ó+|¦*²B7ù™cÇñýðÕDÍÒZº Ë!½Gª1.ƒ•"ÇÐ8Á¹!ŽÖ{ß…G'xïðéíï‡ÛGÆÒ2ꃉHjð›¼søJ<)縱í¹W ‘3¸2Áqê ÁÑ‹QT.؂ʆ 005.¦Mëú¿ÖùL pW U‘§ÇÕPÙ8}ó×âØñzÄ# ÖN€2áðhóŒ4ÓÆ²Z±Ý“KaY8Täú³ñXél‹Ã&&Ñ@0ªêh©(Ò2Ó´2}*ÿBtHŒý&Îa'Çp²w8ÞóyèFt<Û¾ B4,kÐPmÏxr©Œ¶þ~<‡ÇŒb3ñ±áBþÁv6PæÛrÝrɆ5ìÀ™£3ñóx¼ŽÇ¢eüõÍÚ EQ2¥O¬bÝÑ›:ÇKøµ¾ù|Ózå ÊHÑ?$¬æn±kÿ'ZÜ×y8\Æúv~²X—}³N)•v¼æ8‘ˆèü»¯5ãþzåÅ™´²,»ž‘~î?;Ͻìåm÷±ÎY²$è»ßQ§ÞÚêì úhKvö<òßµ±Nîìù8;ܹÞqhV€ƒI,è6*²â¹“G—U}Ê#·¯ÿ*ƒ¡v#IEND®B`‚twinkle-1.4.2/src/gui/images/sys_encrypted.png0000644000175000001440000000254410503576707016350 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ.wxtñIDATHÇ•–ihWÇÿ³¼™yKÞKÌö4ÛKŒ1M¢Mê3‰iꂚüÐÒ/Ui©¸Ð6K#AH…–.´`D¥bé]@,VÛªàFÑŠ6ÑÒ’cԤѨI}Yß2û¼™¹ýð¬bL2p8ÃåœóûßÃ=s‡Â žç]þtlYUßô}uõ’uiiÉox½®"E¥x8üéèhìë––WÂ9ÌLó ¨×ßiÎÜE؆ôåË«š‚Áù™yyÈÊJENNF² pËC¡q¦ªª¾óÂ…ãêŒ,Ë:ßÜäÚ¬­Î ä¿\RR’Ï÷õÝ‹··wEnÜèWEf ³yŽcô÷‡z/^ÝÕÖvаÓèÅõu³ÊGÄZTTäòׯßÒOž¼ü¢è;:¨áp¤±¼¼Ä—™™¼~|»´ÞÙ£$dò,Bë!¸òC_+[tíYZÉd¹’(ïìT3⺗㬷À¤ÀA<™Ù.GE-®cf+=@lôÉ’€° «;Œ‹½d#kÙ–¼t…{ͳ+Ó]—€ Ø1qÊ ÷{ œ»´ óæÞ8ý‰ÊÓ€(âaCrŸdî[¿^ùÝüƒ¨ÒÊŠr;‰áPŒ4ãM1 ñaìÞ¿RÄš¢kH¢b€f&L'L‰’ŒÈÀ@ PãˆÅÚ{’ÎÒìÞ;Æ™æ¤àÆWŽu]é·ˆ dˆƒqœï]–ƒBŠ‘ðQ W€ ‰ ¯› 3,òðüsä”ùÒ–F¹ñз£!]–âf05Š n'Ú`X”Ë ê ¯Y‰ýxÜ é׬/¶·Kß~kø·áÁqâMÓïý P‰3™P©›€n%ŠéÖCkªš8e“Ó$·sá™ã¾ËåKxçÕËnìÚ»U¾áãF›$vB0é»lÐâ ÈoŸt’Kçe™~ÅI3<]3Ž]ipñR%”XÊÊzP¼hœÛE_î¹Ý´3ZðØAš PµˆmHMg`Y\H/ôáÅü>ØM™ ((Z¨(ʃL>Ë2E¦iõqE>jqw˜>ß,êÉ‚(WMk<ü¥/Ú¸ÖyzJ€SpÅzÏñ©3ù㘓!”ø]ÿkPßæ|¾ûIEND®B`‚twinkle-1.4.2/src/gui/images/hold-disabled.png0000644000175000001440000000051110503576707016140 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ41ë‘·.ÚIDATxœÐ1JQÆñß[]Dð{ArAð À ˆ°KO x ; ±–­SAb‚ŠÉ3‹Ä°+1D¿îÍ|3ßÿ KtíwZÖ>ýQ]¹áWÛÚÆµlÿR‚ËØó¨«ï͇±WÏn?Üä$\»7iMWQ§† Žêéèéz¨ê47eŸÆ²¡‘‰ :³ù¨S± øjX@i[ aC©ü¦h2e¥-;²$ë›jß³à"cªPÙXiˆ;UÌÈæ©ûqæÝÈ‹ÙÝ×âU#¡³@þƒ¾õmK±v#‹IEND®B`‚twinkle-1.4.2/src/gui/images/1leftarrow-yellow.png0000644000175000001440000000122110503576707017043 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÕ #‹a.CIDAT8Ë…S¿kSQ=ïÇÍ{7ÆÖ´ÅVmµjb¡ÁÔ†jÁ¥ B)¨£'ÁEÜDŠ1£èâ¤à(þ‚X‡„`ÕFM µÕš6ÉKòòîý®CII$I|ÓwÏáœÃw5!\ÀÍÛ68l®1æóÁ4ói†nL†ù€ó½Q¥(«iúìk Ï@Ç.Â{(I¾9~,>~qò‘qd(ÖO$õ}[E*(„÷‚Ûþ»±±iílü>œGO0"¹Ã3[’• á=:w:6ƒ£‡/Àó Èå?¡V+B)B[ÏSš&_ œ˜ŸÁþ¾(ŠÎê¶]¡æ9R´p]\ øð4ëF.ƒÛ½ØÜú ¥$À0,Q‘l)p««‰ÑÑ3ÖHhD[…å&wºnÂUµˆ`Yx‰Ä­Áƒ§à”ÿ‚hÛ¦¦5÷\©lB´Š ë‘„SÎAˆjC¡ÔÐORz­K¬Tp'•J&B¡‚Õ<)=RMëŽ#4ú{R*âê—Å¥?ë¿Ó;d"Ù4J„ðÐî^».¦¾}]]Z[OÃ4|ÌnfZPJ¡Ó%&‰0õ#½ñ.³’cœïƒe`YØvu€4€K+™üËÏ‹ïQ«9Øãï·»áçÁ]Ô‘p}í—37ÿñmu#û~œr®[¥Žá?Ü+;ø°œŸË,§N–'[*©Ùúò»¢²ò'IEND®B`‚twinkle-1.4.2/src/gui/images/sys_encrypted_verified.png0000644000175000001440000000267710507532246020226 00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ  ˪_LIDATHÇ•–iLTWÇÿo™÷Þ¼fØAÙÄ‘ZUÄ-*„øÁÆ/UcSëÒ[’Bˆ µiÓ%m"FM¦i›Z«±ÚVMÜ>¸DÚ`¤‘"BQD–aXf˜yËÌ›yïö!­F Üä&77ÿs~÷žsϽ—ÂÏóbbv¯«¬=]ZºlKllä{6›è¿_éu»=ߌŽú~lhxÃ3eÃ̰(ƒz÷£ú„ý„­Š[½º¤¶°pQBZZ<’’b’)Üj—kœ))©l»uë‚:'˲æ÷wЇ ËKSéÛ²³³Óùžžg¡––vogg¯¢(2“™™Ìs»¸·×Õ]T´¾½¹ù2ag ÈrÐE•Ñy#þräç§ò>^ºtç„¢¿ ß¿Oíõx¼ÕyyÙö„„È­ããçøéÙJóé]ŽEFÓâÁó ÚÚ:½ÃÞokúkÆT5ÐøèQ¿¦©à8Ö¡ªAèY†'qÍ:¶‚âx„Ã!¨ªŠaW?‡Û¦4GŽÔ»ý~9  idY™´   —T•• 0Â0TTÏ3ˆ”Ë¶ç•‹É GsŒ)Ý©I—\ æu)F<Ôl{k,WêÞ™_)uÛ!Òa±ØàõŒ‡¯Ã"°Ê”nLµæØ"ífE’¬÷qKHU¾¢fŽ]vñ\ƵTšã“s*`›7 @‚A ÐÔóæ„x´¢9|]wéidË Åƒ+‹™$1‚²Í‹8-´qœe˜(˜ˆ5!Y4å—Óh?À<¥ ðŽuºñöÂX˜˜É4(N÷y¢£.!z‡·»ÉV7tyåˆåkãD“h`†@„²€ Œ¡n ×›Vaá‚'\› v…ðVT$NŒyð3Ħ€ˆ£x Ó‡@“,—˜þ!ýæÝ?­D•Öæç Ï€bL 3hŠ ¹qàÈ>H^ Êœ!‚ò0ý*>žïÆq÷.GùQ7(¢†cÁù5Ÿ ¥+â Àè~ª]­ÿ\*Üñfÿùö»½: zA!P2ü!ÜèÞ – „)(V†X>I1p´Õ†@Ã4&Áðd×tò| ž½~}wµ\}ê§QWP–bE@c X(A! Ðt8i`y+‡žF`›…d è@à_ÀËî"Ý5BîÝnÂ…¾^uiQ“aóQ7næƒHn¬XüQœÐtðºŽòD tØ4cÒ©¦!#>­ƒ¶æii„żäêû¼e¼ùÁ öÚŽû¯°s#€A&wB0íXÖhÿ€Ÿ¯›¶’sj¹ ‰Š™f¬xµlûcâvS1Ÿ¹¹]È*g1@QÀw‡GžÔî›Èxi!M()`«bâèºq™vlJï¡TeE 5¼B&eg8¬w½ègºËŽÎÌÀ“ L¦‰a´ÜèSÎw¹ýc* c€ в¢¤ÔŠâ%LÕ¬_.Q`Ö>hŠ$²”JdiîK"‡>ºœv}\—¶u£pöÞ­˜°ß—I¥È~'ù´ÞÚÌó<7+À– á€$‘(JyÚKvmæ*ù?aébvϩתּ4–H&&œäê¹Ø@j"ç˜Ñ9Ã0¦ƒŸ˜›U_"ùý¤UZUÌ×N§å86kÏNÓõ‡÷£¡¿ãÉúBõŒÎD'ûZô~Ù`éÈr0kìöhêÿD‰e…\õ™ïìÕ›ÍWf˜“å ·ó3—Çüx!/ËÁ¿öâü?mî\v}¶åSIEND®B`‚twinkle-1.4.2/src/gui/images/clock.png0000644000175000001440000000457510503576707014556 00000000000000‰PNG  IHDR szzô DIDATxœµ—leÇ?ïÌìììv·»Ý–,…Š ×Q €ÉIr9©§þ£ÎKŒ§ÆèåŒÍ…ËÝ%g΄’‹‰‰—\<£&†‹§ãaÁž ŠH±VJKK¡ôw·ÝÝvÌìÌûÞ»[Šw'žÉ½É“MfÞ}¾ŸçyŸgæÁwXï¼óÏz)e‹”j—”²ÉóTTJ‰çI¤”H)ž';¤”oK©Þzà–ïâW)…ø¶ ï¾ûq“Rj¯”²Åï7©©©¤²2‚aèTUEQJ16ǶóŒŒL288F*•ÆuÝv=òÈÝßààÁOZ¥TWT„Y¾| ±XP$“³ØvžDbÛvˆÅ @ååeH)‰sút/££“ضýÂOì~ôhk;•RÑu­iíÚjjbd26½½žÄ–>²"Ĭ#ð¤"ì³ñ2I„“fÑ¢*V­ªÇ²ü\¼8Ê'Ÿ|I:éBÛüä“»Whk;UJ …‚MÍÍ+ñù ÎäÂÅQˆÔ²rùBj"> Ž%/á¦- q$ôæ˜8ßÏd_/õKjXµêZ²Y›öö/èžššÜÜÚúLü›Æ•8 ›Ö¯_M.çpâÄ×L©rš6Þˆe˜äH GŽŒ"·,DµÕ ªV3¾ü:Žpšóç?fãÆulÝz‡Ÿht]ï#` àÍלË@[ÛñVMÓß´i®ëqâÄ×ô{‹Øº©ŸSCL¸00‹T°hIˆ¼GMAÎQnë¦lì[·6£iï½wœññÑWZ[ŸÞ3?ZQ¼IJõøÚµ×áóttœ¥×]Äú›kq¸ªy^- ¶pIˆ…EqW§ ¡y\ 7mYÉTì´·ŸBÓ4š›WGwßyç;çg@+’´VT„©®ŽÑ×w‰Ž‰2Ö4_ƒ[tæ*ÈÏ‹p.ZY¸ž—¸·^}™[ë+è>Ýë)š6¬ä‚WKgç9ª«+ˆÅ"ÔÕ5<ç|?³ÉþôG2™®«¨^ÓDg÷033icYeÛ¶lùÑú9¥T‹e™Äbåœ;w‰S‰*ª+ýØyU0GÍ •Äy⎄7‹â›nkᮇž&ï‚ãÁ‚Ê#ëùê«~"‘~¿ÉÒ¥·f `Wuuccqò¡ª¢8ØŽ"—Wäìâ¯ö|s ⿞'¾ç©ç(¯\Œ&ù¼"ï*Œš††Æq]ªªÑhå-@ÀR6ÅbR©4Árv^•Ú²PTèh¢Ø; þñÆ_øýcñ·µ°ûÉçW.Ææ\iÉ¥iŸSÆÔTŠH$„®›+Šã†”*j:Ž“g"ë§¢VÃvªØïž×CM(ºOóÚþß0›Jpú؇løa ÷ýò9Êb‹ñ0qÅLVÒ?ìÒ{ÉÅq)½†\ÎA.¢¦”¤²2B<ž$íùèúlŒ7_ü’¡²Ž"k+RiÉð¤G߰˯~ö·ÞÜ @í²FnÜÞÂÅþ>¾>yŒž³ýœqéÈ380ËÀán²ƒS(ÝÇôtŠP(ˆ” @/A)Z‰¡ƒã*\ì<¤f9ÇC*0}Ÿ!ˆ\`ÏžýlÛ¶ýû÷3ÔßÍ Oÿt®¯7Ýõ 6ß³—2K'í/üÇo2˜Ë9¸®[``bbšX,‚¥PÕPEÝêH©ŒÄò ‚>ßø ØyߣÜqÇÔ××S»¬‘5v •š;®kV¬%àó0 Õµ!6ܽštNaöEyyñx)å|™pœ|4´¨Ô“ Ùº2K#h ~AÀ,˜†àç{[¹iëv2éµË©^¼ ¡ûÉ»…¢Ë9м4ÉæE±R‚ÈM D5¶GJwf>@ÇøøÔ¶uë–5r„GÀï#àý¢¡a™¿¯…·ïBˆR—¨BÏų¶"cKÈ•²"pm™›Â²344ŽmÛ=¥—’&¥zûÒ¥q¤TÔÔTRÃ~ŸÀ2EB£Ì/(³¡€ ÐY‚pÉဠ,PØS˜bZ w‹•ãºñx’DbòC Sxkf&ÃøøK‰ÎöcéþbÚ-S° ÎËü‚ ZñW‡ )(ókü…ý%aÓ'0”ƒ=pŠºº¦§Sd³6gÏž< $´{ïÝ9àºîß;;Ïøi¸v!Áés˜FÁI Âò üøõËÂ,üXW•é˜ÌtcaU]×'›=zæÌgÃs…R{GGã ޱjU=ÁôÄñéÓ~CÌÍ~írô–V0SŸ>L£P'>’ý]¤û;©­­&OJÍÒÓóÅKEqgàþûÜá8Î ÇŽu’Ë9lذ»ï4Ùá M ÏFLqÂÒ/‹—îèš`¼»‹ö÷hl\Šã8œ??L*5õú‰m=ÀÈóÀCÝýh:íjo?E `²eK3‰3_rñäI<ÇA E|üáw<ÿÛtQp¢'%×¶é|ÿ}Î~pˆ5k®Ã0 z{Éd2=´îÆKx€¦i›ÇÆ&º>ahìØ±ž@n–#¯ü•®ã§°sªðbÉÒuKC”ži¹¬ÍçïÄç_$=x¦¦!èî ™Lõ:ôÚƒEáÁùšÿ6–?ó̾Êh4ö‘eY7ÜÐHMM%©TšÎÎs ŽކYP# á)E|2ÉÐ¥1&G'‰ÅÊ©««AÓ4&&¦éë»D&“é9tèÕGFÎsý_xHý÷ýÙg÷ÿ9®Ø]YYÎòåK¨¨Ïõq6k'q]`ÐÀ²Lòy—x<É… £$“3$“ñ×ßxcß¾bäWˆ_ €{îyxg}ýʧ,«l›e™,X% #„Ãeäó.Óärñx’‰‰i²Ù™ÌìÑîî“/}úéÁžâ™þ'ÿW(®àöí»Ö/[výíÑhÕ-†á[¡áù§žçÍärÙžéé‰ÏœùühW×ñRŸ0¯à¾/@i™¦˜(…aBÿÆ}¯(–`^ŸÛRJ!”RWÛ÷]ÿëºß~[iÄIEND®B`‚twinkle-1.4.2/src/gui/images/telephone-hook.png0000644000175000001440000000115010503576707016366 00000000000000‰PNG  IHDR ¼©7/IDATxœcüÿÿ?õÍ¢¾q,Èœo^¾qíÅ¡Û gubºÙ¹øÈ7îõã»ZÂØ9ÞŠüxpöº±†F4777™Æ=8Ó©–ùü7ã?¼\Ì}úô‰Tãa÷èÑó¯Œ&ø<Ùx "Ÿ?$É,ã?g}þçé±ó/¯¼üúLàÍFRÍb@ö¬–’¨$Ëß /¯–³•”ü)+aÄÏK¾qÏØT¯ß½hosYàþYcU!aVÒcáÙ(+Ÿ×~000Hš¿PUSÓÕÑáå%Ùuã$%¥OüRúûSB”a‡´”'''©f¡ÇËË+ auä´(£$ËçÏýß¿§È8†<ÏÈͧ¤ôX¼{pŒRã„Ä¥4¬6.wb”dQclºufÓŠ:ƒ³³LnÙDŽq %‡Ÿ³Þº òGöúÃ}u ºÖÜâ,™§×§eÞ ðúõëüòÀ£÷YŸPÞ³Öü߯ß/¹~¿äú&íÓ§O˜ê‘–JDD¤<êª>מŠˆ1üúwƒáÖ‘=÷ônݺEšg!@RR²<êÝ7ú^1üxûãÖ‘YûŒ]y{óḚöÎ^LŒx ÷çÏŸ_=²îã³üR÷Þ³¾}ÿùû·¯)N.nyU7;{bc``øúõë÷ïßß½{ÃÊÊÎÁÁÁÀÀÀÊÊÊÎÎÎÄÄôïß?ÌlCÀ8RÁà®z¨lÉ”ÿ×¶™[›IEND®B`‚twinkle-1.4.2/src/gui/images/cancel-disabled.png0000644000175000001440000000100310503576707016434 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  @¾áAtIMEÖ5­X‡ý”IDAT(ÏE‘MKaÄÿg“%äŨ#‚clC)¹xè¥Ð[i/‚x°õµýžz­¢1Þ¤¥P¥ ŠÐ‚BÅâAÁˆš&ZÊY²[w­ég†™Z˜ éœN!úP ö+ÿÄ(oåM0~“3Ë_òßNZ†ÉnÖ»ÒOÉþpÀ*G¿õðÂ:LDe+“~Aä7|a£æe«<œK<{N˜v~ѤI¡“ÎÂõXnM‡dê6qÂtS§ŽG/a<2£N"ŠG°Øä’6P ßXb3*CR1,ÂWÓE'ð™]„*¥ .±øÉ*%6±‘¿•Ò‡ .¨pBŒ1 D’i nðËJKPô1¼'O‰$3˜ql«‚íÏ»Äy|Ä&Á2§ô‘ÅÅ[1+/;Œb¶¿ç­¡ìó£ì˜ExÕo¬=HÞ¿;Í1ûeý:ð=eìÔ³j±JÚ5]®©²×¨~ògƒ[ù«Ö›0m:=2¤R(¿Ì¶Y¡–wn¬/ŒšC¿õŠIEND®B`‚twinkle-1.4.2/src/gui/images/invite-disabled.png0000644000175000001440000000047610503576707016522 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ5Dì«RÏIDATxœÑ=NÃ@†ág£Ü Påö%L5%çÈRr ¤”éi|‰¤Šè‘¢t¡Š"™Â?;–AÊWÌîξóÍþpƒR\TMž×é¨jØ„‚צ‰@[,ýdl6NÞ‡˜5û<†U3qz1kÞ{vøÀ“£²Ë ÐÞg%Ê®úlÙ‡v/“›åL×îÇÖ—ùà³sµ á¾qòé„;ÏXxS§pðCm‹Ct¢jV —Ñ™Öñ[ZŒUoìjmòÁìUvnÐ/_4¤ÉÚIEND®B`‚twinkle-1.4.2/src/gui/images/consult-xfer.png0000644000175000001440000000146110532115306016065 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  d_‘tIMEÖ "¯ü¾IDAT8ËÅ“Mh\UÅ÷Î÷òÞ¼13“!щøUlt¥T\Õ‚P(¨H»ê¦t¡vá¢+7f㾸Š.DpaQ‹X… Ñ`°-µ-V¬Í„43“™yoÞç½×Eh?ÖþWç¿ùqàœÿ÷‰¿>Õ×­,Wñ„Ä{¸Ö)M{εg­É‰‹ÑðmaþP·…{Äú^”XhƇff*Ïî®»wלèd£=¼°ÖñÞI^±çgDúO/™zÃ×§^~¢wdïnob®5FÕÛa§¹á—v̧«á­÷V›oæÚžæ}Yü x1k‚|kñžîášoÂNZ×™.ÙÆØ°´Ð2õù]w¹nY‘¤ -‡ë__?–gÙ'|X%L~¢VQÏM6&6çhNUµoŒa+ F+×ø}ù‹¸¹pŸLTÀ­ÔfªN~¸›ñ%0P ß<¿¡”}†ÙV]³kJ"¥`s[ûOÍÉûOVî~sE³Óc*É¡$³Etú8‡¶†êé+ƒ{yd²ªy ¥è„‚4‡Ö„@JË O:öç–î*¿'µÞ…h¿WSãìÓV0H$›ÁÅ_]8¥%.Ý„ªa†14* ¬1i-k“¿ª›ØI~Þ€8É9ð¨E)Ź‹–+mI¡Ya±z‘¡·Õ^Ͳü8°¦z¡Ø ÓîÄrð±‚ɚǻ_¾».‘ÀÒí'ib¤;ؾuÕæÑ1ÎÎÿ Â”Ðul ¬À–2+×`í7IYîpóÂFQØ_ “lŸÖî41ÍÌJYŠý®XKk”c%,§–$3ߺŽ"Œú@Ÿ³óú`½'—<•MÍß«òÊ–¹–CY .·-Û‘åêôÇ©sfüÒ¿IiÃùËÎkˆüæ8û>\&Ú½"\ïØ•Ÿnª%°çÿkª?EŸ6`»IEND®B`‚twinkle-1.4.2/src/gui/images/sys_busy_trans_dis.png0000644000175000001440000000137310503576707017402 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ $/„Á¢ëŒIDAT8Ë”KH”QÇó}ß|ópt4eð1cj¨‰Ï ,s!T"-²6‚&=ÁM$µèA‹p¥V $e‘F‰N"JŠ!>JR‰0t|¤2êÌÜ!MÎ žÕ½çü‡Ëýßs!hèŒÑ%•ÝGBÍ=·%#XE –T ÇÎé’Nì°åÍÜÄq2#ì´¡f›B”Ÿ;•òbR;‚ɲ8ÿòKè%©wã_U”mš aÆâ¬-ÆW©6¸v8’GñàcÇÃAhp_µìè™$ra©ø¦a¤¡ÕJp@Qޏ03Eʱ¢gÞÞø¶?¤ËžhUÃA“]Ÿm ‹R7´†ÙdÕ>#‹a¦±‘O!ÈXYÁ„„K4)ÞÕC%yFàE !hgˆ‚ôxeŸg<ØÓl%:4Üô¬µþZă@"›´â ó /pDH–hž¸~üÎÁºç£^d—ë‚kÑý1)ºEi›>æo‡ÔêúµQ1!šÜV{€\ÖÖ:¿ŠG+®øgÕä3|}ÂQh­u‹—Glæm#%³ª,•µz½­B þ‡X2íÇ·Ö±ÏV8l«]IEND®B`‚twinkle-1.4.2/src/gui/images/encrypted_verified.png0000644000175000001440000000151410507511703017310 00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÖ 83vŸÙIDAT8Ëu’_hSgÆ9É9ùÓ˜?m5S×ÕagÁ²Q°Ƭl°n÷½6Ù͘»†¡lôfèMÀ eCEŒ]Ì zåÝ`ì­ÍJÕš„$'Éé9_Î99çÛEhVü®Þ÷y~ßÇó¾þwΟ¿‘Þ½;yrx8u*‘ˆ0 k­RÑ/U«­kssŸéýú`ÿe~þêP2Ïe³ßMMgFG÷°ÿ##{R‘ˆöa©Tf³Ÿ.>|xGìär—”X,2;=ýÞüøøÈÀêêswaáIceeͲ,386öfXÓBï®­•þ9ztæÉ£G÷$@h à8î@&“>1:šI./í»w¿nYö÷€ùøqàœ®7¾žœ<œÌdR'êõ毀 l„°Cá°v ²´T,—Ëú•|þôz>º&D;ÿìÙ‹Ž#дÐ!ìÞÃ=€iZ¸®ƒ‚r¹Þìt:‹[½Ë—sÃ0mÛnã8¦iõrë‘Þc9ŽØ§ ý9j§š;r{ßÜ‘‰žðöK]õ6K(í²úñÈßé› ó‡gÔh,ç¥NÇwÅ#M½!Òc©B5ŸH¤’QkÓl‡ÅWX&Ï>}¨è|’=6“Ø[jøÒ*èT?à-ÙAwJŒij¤UØûÑ?¯þt¯ª>žU€V€W*|ùÎ0j°ÑKËá§õH3™ÞSWÕøvU‰Û°@³¸ßÜD\¾H§¸^Ó¹°™mÇø&†• ®.Ù¨Êm@½%ñZ6¨Ý;î÷ƒ\,—hú\øwˆ¯$jQ×Ãk+Ô[})Ë…° J€ãn¹.Ùô|~(&ø|Hš ®®N°ëé#®ß%9>‡øàOSƒf0msLJ{ d´'JH_ÞŽ“P$Šëo›]:>Bw w~3Œ5¼ _v"áuµé(Pøˆi5Ì0‚oIEND®B`‚twinkle-1.4.2/src/gui/images/cf-disabled.png0000644000175000001440000000067110503576707015611 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  d_‘tIMEÖ.ZJºTJIDAT(Ï­»KBa‡žï¨ÍP‰Ì† í"QaAECCKBtí&‡Ü‚ç–þújiuhƒèbK*^*(PÐJ¼ó¿sÂL×z–wy†ßûEó}üœ h„>bÄ“ÊêRõDi ø ò–õt<îÎ ç&^úÏÙæ¶¾)`Ã"„æ=³“lä­.ºüV»K(@Öm8²ïH¥Û×H>Q{(˜ÏG|$À+{Xx>Æ’`ÅÑÇ5çÃl„a@ï“/QxeQ@ô‚€·€pÖQ÷۵ܛñ–¾€U‚\ÈÔ- :PFU¡÷¤%¤˜+¥’ž% €ô€R¹jÉï(éšóZ4ËS]|ŸÈßH5FÚ»eèPT$ò´¤+¦äÝðCF%i³¢3FÝ¢–í#’UÛF¶X1A‹R˜á_ø©šuš$æÎIEND®B`‚twinkle-1.4.2/src/gui/images/1downarrow.png0000644000175000001440000000110310503576707015546 00000000000000‰PNG  IHDRóÿa IDAT8Å“»OTQ‡¿sïÝee]‘°‰¢‘   êµ²¶0VtFI 6ü¾þ£&B„Õøåª  f6qDäîëÞUØ×=ç‹„…ŽÂI&“s2¿Éd桵f?fìK ˆS—’Wj¾yG)mhOâ{~]¢êª.Ñ[Q¢<‰ïÕQžD¹¿}\÷šˆ]žYëè;Ò‹àûÍ回¢ñgYšûÁÜ͇¶å-Ñs}Î÷B©¶K³ÃLÑðÖ ùŒ^]NYYÍLÏ'â¡øé6P°}/B4Š~ÊÁb*òÜûUª£æÁî i³¼q ›];í]`ÊP¬@¡Òˆ³k°`CY‚W‘TÇÆÁÎÜ‚à=3rò"Zé¤ÈÙ=E·Ö_ì8SÊ/C¦+ë€ ^<ƒÔûG¼ ëßx1¾,ÄòfËYÙ?€– }›4ˆI¾ÙwoÁÙ÷HZGK9dÍN/¾.Ò„€° ‘0?.@rj ÄΦn'‰ÂHëJuP¼~ewØËô…îNhÿþ 55a£êƒ ÒÛ%»Q6Íy¯è &'kmN–¶‚Mnl¼¦6~ C`¾9ÝÚ aY‰õ•Õcnܽ¯©–ÜëLì™û߯ñ“ÒïÅFì *IEND®B`‚twinkle-1.4.2/src/gui/images/ok.png0000644000175000001440000000122510503576707014061 00000000000000‰PNG  IHDRóÿagAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<'IDATxÚbüÿÿ?% €˜(ÄÂ8Q–áÃc†¯@Þ7 þÄ@2@ÌĬHl(ŸA™!™™™A €Xþ2lj¨ oÇkȧÿ¤€dP}Ú¯? ?YBˆ‰é/ÓoVÖÅ ¿qjüÅ $ËdöIÊH6]ùˆá'ƒPì"@1ýÿô•°–°0‡Ç"† – ŒHš3ˆ]˜Á"ÍrTÚWºƒ_–_ýÕíWۚÀꞀ”ËÿÿO¿ûñîS“ Ã;†¥ B€â×€¶&0È3$0Z1š³™²1|8ùáëö¯«˜Ò8>Àì F†1 Âí  F ¯€"óîø–ÁŽÁŒÁÈâ @¼…aC/ÃGp€r000r10 0`^1Üa8Åph€:P"œA™ ˆ%Á^``˜ ²S ý ì •@Ûÿ¢@1ýÃÀð…á4Ã% $Èì@Ì ÄxïjüÏP†M3 Ãg ù—áà³õ€ÞÅó°³0ÜfÈ6›Or °¹n5]ex4àØ¿ïU ôó|i €XÀþüÄ?Ž=L Ï^5ÇSÝ”(ň\ `…ÿN~Î`Îð /, {Àb,HI™f†°l€b¤47Ź ÀÃQ‹ôÓU!6IEND®B`‚twinkle-1.4.2/src/gui/images/sys_hold_dis.png0000644000175000001440000000131110503576707016127 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ `š¶ZIDAT8Ë“]HSaÇçœmgi­DV®üª5D4í“% d–D‚Ú­QÝÒeR˜ÒE}ÐUD]tSTTˆ-Â3¿´$ÍÜ´ét;{º˜šºøo^þÏóyŸ?˜BwfœQmMÂZ{új$½Ð,¢š‘Ç‘º }ÇQ³˜’LµÊ^¾2Â$af™'̯—ò,«ÓÏËaÀXÁz¥Wù ?ãLbŒïŒ"€WzAƒ9¢ 1M„8P’ŠÊšqO1ë’¬8€‚ bòðïínKqóî gjšm>Õêr¸´u?ˆbE'…*Q‚ÄIÌ®i´ °áýþN` ¨µÜ&ŽŠŠe+! ƒJ(Aûùòc`îP^Š  óLp“2âXtáÁƒg©ØRÑÖ–©‘+â]vjePnM{/%ê]œ î««¿|Ìídv’Ãf4†ˆâg–ûCí'¿¼J”¢-Œ_:Ÿ nu*¦‰1Ãoð‘FËûÖʱO&Ë7Õ÷´á[$…j Æé§‹ ä!L}Ž ¯èû?ää§94 pÑE˜\|è(d—­Ô?Vn$†Â6<Ä‘…Öd[¼±^3?¨™~!ÂÛ™‡cAb*ÅäWšÈ^^êRBÜí»XÕ´¯ñQGAãà Ýf²\׺ePÞHõc»'ñBÞ©æ™é“;wVRºf½ð®_nüÙsn9kóÕ¼xï”Ò†$ÕÝ<ÛY¾~•i5gQÃõÐñgI»=³Þ¶ÉÜ é»²ªï)'ÔîõŠÆIEND®B`‚twinkle-1.4.2/src/gui/images/encrypted32.png0000644000175000001440000000305710503576707015617 00000000000000‰PNG  IHDR szzôgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ÁIDATxÚbüÿÿ?Ã@€bA`ddÄ«a„Õÿþý 2J€îgòþýûûÒíÛWΙÓù(÷—Å0#zàs@w÷²F |¾’’¿ŒŒ(ƒˆ?Ãß¿>}úÊpçÎS†'OÞ0|ûöeÖå˧W­šõŸC`öQhm](? ''®ïåeÁ À‹¡ ÏŸ¿fؽû ÃãÇ/oìÝ»ÞûàÁ-R¿ñ9 €: ¾~ØrU}??°üŸ?~üøÁðë×/°Å 1...NNN†ß¿3¬_áÒ¥;7÷ìYã{òäÞØ³ €XÅÕïß%Á–ƒÀçÏŸ~þüÉðâÅ; O_ò“AFF˜ŸŸ“‡‡‡A\\œ!8Ø‘áýûê&&Nõ@äµ}À„×……ýŠÀ8Î ´ó?}útÀW €‚ùëÇïŽ=ÿŸ››_OLLHÜÂB…áëׯ ªªª ¾¾V@5o¢-,ÜçŸ8±óPû7ÇÑí ¼ø÷"ƒ°°Ø`Ï—,ÙÍpóæí=Û·/šúòåã@eßAÇÅUä¾{÷)Å×׈ƒƒƒAVV–AZZˆACÃ$è€k@5?øºÄ„?øhi)‚ãëË—/ çÎÝb¸wïñ½ Z;€–ß*Åï}^´¨£êíÛ·ëOž¼ÍðèÑ#°~MMy&&V “ˆY±Ù@xðçÏ_;`–cøþý;8qððáÍ Ð8ùþ5(f@Iˆß>yr¯áþýWàúþý{ 6} 7.^üúõ˜²ÙÁ–ƒð¯_¿>|xûÉRä„õoçÎE×¾~ýVûæÍ^^n°@À†+ºˆP€³ƒ²ˆLÿ ñ‰-Uÿ©E¨€‚9˜A9›D ~ƒC û6[j†eoHôý:þ7Þl@L„Êkå ƒ ¾ÿÇ@¨î‚00ªìk¼\ ÈÄÄ`xàÑ-†W‚}Í 4ÌXà>ƒ±Û[©`5%~Næo@5ÿÐõ{v‹Aèý/–_\ YÙœn1ÄV(§Ãÿ°_ÇÝ%Шƒë Œ¢øL—öVf†|^99^Y9ªT¹Ÿ?bø Ìšo?ÿãÜx³(ôh/؄߾3䫸;1H™éÃó(%PìQSu†g§%>î<•ävñ3hÉÈ@øøõ?» Ð+©b9|ùÉÀ~÷%ÐlPqÀ *3` |úòŸáÏ÷§ ?¾RÇò?À¾ôœáÏ·`³¡<ñ–¦’Ÿ@M?þPnù_ 9×^ÁO†¿¿XÀf£€Â `ü;à7e–ÿ&öûï€ÁŒÆ¿@3ý›3@Qð¨ùûŠâœá°´þý ÿ øøÓ„á€?@»ÿÿ!3 @–½ûr¥ ŸÃð X o€ÂÞø' þý‡yˆäàß@Ó¿þB±ACÙX@±àL¹°(`a‚T# a†ýû5‰M ÅØ‹d€Âá o~C€‡bùßÿ¡XJ¤ž Ü!Àņ`£Å'œåÇ/ ÿüùËÌð™C„a—ÉW†ÏŒ?Þ±ŸaðÿÉ ÁiÊ øÝ€Aö¨Ãþ7ý ŒöÜ , ì 1Ÿ0Ðoþá¿ÿì <\j ·$þ1<ãbøÈö–á5ß#~&1Æœ çœaøüþ7ÓN†ßþ ø@,ÿþa±þ231ÝyÍÀ&,Ïðóçw‰×j ߘ¾00rs1|ûûƒA˜W”ALO‘Aø¿ƒ” Ãæß»À±@,°èøËÊÌ vãÃeÕã ÜüR _ñ0\8à ªáÌðï;/ÃûÿwxÈðˆóƒ‹¶33X@ EËÏß ·Ì5þýcaø÷ó5ƒ¢« Ãæg'ÞßpexÿþÃ[éE ¿õÙ>üúÆÀù€¬H0 #ˆÅÄÈÀÊÂÈì-)ÄÀúá Ã1¾ßìµÊæ®ÞÆPײo;#3ã;Æÿ@•L [þof(¾ 66Žo ß><ýý¥pê’/ìßÿbûÿïça)†SW®1ü¿Ã° È+!.þó58­£µu°ã›7ŸrnÞÚ·hì   H)µ2•ÞŠ\Ä–”†@š ${Fl‚ÄHiv0sô~¨ò˜IEND®B`‚twinkle-1.4.2/src/gui/images/reject-disabled.png0000644000175000001440000000055110503576707016472 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ6 h¬<ˆúIDATxœÒ-NQàï5“n`U3ÔGB2I7PÅÐÖP…¨Æ°„Y XºRƒ¢AÌ`’‡˜7?­êUïž{îïyœ`aì¬b^¹jÉw㌨'†ŽR*Žšì¼&Z6P2͈’µI± LZ¨@3ôN …i7Ó*–j?j<ØbaƒÜ™¿± j3ÌQÚÈd6Ê„ÌÔúv¼cimoom™~»ÛøèŸGÛ]áÚ“·fk\:¶Ü_7xîKï#ÊE"’Q±èÁC{Q…^–]º÷6 í®¦­Õt1ª2ÈÒk½ŠÜ§¬Ï{%ªÀ4î“w~ðUN²¤y?Ê‘GIEND®B`‚twinkle-1.4.2/src/gui/images/1leftarrow.png0000644000175000001440000000114610503576707015540 00000000000000‰PNG  IHDRóÿa-IDAT8…“OHTQÆoÞ›¿o¬FÔ±Y„JX–P¢‹@¤%"AÝ´lUÔ®@¢!"#B¡ËjéÊE´ )ŒZôb¬™FŸ£=ß{÷½ÛbtqÆÜ{¹œs¾û}ß½W‘R ønàÑ¢a4=Œ¦‡ðG¨zHQýêy‰Þ¡¦¶5èÚÙ€´G?OvøøO¸–}w•ÐL[w29~ë”z¤ãDÜôÔÔV^«Ø)eÌ2­‡²±ièÜ@;·{ª8Z ³_«Xð¶. e“m‰gûÚZÏ^éàâ1•5æÓ°lBP@A:NÛ†˜®ï<Ý<8t’ö„Âe"¬Zà9eÀ³¬~©~Ü0пÐ×B\‡Å ÈÍš«6HÛÝ ¥¸æV'R#—‚gºpmXü»“_@…¼žã”‘ ¸_{u8Ø”Œ“ùi¹Í¬0–¥uv9°=øf€knVKp%x²°5lX+kâÚÊMãéDj½ÿrÐ×r,. Ò+Ñ¡í4±ä!©È¥ÅÔÄ/ûÍ{lÒÜ’!À³*^càfþ;3SÓ~#×éê|»¸el…ÿ®×ë̾žó^½¤& ¨A]êtˆGÁ'öP¾}ù·sϳ““„3KŒAmê÷ƒooÅÔ2ø‡ cŸ<Ù0ç?¨õgÇX+ŠRŠßY¹^ §'ÕÇb ‡Ž¯ÿÎeM#?*6îüÛÍç³æ1„pIEND®B`‚twinkle-1.4.2/src/gui/images/sys_services_dis.png0000644000175000001440000000137010503576707017031 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ &žõx÷‰IDAT8Ëu“KHÔqÇ?ÿç>Ps+jCk­DLBË,è¡(ÑC’$<„ÔE#zº"*Â:D êRY(=4H!Ù°§¨+QF…&®»æ®»ýw§Ci>þÍï2ÌÌç 3¿°5‡;ãˆjÚet{ ó@í¹óm—.G7;ô b|¶ÆÛ¯”ò?Ó]Gý~¹õ«U†ÄK¾Ë5©‰Ôøþ¬,i²¥C,ùg–Ü”š¨v@þÁ-F. É©§°“ôlÛtï–í ÂĬLº}Ó«Ê7,V!‚2#%dl¬^‚FŒ>V͈wìŸÛƒ®——ÛyÌ/44T44â<”ÐaÐ ë×e¸Óšñ4Ããòh)^£ˆ0ƒ$0é`Ç”ÒSÜÊîGÁ^=1¾q×· H ¨´bâÅKSÀsöq¯»w¿6ØÖåmÍK5QÑQˆÓ€ƒådàá=9,BC£Ÿ×´<¸YîUI´\(:r¯+G†ùŒ )Ä100ˆ3ô©±2ö 4Æ>6¾þj®ÏN1¦œ8°ò’ëÔs…f×¾}“$†_uÞÿRX°Ô­øÃ"Âaò8A%ÜçÉ>ÀŒ±†Mu©T‘àý¼Áâ Q‚Äì×{Åê….|<¼aœ•är–ã ÒM¶Èm  |> ËÈ$‰ r¡“¶5Ò7Y3ý§Uß.Çߥk4 b!¨²º|ZÑ?×Y¶É£"„¸8Uy~Ãé»=‰$ ÅÕ»sÝv±[>Ê ©jtfþQÈ;Té‘€\ŸðfÍ)׌“ýrõgÑñéQ3wï³§ÉNÙT70¼§GuûÊæ)³„Ükë.…ö4ÏœNß~sý/Z“U9éÿjsûwF¬µÍIEND®B`‚twinkle-1.4.2/src/gui/images/settings.png0000644000175000001440000000144710503576707015316 00000000000000‰PNG  IHDRóÿagAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<¹IDATxÚbX¹r'âEëÖ®ÝÝôàÁ‹oÏŸ¿ýpøðÙ£¶¶În D€bèè˜ÍÀÍÍà /¯¤²páš‹¿ÿýׯ?ø¦£cèCH?@ ðfddf±¥¤d–.Ýrç?”•5 âÓ@LFFzë""û˜™Y¢£3,44”EþþýÇðÿ?ƒ¢¢‚P*>ˆ…ŸŸûoCCm´´ŠŠŸŸ‡£šš<÷§O_XYÙž>}ñ ¨æ>ˆY]ÝÔÕÂÂPÁØXWMX˜Ÿíû÷Ÿ ¿~ýfxýú=ÓŸþr|¹òBˆíëç'ïþ¼Äf@1ß»wÿ±  L´´$ÐÛ ¿ÿcøöí;Û÷?TÄ~s…ëuõ³g :|öû¥~ßE7 €˜ß¿yÿèÑÃgnÝz,sãÆ]Ö={½cdáåTûÅÂ{¿žAôý9~FkKIï£ç¾]|õ Õ€bDbó±:ÿõ²2ˆš”Å[$Åt…“™áÿ_†ÿB\ çr½‹kyuíÙ·0MÄŒdÀO ~ ÄÏ9þ½}j¯Áª¬ÉÍÍÀËÆÀÈÅÎÀÈŒfÉÿœFJ^‡/~¿øö Ä%ÄŒ-`^}þ÷ú蕟Õż•µ98„8˜JüfûÇ©!ÆïuøÊ÷S¾ýy@̸¢çí×ßw]þ~Q‰›ËKMŸ““µ ÷ß%>3(+²p>Ë¡tôæçõÄŒ/ŽßråÇEYV/MៜŒìÀ ûö›éÃÙ{¬ {¯~Þ @Ì„’úÇ¿ï¿þó¢8·§ŽÔ?.F6†ÛÙ:¶~;úäýMÄÈ@$àçtðÕå«çeTØyýûõÓ>Î ï ¢ @D5£20R?Ccì@€G mžãIEND®B`‚twinkle-1.4.2/src/gui/images/encrypted-disabled.png0000644000175000001440000000074110503576707017214 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  šœtIMEÖ&Rž,ÕrIDAT(Ï]¿K[a†“{½Ñ˜Þ„P…T$P…ÒEÛ¢¡ôÐÍŹî¢K)t).U:éßà"4‚K©–:ÔÒFŒI“šû;ß½_‡/½ }ßáÀá9œóž>º*çî.æ_Þ)Aûìf½¾¹ÒTý¤*oòæò“W#cÍϯ““G{n ¬&çž½.¥O;­ŸŽ“¼oèÎOž~û$!¤‡ÆÌþöÖáø×;kŸí{æðB†.àiFÑàûuíCù¢ÜpßU/ú‹ž6\j¿ÅÀûšåûØh…!Oo!´©Â§º¯s4¡6fRË™é¡TËM«LîCsÀö¬}ïíREƒæìüL <&–L]½øø…Šulµ©G›sêê†ú€Ã/, ¸Å¡¿g6ÂÇBp«‰G‚ˆˆˆA‡ü3!‚Aصø÷5öXáÅ@u·­g$±ÁoS…?múŸ’h¢.9IEND®B`‚twinkle-1.4.2/src/gui/images/mwi_none16.png0000644000175000001440000000142610541072237015424 00000000000000‰PNG  IHDRóÿaÝIDAT8½“Kh\uÆwî½óH&3™Læ6É%é´©¥”ÖG¤ô…¥nDS¨AhéÂMÁXR\Y|P·.ŠV$ˆº² ÑDjQi]8R¨é¤L‡É$Î$3só¿÷þ¯‹X¡›,=Ë~ßáœïø?kÏžOvŸ={õÕ¡¡¿¯i[ÇþʉãF&“8JÅŒe]×SV~¬Õ8 >h0=ýÝ©#GÌ\³Ù=³cG6—Ï÷õÇã:Ѩ†¢(8Ž@ÓÀ43‡´‹gßšœ9=<œ1úû{±˜†®«ÿ™†!H ¾P¯·0Œ433èÇÏ Ùál¶'ÑÛCUU‚„Ž – –R­¶ˆÅ¢hšÆÞ½Åâå À€V.oüê †”©T(:¾~°ÙÝ.Íf‡œ‘ÇóvçC)ÃkËËëäriâñ(årjµ‰ãHZíÛø³Taûö¤T³I²ƒ=Óß—‹·oÿÝ ¤B2™dÄ¢ÝîP*ÝÁ²:T+u’} ôh/®»9–í@¡ÛŒñÊ•“ýæ—¿W¯]Þ åö©s¸ñG™õ¦Ë±ç‹XöýeB atÌ`×ø¶×´YRmæÝŽVØFèvq˜@ê}ì;ÿ>Žëáº:þ¿°!õºÅÆF®­v|M‰ÆžX¯<Û(YDŒ<ì;Lx¯ŒúýW4Máí|‚z}Z­ÍÊJ›µUkÎuüyËöµ5ëSåWó±Å®ŒŒU^~3m=Še Z×bèëKØóíÁ·ç?œ—’¹.=9÷à­¾—V~ÞýÔuóÔKO T:wkt—–H¨’¨®„K7—g߈½þç…%!‚»B„!ð`Q5¢¯v¶’ËUÓ\¢%…ܲ±ù&>ÊÂøñ` ˆëC•1 ¢bR¬GÂ5Á>}†0‹“d€ñ ‘è£}¬©æÄ‹<)ŸfO™&g0>Ž~oÁÀa޾Pâe¥ò‚ôl+8ÎMýmWFaÜÓÙµÿ½©ýÁk‰Ô@®´¬<³Œ“Dé¨\´G5CSU<ÀóÇÝ{P4‘ßïy„iE¦Í¥Å|–)‰%gÚdQQcÉ¢O5Ë|* dÉÈ6 §qˆõûÐÛ)AÕâH6·àô‰¼P1aHDGë¯À–òsUlùEˆ¯ q=*n®˜Zžf2˜’è€î ‚˜ =í vÕmB31&]D¦õ~mÅÜyC µbͪo°¯Niý㲺„¿Ño_Õïms Îó¼aóZ㙈ßN?ÖZ‚ÏKËf+Š‚³z©áØåæzϵtšùœ\õXÑÀÙ·}bøhµ¹Õ™ËOOIÁ3M)«ê¾JñU-4~,Q6ÈÎ\n‰$J¶áÜì'Òåg®4wðÿ?õ`$¦ÌWáIEND®B`‚twinkle-1.4.2/src/gui/images/searchfind0000644000175000001440000000122210503576707014770 00000000000000‰PNG  IHDRÄ´l;YIDATxœµ•!“9FŸ·z˜Ä,(8Ël¶†h–…ù]†kfÃ…=Ì5LbÝlWm.—ó¦rû!©KõôI­n-ú¾ç#ôð!TàÓÛI)eN)‘s¦šàDˆ1c¤išÅƒsÎs>ãc`½û N®ñ”^Ϥ”Øl6³÷þ]ðEß÷äœç——6Ÿ;6_v˜jŠaT«ôߎH6¶Ûí»œ?¨êÜŸ{º¯Ï´Û3Ã’ i c öBÉ…vÛAð Ãð®«xH)ácdÓuH^RRf²IFÄ<ÒG¬Vâ¦eL‰RÊ|0Â<ú«ß —XF=ŽPi™7ÒëØî93¥õŽ!n0íõS2WÓÅ÷-œaýnë‰ <÷ê§l€RJ)åßù«åì·-ªIEND®B`‚twinkle-1.4.2/src/gui/images/mute-disabled.png0000644000175000001440000000061710503576707016173 00000000000000‰PNG  IHDRVÎŽWVIDATxœ}”¿­ƒ0Æ?ž"JZH›% +Ðd³JÇ În<‚ÉÌ@EV ¹W¼gË.ù$KgÎþqwò]EDàÔuëx½^{ˆ’%„ !Yk‰“÷ç÷ ˆµ–ö}Ë+ßç°"¢¦i¾iš$2kmûáÒmÛ–-C¬¾ïËq)ù¨>ÙyT—o}¿ßض Æ ÀÛí8Ž£8›¤vžgb{ˆR Ƭë|çypŠmÛÆFéau]@šZ]×ß2ýzîü½Ö®ëHkƘ`/ËÂF6ÏsxéEjÓ4aš&€R àœ ð¸.±èz½¯Çã‘|‹kS€8À²,x>ŸˆÛCâ´ðÉ8ކó<(§Û"ZkÜïwh­áœCUUIì(‰;XJIRJrΑs.´‚”²ùªòÁ6Ž#;ДRü@û×/§Ê£æÈ¨IEND®B`‚twinkle-1.4.2/src/gui/images/favorites.png0000644000175000001440000001007410503576707015454 00000000000000‰PNG  IHDR@@ªiqÞIDATxœå›yUõ•Ç?w}{ïtÝ€,ʪdH@4ÆÍŒ+˜ jÔ)f"eÄL³ .SѸ”V*5cp¢&&n‰ŠÄ†Ùf‘†Þ—×Û{ýö»Í¿ûè›å5ôã9U·n¿÷îýÝóûžs¾¿sÎï6œ%qž¢<¹Šÿê\Éȳ¥€|6ê¬3Á‹ªÄŠb¿wõΆ.gº(3L®4,æö}Ö­È£$â½p× î´¡Ö òáq02ÜoG@Ÿw9p°1ñð ‰Yxç]I& ãB\ñ©Ì$ =Éiw1P‰pùý@1"í;€-@ k–a«àµ(|t.·0Äd8´dXe§@?¯¹zÐŒ°¶·ß£5Àþ ´£TÜ€6¹œD'\4œ[Æ mb4d8Ï1ÖH0ËŒƒ>0Áü5@àôSÁ| Š]s+F ʹD‚s Çá' ùË|&R Qé¤/ž~ çÄ´cÀÓÀ\ú¸¢ c÷v`Æ$ìÞvw FÇç¤[j1Z ŒˆkÃìIé3,ÀBYÙj¡‹½U({I¡r.†ûü9@é P|ØÚ8dŸ¼ÃPôáî$ ]Äñ4÷f\ÓdÉA úŽ{ÒïºDu5üƒë &‚3Æ‘CzH‚ýËJhÂI6aÆš1»Ó˜ »c'fÛ.Œæ:ßn@r  AgšF`œôâ¸y¼AæÒ ̘—½ ]‹…\ål÷A ÄÀ‰Ý÷îD°}»û· t!*¾ìÚ?ûg%ë†i ‘-êîpõ(Bf¹ J]|îõ…îuA÷ÙµÀ>š}œæ×÷R\õ >»~+÷˜–.¨Ä»þ^^ ¹`B%|{5ȇwÁnt'ÔDû'ê*,»õçUÅ.@n+nhÓ$ Zvl§ßÙvY²$]Ä«„°|N·Áo¡sS’òJØç£o~ÂãÆ­ûÂ*Œýn¥áfw½ÚB°€ÌbB²WŠûY§Ï²ý')ñEkŸÈò‰tÌùØû³îŸÞÕ‚¸ 2ë8m öÜßMâ”VÁ¶nÞ»y;Ï-À ûKË`ÃOXUUÁJšÁtçj¤’;ÁZ ±ç@©ùxJåQŽ:…íR‹D½P©bìí¦æÁ&ÒmP2>ó»¥;YˆÍ:„+œì€{&”óa04PïüRõrÈ\½kA©p}¬kæCœ¾“`CRƒ.LF+$7´²oU/N‚eðr#ÏülDU‚O¬ùÚ»¸þ²óù=aH› Ýö3äI߃؈寧'bõ!YÙVz¡G # ò—>–B•ÅäÝËOžoà#D®ÝÄûuÜ*ë¥íÔ\4‚M«¹A±PÓ›ÿ†\G» œ?B¼'G¿eV2!%C‡¢š ýaÐýZŸLáó^Djå\ÓÈD"Ñ€Xº¾ 'õÝÇ®fÚ²9üY7¨L´€~ã·Ñ.»"ß„n<þ“ qú’4ŵz̽^á€e*xmZ_ì ~Mš@)X:oý„>°1ñÄRõ%9i½ö mÑ4¯^|.W”%7îÂ6Ó¨Þ™¿AÂIۺñ@Î@ZžÄ=â» Ô4ÏvÐøšAqDd-ù„•ŸEÙ‡ˆ÷ s¼ù2{]:–Ð+‹y½Tá²h¨óà_T‘ßAŒ¡m­È@Ò½~°$ÿ% dÒÔ>ÝKç&(­€º ;¬ç§ˆ5¾‘‘p·9'ú–$hÿ¯•y¹!ÒÊ„ñnI )M‚ZŽÍƒÎ„È@Z†p¡˜¸ IÉpàÉ$={¡¼vöð×ÚĈÉA,w']§¥nݽÿ¤»  Þlà×Ëwñ2}“ä2ô #wEãìGB÷=Ô¦•BºÒõôÕ2ö>,wlÕ"z¢Mà-ƒßæÙ廸Ä(×ÉÃi´ÄÖ­Û<ÖWXPŠÀSˆè#d8ó< ¸c&À[ž"À„M|† ºŽIpNUNƒ»³íºmdÚD†"8ÚS8ÓÖw;N¤ XJ0áÊᜇˆ÷AÞé4Eçgv¿Ž#‰JTö"R¬»žIÉryð€^fŒ0aDQ;ç,ƒÀq y~z=Hà)EX+Esxãß ¬£Y û  GBÓa( 0^—)ÊØt3HIÝv¶VíõÈ2¨Ù]®Œ«†qœ#ÛÛȦö'º6{˜î‘ ‰ +À0Àå—•Þ‹UƒÀ7…æ:¿Ù RÈ„{öW´ÿ‘µƒàéÞ~CÙ'¸¯?/Hƒ7š4ßÄc8£A˜i6ÀŒBÒ‚ˆ:ËmÌ|éÀD'"3oA,\ÙÚÌ9Î}ý½ @´x¦•†ILG0(æÉÿáyÆ¡÷DO¢ѳ̺ø±Ö“ÜßI*îu½ˆžeÌý,pï@¹€ (à/„d*u¦! âAyÁ < †Ifz²6‚xJ±Ÿ þ–“Ü ¡ÏíÀ Vº·ƒµ‘å%úMv ëg¹@Ï*(Äb…Qç(e;ȃ c¸œÚ5Å·ãÈ †ÖéÏÁª«NÂí³ßy„ò={ õ ¤ã €Š1P6(Ctϳøcë¸ìûq•²Gfø„ £öÅÙÇ “É < à|»í°d4ƒÝGŸõ³²=˜f„Å=€‰¨ÝM{Á«@¨ü:4Õ@͇ÿÁq¾Ù± ÷;|^ð„@6aFÉä/s¬ú1‘J^úZø.IQ‹pk׌04OžްØÑû?Üʽûc¼]\ vöoÚõú A’1ú:aîˆ$β‚!H&à?“0ç9…€ ÀƒóÓ¶"I Ðçþ*}Db/$‡¡³TÊBÐ’¤öÉ]üæ—5|t¿ZÇš‡¦qñÂ*)Õ™ÐÕ‘6( £&"Â"àN/Kªnhx"ÂÆ¨L§/xrzÝ>§¥Ãq"˜öt×Ê«ôøÎ0ås!0ˆN» Èëp d (ô€e‘\s˜V|Âî•aD!“tõ¾ð¾ûŬ”,|‘8¨*Tac¯] Ü%4ü9ìÞ …œ;˜±ØOŽEQŽ!P0EµèVS)žDúÛè €‘€ÆCÐܺÅ^ØÖÁû_y“ÛV|ÂˈVÕA÷œí#Y@äöÍüüö-L¯MðraT ì=ëE'žDXè€ BÑ¥’¤›*˜É B GºÛ›Þzë3,ößUQ…GÁ¶ ½êêÁÌ@YŽ$Ùºôc¾·ð}jJ²Ï½º,¹ª¹©“ƒWýÛW×rEÄbcib½°uܙݭú½øýÂË&ù˜Æ þí&çìéÐ"~¤(<(€²B ‘tEÅK …:DÓ´¯ÞÏóî`}ÌÐAne« ø9…;f³Âg3¢'šÕUP5 ÂîµÐÕmðÁM5ÜŽ«ãv•œˆþG‰æ¶Íi…ÙÅ:xUhB:~Ul®käµ»7ðJW†fúâ¼—Áo$*ŒüéxîŸ`Y2ñü0õ"èl‡Ïk@Ñh»xó’:ÕÁsÀøwhI“4͆´-âÔ/CM'ïÙÈê­a!¬ÞŠpV㄃žºh×–3mY5?/SYK€iƒÏ™Œx;`Y-Wlêåcr œ8@Õ¹@–Ñ$lJtˆ~hÿùµ7øáÖ0;1þ9ÂåÏÔäŒ7ÛÙþõm\ùV˜%†Êþ"RnfÚ° Älr|³4§<À¶™§9àÑ!š!òß{øí÷7ò¢¬Éº{,—1sÈü¸–—K5Þ[uK§z¹Ï#Q ;p¾—Yˆ¬!Ê)æ9-?˜I“cqÞž.¶-~§Öd"yÍî ¸ÿ6â$mâït±±>Ûã<„b©W:øSMêhéuJ ¦†Öj÷Ü…ˆ÷SfÝ! aõ2d½ñ”ö퀌˜¼Cþ,~*â–\GK§SIä÷ÿåÿ¸ªµ^JË«IEND®B`‚twinkle-1.4.2/src/gui/images/sys_encrypted_dis.png0000644000175000001440000000145510503576707017207 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÖ/"Í Ñ¾IDAT8Ëu”KlLQÇ÷5wfJk´h¨v˜¢£ŠFD#HÙHDÄc!‚xm°°‘دx-ĆŠ‰ˆ¤ ¤‰Ç¢Æ#•VHS-¥‰VéŒÎ¹sçÞ9”Ñç[œ/çü_N¾ó?G"çнEÛV^¯Y_¸3* ¾ÿz®ÿÒ%7àß±ç¸wÌâ}sÇ•2ž’Qú’^eAÛƒÄÕ³éLÍÄiÁézwêiäu<®tmVOWõ«f!çÊæ×UZôŽdcCKUkųacBÁØ VäB['):/"}Ž~8ú-q¢ó“…Ëoª9µxár ›_» àL_,™ÄÂÔl`z}õ¸4&¤üPIC [3Hj~R6°ýî–_°Éc©ÝHÌ(ðfì±yd8 ªµ—šòô £öŸi:¡Vš;Á›_ä²ò5ŸÇ§Œ(ÖæÑŒ‘uVAí[TǨYµÐë2‚´@ÄùN ó¶Òû°µ%¹48Ò…ŒŠ„Å bPHý “ `£³IAD߆¯u–—N)”½4áÆJšILâ$°q0xþeÁî[mŸ]óËG¸èç*åxp°Iac‘ÂÆÆÆà]xÈKNÿóg«fOôJ-Ä ¢ccã`ãàüž£| ÿÓּЕ'•ž—\҆@âO@r0ºÿŸîMžYäQáã*p#qñÝáÉ• Ì®D)%¤ÈÈB“Ô©vç&Ó|rÙ* É£ø¾6™*fÖgˆþ¦îºZŸŒ Ê它«UºÙᤑPX´NwåxËN¶‹nÑ,ÖÜr—üªÜ}*Þ!ºDƒYìÏ’+Úðq>6o_檫bãý{ég¢vW Šìm/«+æ_Å;g×éèÚ»Y€Û]¶ÙU˜û[é_=”ÿƒË dÂ!‚IEND®B`‚twinkle-1.4.2/src/gui/images/presence_failed.png0000644000175000001440000000150010637222527016550 00000000000000‰PNG  IHDRóÿaIDAT8m“[huÅßfg/Îî&»ÙK.²hR)ÆmjšÒÔ‚¦-¨ú H@E0T«è« *‚‹(£_‹>hmPZJK/i“Ô›,6²f©¹lØK6w³3ãCl4m?øÞÎ9p¾s>á6si[¿ÏqÝ>º\\q‘ke]<¦z3Vn"š¯{\÷… RáÆ4|™ EÛ)U…¯‹ºçí}çNÿy‹À¥mýI'¢‰øæð3O£í@ pkuªcãT¾ø’ùÌT~Öïò‘Ó'O¬ Lôn7•È…¶Þ­›}¯@š·s†³Ú ðùaæ~:¶8iš÷<þ—°¿µýX2ù˜ÿ¥ÑC&ž–ê¹Nµº¾(…‘ˆ£Åch¿Odv.¨=úðˆºÐÛçóÀóÞ}{±+ôh-ÄH¥¨Ïç©ÏçqVmü›6¡ƒ¸¶ƒ<°‹ã m™Éµé@Ÿia»¹ 'Ÿ§øã1Â{ÂH$¸#ÝCõ×+·ßÀâwßc~úíå%\¥ÌÎre§t©H„F>h(Åâ‘oˆ<ñ8ÞŽvŒ½ –}Là—ãx—–AÀ§ixDºt@´z-;ƒbøò 07o½¹v½ñ ‚G¾ý/7W‚#¢”‹\sJ%¢S"—¯Ð|qŒ@(„÷d¶¦áÃÿ è5§ÁŠHN•um´dÛ%A4…¤{ÐÞ{w |àUxùµu÷£÷±~lŸ‚í,_4«ÁógªUáð¬Ê8Ï=»æùàj5 ÷tSøÄbu*ƒÜ×CuÏ ³JXðèG³ñØuéhŽØÑ–;:–èZ„Ùì-E2R)*ÇX8{6÷s[ëSÓ‰Øèz•ØÝ™¬×GÂéôÝfw7"É® •ÉIйSÉÄþß’ñS–e•7À¾Úý`kªºòF 2îJ™Þ¦fjÅõ?²Ë…ÚßGÏ%⇦±Ë–e•7<Ó6¶ÌäÚ:Ë•‘.GD­ˆä®FšÆ³ñØu`Ѳ¬ú ü?ö_&¢ˆúIEND®B`‚twinkle-1.4.2/src/gui/images/attach.png0000644000175000001440000000131011000421172014661 00000000000000‰PNG  IHDRÄ´l;IDAT8•ÔKhAÇñïLj…ž"=ø<”‚bOÍA<jƒâ­ŠH}°EA‚Ôƒ^¤D,>v¥ìÅ (""ÅB‘ˆâA,Ö‹-µIšù{˜M6›¤¶™ëüçÃßÌ."BÃuô›Ã‘/Bß·ñÀìKDÐ wŽÿpPÚ ¦ö½m¯‡OþrPÊ&Q* ’qØõ¦)< Ÿš('D‘äîª,F’ˆä0â°íżñ>3¢Z'¹Ù‘³ÚEé 69›žÍ ·ðù¢ƒ"D—ZôЧ ÄEë”MŽÃúÇsâ¶‚V½ ´ç*»÷º¾cL/ÇH¥R 9DÖfþ‹[XÄÀÈ©ßñÈÄpw#ý@È u °xbxVÜÂô#x@c|NüŒâÖxH€W’x×PC<¼¼Ëmý6¹$ãsl,Š?ZâRU âÐy«·ð¹Bg§&ˆé4"B#>Î×(þ´§×)Œä– ºõ°]qŒøÄbijñ9ø1Šg·Dq­S•§Ø>àFáK­Y„ Cã£ËÉÅv¾?Å_í q‚ZLðµ]qk;öS…«4ã³{$Šîõ0Á¼!Vu¡Ô~ÒW…¸à£céÊ…–ŒÏö—Qü}ŸG)˜o]ø#ul×µÅUOËØÎí;·¯eóó(^œé¨3Â7VÔÔR…—ŒÏ†'ñ†çªVˬ;·;=pãÓKR,8ã³òÎ3f¼y`hµÇw/­“ˆâ'( P€éB“0Àýn=£Ar±ÉÇÆ¯Ïulnì¿bÇë0ùò%iòAÚrâ|´ÚX>¢D¥Ô¼|¶f E—bž†ðß›ùºªæÜ9—×MRd­mÛNn¹\.f­"@UͰ¯%¹mÛNTŠ"B]׈MÓp:âGÀ~¿ÇZ뺞̋HV3JQUÛíöe>„Àz½Î¹wmîÓ0 Exï=ðk¸™·¿TF 2îü”– «ªŠÍfóp¿ßŸIªÌñxŒ‡ÃañpIU‚c¸ÝnŸÍ.EzO"‚ª2 óý}ß¿½9„@ß÷“V—âË9g®×+»Ý.Tï=Þ{ÞûX®ëpΙ\šª’þQ×uÀÓÄdj7M“Aãî­æR^’¿´ïåÍc¬hißÇ¿–c%•Ô•âPè×Àž IEND®B`‚twinkle-1.4.2/src/gui/images/conf-disabled.png0000644000175000001440000000107510503576707016145 00000000000000‰PNG  IHDRVÎŽWIDATxœ­”/ˆ2A‡EDn‘MÖÅ ˜L–Ë‹M &‹ lAƒa‹  Íf5X®NÙ`µ¸‚Á»bÚ §È*È 7_rqÏU¾¾ ü3óðþÞù2M“ÿ¡È£ Ã0dP¼Ûí†þ tL§S\×%úújµ*ƒ€¡[k†aÈv»M&“yjò,z½žþ I§Ó(Šò°e2Úí¶Ï¾ÏÚ5EQžft…ùdš&º®K!„´m[:Ž#…²X,Êf³)ÇñÚ5&„»ÝN !¤®ëÒ4ÍàS[.—4 r¹¼¿¿Ðï÷I¥R ‡C^__}Yù@®ë¢( õz€¯¯/âñ8•Jųt<½ù[…o›ÍÛ¶Y¯×|ß->NœN'f³¶ms>ŸïAápMÓ(•J‡À"_•ÏçiµZ|~~Þ[ûùùa»Ý2Ùn·¨ª €¦i¸®ëmB0ˆÅb^Ü»†aÈétŠã8ì÷{jµÅb˲8¨ªŠªª, 8Ñu=tW#˲ˆÇãhšÆd2áííÑhD¹\ær¹°X,h4$ Æã1óùü¾FÝn7ÔëõX­Vž¥ÉdB¡P ™L’ÏçÉf³”Ëeæó¹ï‰„~#×kßétˆD"¼¼¼P«Õè÷ûÞšÁ`ðüуô•<ý«þê{ldù‚¥IEND®B`‚twinkle-1.4.2/src/gui/images/transfer.png0000644000175000001440000000065010503576707015275 00000000000000‰PNG  IHDRa~e®PLTEÿÿÿ0/e4/OHpR^`llNJ+uI>pn.12COPGtKBa`IurmŸ55žc)Âl:§7B`OÑma}€‰‰¶¹¤˜•1°”/±®.ω̲ë¯Æ“(Ì´,¿Â#ëäÌË2íÐ*Þà2ûú2«—Y˪XÚÒbz|‰˜“’ª’¹«•——¢¨˜¡°«­Ó®ŸíÝ£»¼ÄÍÊÌüÎÏúíÑØØãêßàø÷÷ jØtRNS@æØfbKGDˆH pHYs  ÒÝ~ütIMEÕkR,csIDATxœu± €0 D%““dèr‹ È}€ƒÿÿc¶Z­øÆÇ%½fþÊKX¥I™ò1náä2T‹X º¹O»ÆhÌ1;ŒÊ‡òx³¥Ò½ÿTšàZÖ.•K,¨Îpu-˘2ÙðSnŸ »[tÇysð(<DôIEND®B`‚twinkle-1.4.2/src/gui/images/dtmf.png0000644000175000001440000000054210503576707014403 00000000000000‰PNG  IHDRhûÞWPLTEÿÿÿ€Â««pppþþíí!…ÓÓîîûûùùííéé÷÷ÝÝææüüååÿî3ÿÿ3™™3ÿÿÿÌ™3ÌÌ3ÿÌ3f33ÿÿדW“tRNS@æØfbKGDˆH pHYs  ÒÝ~ütIMEÕM;ã„IDATxœ}ÐÛà àRãΧPPxÿç\!M¦ÎìOðâ#AešþD|¨þc ¿²]Š5ôªƒ;Èváé}N[bIEND®B`‚twinkle-1.4.2/src/gui/images/invite.png0000644000175000001440000000052210503576707014745 00000000000000‰PNG  IHDRVÎŽWIDATxœ­”½MÆ0†ŸDôY±Ä¹£K…ÄÙ€†ѰA<¢ù2o ÄLpvBœ8úÄI¶.çËëçüטÿa7GƒsÕÆ›Z¼ÙÍc<š .X ÎÙ‘@Mp-Ö^#’ˆÊòÛ³ä¦Ñª_³öŒF$VýÕ)Ñ8JÕ¯Y¹ýSÆïUÇëKŠ=<:TA¤ÌÛ M ]ÆWrI¡›ÿq@ß•œ;-á(§ ð1‚j.m£©óq¿ðËœw.dTQåã]ùüJßw·Êó=„Þà N–C¹[lßg_–î7 àQ@aÚ ™ÙÒ¼ˆÙ3“uxß.˜±uðøÒ¾)ÚùbL¾ÃS¢<½´5Á­ýù¹Ö~ɤ¯äŒIÄÎIEND®B`‚twinkle-1.4.2/src/gui/images/mwi_new16.png0000644000175000001440000000146710541072237015263 00000000000000‰PNG  IHDRóÿaþIDAT8•“_h[eŹ7mÒ5mcC¶Rg]l“ulatsè솨°‰ˆ+8(ƒ"âË@üƒÛDö°áS߇VTD}r2£«¦Ó`umÙtm“. mRoÒÜÜäæ»÷~Ÿ*Ô—ÉÎãßy9çÀ-hæècÇgŽî;±ÖÓn%à¶þ¾±ð–þñDÏé­ÿzþ›{÷~°ÿÙís= ­m$è´o”Q½Yç¥éS÷„†ß• Û·8vìüøîݱh©Ôx&D»»ÛÂ剃t Jáu ·<ÕX&s¾r…“'“¯¤Rs™ëךiÚJW­•¨”TîìSÊI‡•ú­S©_;•;ݦþ8ÿnÿÀÓƒZ½.v$‘;#‘u-­­t]Çó@8P·¡¡…i}sUƒmw¦I~4_Õ2™Õ@Ç0jär¦éPµÀ4¡b‚Y…òï— ˜³]N¼«ÎãƒSAMJ•ÊfËD£ƒÍd2òùõº¤b*j5ÊbŠåô(nlm$Íbò9Ñ4וÓ×®ýÙð¤P(ĦX¦Yevv˪’ϰâ‡Þ" „Æ¿ãm¾±_þ»Æ‰‰Õm±O.çSg·ϪÓáÚ¿Æ¥™ å’ÍÃaÕ@Jp]ð$ôö­§ˆƒþ$íšÿãUbÊn`@6µ1|äuÛÁ¶›pÿ…P ««žZ)V]¿¯9ðPg9·Ó˜µÐÖwÃð(êFý«O1ÃÙ¼•B¡ÌÒ’Éò²ÉJѺ`×ÝI«æ¨•ë=_:60ÝZ_îÉ:b{ö`Õ•‹ßÒõÙjùb׫5ÿK6ù|àÐiÇQW„ð²B(%„Dp©9ÎaéûÛ{î¸oðóÞ}»†üÁn±ˆS³Y˜¼t.ÿÓÕ±1r•›ýÅð~So$²yÓëáX÷@iþÆÆÕì‘îœùý TW‰ GV’IEND®B`‚twinkle-1.4.2/src/gui/images/presence_online.png0000644000175000001440000000152010637222376016614 00000000000000‰PNG  IHDRóÿaIDAT8]“Kh\u‡¿ûŸ{ï¼îLó˜N’24¨ •š­]˜R°ŠvS°JPÜ•".\(T¡[ÔE7E+H±Ziêƒ`j“*–¦Ó6I”Ú&f:yØL'¹3sïÜÿq1UÔÎâ,~‡Ã9†ˆÀ5ª .ÔŠ`:»u²ÿŽïê3ã)[Ê#¿]Ÿž=~è½Ë§nÜ®ˆeÜCD<È4ԆȮ¿8¬ÞÔò?÷–Ì ¿{ö@ߦÇR·p_g£ ß ¼¶–®nl}îx·J6ƒÒ $€À]]fñ§÷‹¯}x¾ÿÜ솳QK0ð‰-pÌjkïVÞ ~ÁÀÕ6$C ^Å¥\Z¥5á’NGÚŽì]ÿôågçrE-*oÉØå—è Ùyps,ÌOñÅ·g :õIææ&ùìä¯àORõ¦ÉvÔ²ûw¸ýºBøwx6ÜJ]‡µA ‹c䯝90/RX¼ÌÅñ ´÷ †ä1[`Ooù'¢ÛL€úOEÛAµ€×é›8–áXšhÌ£)V‚‡8€@&d¢¶l6t]mJd¾ÊÁÓ{¡wG‡zk +À#Ûàh¨ ÂÎÍwˆ+E“°›õ-eC±w}µB$ 8@TÂi S³`†¡®©jMcñŒ}ÆÐ¶á›! Ø@¸Âjô3y(.C¢ k¡•ªÇpbÔùN|xiÌÏÃøù{a5Åe8y º»ŽNÇÇÊnèD„ž²VþóØ—’Cr_#û‘Ó'í7ujyóuä·)"ùÂsvwîëÌd-CDèhïâÉGë[?~¥øc¢ËëºpNCª ¢ ¸½m-pø øó†¹öꑌ^Š‹E¤`ˆ÷oɲ^5xb[½çðó«õn_߃£ñ«PWM–Á•\löí£MŸœË…’Žžä@Õ3ˆF û™Çý»^ÛŸj®u* {¥b¯ü<¿ôýHxÈ­ÉD4,K?ãZCÅ30CÊ´M¯n¸u_îF#RQŠ€ñÓfq{dDèIEND®B`‚twinkle-1.4.2/src/gui/images/fileopen.png0000644000175000001440000000146210503576707015254 00000000000000‰PNG  IHDRóÿaùIDAT8¥KkœeFÏû}ï\’I¦‰ISBšÒš&%H«´ƒ%\Q\©T—]îTè¢*(þAÁ… þA*AÚ"41i«MI2“L2¹Í%3ß彺(¸så³?‡Ã#¼÷üŸ‰Óï¬påb?íØc=ܾ[åÊ`ƒá¢!M!V¶§Ð™¹Ù™ÏÌmn5/{¨6cÌ/iä™÷ıž;ÝÿÅÜ«g.‹9n|þÛýÃèúÏ R tHçÜ7JûœÖO ´rmk݇¡¯ÏÎŒ~<{u¤Ø‘QÊquzôíïZþAÊ`Þ8€<;Ö}íÚ»ý4¡m`âlŽôáÆÜ{oŒ MŒ÷EÐjYp0óÒp÷üï;_ÚÅý· ,Ù ­Þž€Ž<¨:¾ÆÍ&‡ÎOô¢5AÖYvë†Ésý—†ŽÛ×ILÎ÷IcÁyع¿ÏT·áÅ7OýûC.Y.òÑ×e–Ö ' ŒNùt`L¼ö×Ò¶•ÎB@’ëàÇ{ûüQk¢S±«ëY~Ü`­2rþ$•$CïÅáâþê˦½µ ­wH¿.F ø =’0G=v4޵–§0ÒÅäx¥ı£¶Zså[+.ùE:ë©· ZjñÕ'§ˆRCf0ÃrYpø·g·ê)ïxö¶j›4WH·š2ª“œ»'¥Ü^ˆ?ÙE®/àîC8Xw¬o‡–eèxžcÀ¹"<3Ò8Ôœ ½iij¡EÇ`Û†´mÄfÙuíUìŸaäÚê3Ž1;–ô@2QQÛ‘^’D±£ÕöDí.”ÊóÙ·q¼Wr „©[)¯LžÂò…€0”x§QÊbF©¥Ú‰æÁ££ ÞÝ!Ÿ»U{þ…þ®B.ÀZÀY´qèD¡R…JST¢1©Â(Cšv×ÌwÞGÀ?†Ì¢[ìÃpIEND®B`‚twinkle-1.4.2/src/gui/images/buddy.png0000644000175000001440000000134110643552507014553 00000000000000‰PNG  IHDRóÿa¨IDAT8}’ÝKSqÆŸßù×¹M7]›šn6'bhŽÈPª #£º Ò@z£«¨‹®ºŠ ª‹0‚¼1 ‚¢"*owÑ‹`“Ä–šæÜ\¾íUwÎί+E§ö½{àù<|ù>_`犮¾‹7ûÆ&Ÿ£ÉþáhòêÃá1[}G×.Þã>yýÖ‹‘,›^6X8®±p\cS+Œõ.3KÃÙîB?ݦÄjÿ¹kwŸô”HSñ,æ:"«:þ,å ©Xâ«›ô?ôäÂm奚¦V±ØeeIˆe DÓæ’yŒGÒ0»¼n¹²¡u+³=@A¢HäuB qtÊa  A‘ð’\´•á·ŠÄܧ% §½„3‰‘‚1†ôšÅD±¸°¨§¢á‰=7ÀßÐà×·}¯^§‚ªRUeÑ·2¯O<æ?©(Jp€ wû63 M3‡Ç~hˆÜu¯¾ï;¯úDó~KÜòª–S»é”¥c€UÀyœ}´.A®¢ªjhí.ù̦ª|S3‡“QŽø‚"%Í÷ø½3?ñ1üBPK¹*`çÎí>ŸïyI’‚ª* ÁÖ­ƒ„n⹧£O¶%ç©Î­%ÃýTð"àq—veN2*ÿ’û¼î«vìØ‘q]Wõ<Y–q]—†AýgÑÖ¾p{fôßÌÞI?ߦ…w8#Ó.Šä«²ÙìÿŠxžG8f` ÍTìgRã:ýGê÷ù=ïK£8¼(Ër]aaÑJí„öG"¢@j^o?³¹Q)±ýR 8ßÔÓ™T@×sy>SÉ{ãHkžmÛ(ŠBee%@€¡¡!’É$®ëÒ¸¡„ºª]ŒE$Z“sü*jÒìÊ j4½aû;ÖšórñÍwø¶7µÚš<ð¢@†ÝŸ¡¸¸žS§N133CGG 8p!çÆ=ŠB?æ¶uÏQÿ–Ê1Kâ&¹tù_²øètæe|2×Û?=. -k×x~ÅP Y±x«g–ÒÒ D"ÆÇÇ™˜˜À²,ÚÚÚ˜œœDÓ4d¹’yÇ™Š%ùø\†­þ›žŠŸ‹œ×ߎõg~«b.’ûüŸï¦_þÏBUõWâ«‹Š$YVe 22§©©‰ááaÂá0ÓÓÓ”••á8¶m£i:9/ý#½TÎÉ©§IýúLÊ÷ z´ÝJ)—ô468â½~ìXv§e6ÜX«9élýý§§¹¹™ÑÑQ’É$³³³ÔÕÕáº.¶m“Jì?øæÂ§/ÉŸŸÍìæ‹ô¤²€§\68¹óÓâƒC‡ysìlb]G»WzúÓij*ã8tvv )//§¶¶ŸÏ‡mÛ\˜ §÷ð+[ÂÑÌX2=àKÇt.š~å5Ñ5~v1ùx÷‡”–ÈÌÍÍÓÓÓC}}=---lÛà““ïžõ„R—8ª`Éù¾4êV§o',ÀáÑÇ{9Þgr°¯†¿íeE¨”Õ7®Á²b±^æ§÷ØKÊ3—ÛõoU[ó „ˆcXMßriÚ6‹—›Á“>C’úe¤¥7h«žýƒ’ŸÍæf/¯s¥Ÿ,WU²]3Í‹f)^rŠ÷Ž-îýëù ±Ùž7$$‡·94Þ¢´^·5Û¦ÒòÉá ˆ/”‰øÂWÅÔX‰xv—ùYu…º­0O/ïh3_û /?‹V‰ÅÅõ"«?Ø9jÆõ­Ò»¿aþ&6‹‹åâ‹ÁñÃvãuÛ”V]’b®«W|ùgqa6$"‘jq`_A²,¤W\³¸¢(Ú3ÝÖÑD4$ÞxÉY¸½Ñøé•ru]­yð~íß§?\áMމm›Ì®ktM=ÿ¤=ÿÄ#¾Áš å×]!]]d}½Þµ÷On¤«ÝúÇ5–©™5r§¡ùËY©+‹Ì55Æ—ßÿ2ÞÊ›\•·IEND®B`‚twinkle-1.4.2/src/gui/images/stat_ringing.png0000644000175000001440000000110510503576707016135 00000000000000‰PNG  IHDRóÿa IDAT8’]HSqÆgnîÃ}8ªÍ +‡¡å‘V +¡»)Ýt'H]uWÝtÓ•wAÐ]·Auã »´(èK(]¹aàÜÖZçè,ÏÙùÿ»8›º­`/¼ðçÏû><Ïû/ÔŽ«À·ß?Îjk‡éÀ!(ƒˆ@ Â‘Ú ÃÖ9U4Ó`"fGš,Fc#fQL¤eš©ŽXŠ0eoì©iÍS\úUÃ#q”–<è×~pn‡ƒØ®ôõñ =ž3ϸ¸f¾Õ Ìt@ˆ#âÃqx~‰ÁAÀ ¸´¡þøšu@ûßÀö-@i ØŽ­Ð?ý /t_ÿ/bZO{ï&ŽŸ¿oa‘ÐüÒÝD% BpTG(óâxS-,zºÓ aÕJPK‚[¶Aóz1lµ`¸åøü<ÐÂé÷{1ÐÓwXkô”–ï Ø ?Ñ}ìDtß¿¡ÜüœpžÍF8Žç2‚€'ˆ Çafà”ŒŒÜ¸h‘{^ÄMê£Ð:®"Ú㿳ýׯ÷žËp¬»¯»ž4ZðZ—~øâÅøm£«œö‚ R!CýA¸š6BË‹¬Îý¼Q'K Òã€(!ÐÖŽÁÖÖÞSûJ·ÝÖâr¹´§œè»ÇZOžBãÍžHYe9d2HóñRô„Ëáu.€äë½ÜŒøpúHQ¿AO†Îž×¼wî:iO_ÿP<ðÜ»ÈdTf45&+yIR®œ3bÃν |š€¨õ ÎRêâó`Ppôhèô07}­Çf½`ÀårEÕùh€Â¼hQº]S8ªbfõ öXÞÀÉSUÐ2ŠŠÜ((„hÔAH œÿ^ƦMîÖgi4À¬r¾.ÍJ‘H„À`€57 ¯çtCO0è$BTNˆ%4‡çi~<žp?­3š“¹Ü)X,È2 0}¸g›oj~ìó"Ðu€Q1ëEU3hݸ_.ƒLç_9•Ì¡É,šÊúof²m_Èîül~¡5EÌZþª|°õ¯´x0Ë4­‚…ƒùló'êI’Äq–-’·ïÙ™¦e1Ï5 {©tØ ç)rY1¿zß.U ؙߟϚY†'ÛÅì1Å)¥ÂÖÏ•3‘€ýú³š[%­-Wù‚Õï v¶¥êw»llályÕ˜Qàì; Cõ× ²é¼¤¤TòüCu…¸ê€+É¿j©rdL€" rA6÷®$JiùqdØä’‚liÉÓãÿ®MšÓƒâ]IEND®B`‚twinkle-1.4.2/src/gui/images/message32.png0000644000175000001440000000167710644226646015254 00000000000000‰PNG  IHDR szzô†IDATX…í—Mh\UÇ÷½ÓÁ™˜Æ$m’i¢­22S±¶˜~ø )4…X¡EpÑ…Ë*è²ZtY¤ÛŠP¬`W ‰ ­JPJ»˜M µ-jŠc“™dfÞ½÷¸˜Î˜7“I±M¸ïþÏÿœ{îá<%"´Rœ–Z@ð<Ó+"oˆÈcZ ÆPR‹1‚µwæZƒˆÅÐZ­Ëß‚1RÚ+ÎEliDß—´R|œÏKU¸._ž8ñüx$ò¾oÎK \¯—ÃAë®ëàº.±Øg¯+õa¿È±ïÈ‘Ï;€ñH¤hôÑ» ãzäÖ­Û$“=33?:Ù¬ïø¾anî{jüæÍ¿Édr,,äq * {z6ây©Ôõ{b|~~lv…¡¡M5ë"°eK/ííW®üú¿Ÿý“Lf™mÛVåÆªg¸uk?¡âÒ¥9D P€|~ýZ(ºvíKKKÄãCäj"PÖXlHÄazzÏm _h^} ž33¿“É,22òD ~Ôexøqººà«¯Slhk‹^­¥Æ@h\¸ð ËËÿ06öJÕ¿ž kWk"£§[qöìU BcÏ…HÎ3K.—f×®aDÔ*ܺWDbt4N_ŸâôéŸéìì¹tu¹s)´ŸfÏžd ñºŒ­¯ÏìapÐåäÉËtu ®[ë9@o7|òéU¬¤yáÅQ§.^u4¼‚jßäɘÃ{ï^¤·[hk+f»RпY8uê'\7ÍÄÄÀiˆÓX­UìÛ7F<îñæ[ßÑ·IØØ CQáý. ¥™œ|p×Ä $ õÚjŒâ¥—w’Hx=zžHXóö; ‡ÓL½²p›Â©¾¯ÒæÚ¢Ø¿7¹•ïÙñôG:´™Ã‡'¯ÉóµR!àkðüf9˜|ŽGHnOmøMŸ­|·ypHl«Ô†õH ‚¿^w/ÕÕ¸&ê>uˆ5°ÖpÉ. ö>ý"#€ÒJD˜š:óCtp`oGGk¥ª, VŠs)Ïm¹lWEJûå±”Æ ÿÁ[\Ì1ým*mÌR¿Èñœ ”~õ·ù¯im£ÆHå­jmÑÚVÊ®ÖE°b¢òM¹;¶öN'\;kÁ{Û÷ ‘ã¹JZ)-ÿ1y@ åþÔgÛ}Râ.IEND®B`‚twinkle-1.4.2/src/gui/images/mime_application.png0000644000175000001440000000170611001732742016751 00000000000000‰PNG  IHDR szzô pHYs  šœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF ©‰ [Ü£cÅ ß㳈…˜à'%ÀR;1–ƒ@¡8”XXae$ ‰–Êa%±–ƒ@¡8àË—/ ÌÌÌ ,,,à,ƒœm°¥n¥È!CŠÅ0@(2øçÏŸpÃÐ Å äX Ä‚Í |Rb€<‡ ˆ…š†Ã‹W`Ôá2 Åê’Öˆ]’PJ',]º”˜D v!@Q5@úA |}}Á‰”¦@ä1¯AìÆÆÆ]¯^½ºR@TwÌ QQQ¬Yº¾¾~ÏŒ3’ÌW >@ÑÌ?~ü€‡˜®­­ÝÓÖÖ–d>é &P¡öë×/pЃèêêj ËA €h €5ÈòÖÖÖ=ÝÝÝ–ƒ@QݰÒDûö¡§§gO__VËA €PJµ”dCXI ¯_¿f¨««[°víÚ ÷).=„â€ïß¿SìX(NܵkW(=âÓ@,È=Vj åµ„,€’’ýÓÔIEND®B`‚twinkle-1.4.2/src/gui/images/yast_PhoneTTOffhook.png0000644000175000001440000000540510503576707017351 00000000000000‰PNG  IHDR Çš ÌIDATxœ–[lWzÇÿÃÎ ï¤x%’EQK²dÉ‘-kcÙ–Wq’];ÛnS£H‚¢Û>mÚ¢èE‹¢èÃØ¢Ú¢»ØÍãzƒ h³‹Ín³I´±­8²eËÑÅ–%™u¿‘"‡CrfȹOŠé¢@úÎÛÎ9œïû~Äåë,n‡’¸4ÿM8–ö@÷<Œú1~¿OÂè¥(~p6ŽŠFar«ÜmxƒoÀøÎ1û»¹D€p&¯Ðm‘ØF‡ÃÑHD €·^¯“²,'E¡t]—ä”à‘=†ã·'¶êþáOA|‡<ƒ¿I¯ÃABÉŸÇÁÁòùjs~£¹Éþ]]7CWÒúûûù|ž<<<„išˆD"¸zíöVWî“ÅÊS¦{Ó®?6rLEøàórh󗱕W T%Èp@W<`YE—åÂåÉÉ©¡ùùy¬ol`gO†iãŒs…zÚöj/D¢ß–¤Zƒ¦k;‚ Ükjjº‹Åì 0 ÛÛÛ YçÚÛsk¥|¦ÞßçÔ׉6G°B°{Ž1(Ð#C >ÛÂ`c*•XÙ"æ~¡Ë¿’ëMÃÃÏUÓNfÕ·[YÒÆ¯< gß~JµÆpv45ÎË»ý¦a…ÿ_–n…B¡—ZZZ aY†A¥TBèìÙÔûwsm¼{a¬§ÿÜ÷W——U{X–A€ÂF ³3‡Tª¨BôG˜ú«ÿ!?{Ù»'Ý º 3ﯘaç&âŽ3 c¿yÕ¨ÿ%A Ÿ/×wÃî¿>3ØŠþÁ¡×hšvP(¯×‹û÷ïãW““Áxew»ý¹Á7LÒ–Ìçò°SvP;E‚¤($ Ф@‘vÒpDˆṲ̈ؕÈÞù¥!Y’ÏnOc-A –½ª’¹=LÅOŽÊB –Çþ‹õ&=Ó¨ºZ¿÷ý˜;Û›( $ $iƒÓí僾ÀþÃ1ví¥—ú-.bhhèÙÏþ"–e¦itt¤{þ3_¾Þ\òüý«C¢1c0ûñ4Hk‡Ö%P®Ä¨¢(͵Z­’Û¥&ýEEcŒÊñÌÃ[3®HãÉt{çV*™Ú”M&{9.>ýÐ)WYÇw;;:œ°,¨ª ’$át:a·Û!*• DQ„aH$Z¨SgzÞX§”ÿÉmk-"ÉêÁ½x ÑÂC©öÔŸ†ÑíóûWãåýî ÔJ[3kJSüôÔ©øÅŸXÞ·GÉýŸÞó•§æ~¶þôÞãù ׿öê·A°W«U°,‹t: Ã00;;‹‰‰ $‰b±ˆ\.‡ÃÃC45„=Jæqn¢…^iËãpö(Å¢p¶T*•J$(äŽsï¯>É»ÞãqÞ¼‚²T92ÄÿX=âgro½÷X¦~ZĨü¼¯ÓÞþ»áp˜E½½½ESSS€sçÎã8|ðÁ@:† ðx=ö­ƒüoüÓG´z>݃­¡ù‡khànƒìííý«Íí-Ÿû°6–ó¼ó¸¾‡Ce¬Q‡­ì²TÄ‹TæÄ-´¯u|eàÚ;ÒŒ¦ihll„®ë˜˜˜Àøø8:;;¡ª*X–E.—Ã0eÇ!m /=YYÓ kž¯‰1n¸Ø‚°üì12ñ#å ¢¬—ܨU«p×Tˆ.~IìA²ÃUôØ~§÷ÔIO¡PEQ¸yó&4MC__TU…Ífƒ®ëX\\|V=Ç! ÑŒƒ}=iE‚¯Y)¨Ϊ›Ëå*ú|>´µ§BWã§‚y¹‚›R.Ÿ²‡[6ñ²WåF çÛ’m8<<„ËåÂ+¯¼¯×‹r¹ Žã°¶¶†äóy¸\.ìïïãsOe]ƒÛrqì¶´ —ÏÕ瀭^¯¯är9èºK亃v7^pu Âs ÊxÚÂÏèh6kxôÜhcµZE½^‡ 8::Âìì,Ö××±°°€ããclmmauu@~¿P«ÕP©TÐØØè2hêâž­Ž\)/‚dY–M&“ªª†\.·c;ZÉ”ø]BÄ&[ofÜŽôùËϹ¼îo^¹r%}ppAÀó<âñ8ÆÇÇqóæMÌÍÍÁ²,LMMahh²,ò,,..>+ÍÞÞ^bþÉ£BY(ÿ¼b)Ú’^%ŠâÇ,ËNÕëõkÁ††ëŽ‘çNp¥Ò¢¿^7ìv{:ÕÞž*UxG(r3 žç¡ª*jµnݺY–áñx‹Å Iº»»‘L&ñøñcìzñâµ…ÔüÒhF3sþÿ;ÿù/ç¸ÇÀår±¤œc;*O Ó‚N%:nt(\À8$ˆcò1&¿c;o.­4'®eÞ¡ ¯¢QYd0(@‘<'Ã5G‚sŒ)ßå€5tïo°—Ñò3u¦4ätk¢Ÿ(ÿâ?®[‹´}oæQ*D#³M”S‹ 0p—ÿÂS›÷Bfy€—èBe*`¹² iç8©¿ÆG©O eIÀâ@ºÄ¤ªPÆ×øÛø6U˜BÒ›6Â@¼4Àñ¼qpøTÿ7åÏBd2Q`2ïØl)W.#+ø‡ØÈ~ÜhLÊ!~Ó°.Nà8ŽãÀ³lçψ4Ûü‡Áû PhùEøeOr“_á°O냕z1À3 òk‘bõŠ'@ÞÔ «ÏV2“®9X½p‰Â‡ õœö½Ìè̇¦¹Ï ƃd‡±½€.>D¥[| ø008%|ÊÜ<‚‡z<äÂÍΘå$)Þf3#Kt3Â^¼@Í€°8³£@˜»í4qón>‡³l<<„M'½$™å=FÔCü¨Dþ§ø%åöãP”Ÿ—¡ÿ>`¬ð:ÛÑù+n*qYa•¦˜â*CbˆLv‹\2ÚÀÃöè®õ¸?e¸ˆã’Îp`ËW ß,¦¨ö@¸òî:àbÞõä:O¡âbFñ¶÷üÍÕ ±0`‘«I/•Ðù)OSÇ.4$&¥ .”ïäd´ï®]w²`¡<Ï~Ãó"M›ÿ0”? 4rEø^eû9Ë~&OAÝšE”èÄäçò8Ü÷))/|¯òuöÓA–]Þ7 ùŸ—ÅJ²‡Y!èª: ãArí§@yæÌ™ƒBæ/I’BÐÖÖö\I€?ó?akÒíàÛœŸ×·¸å ýîxÝ9©‹===Éd²Ã0ŒGMÓ¬±,KVUUUÑ4 EQP¥¡iZF×õÛí~7ŠÙµkÇ,ø±ëÇVü&ß#¶%±‡ßÖ~ÒѱïþÕ«W­BL&I¥RX–…eY…1š¦áv»ÑuŠŠ ªªª¨¨¨Àçó!Ë2Š¢Fêû;w>ò>û9È þ~ˆ~H¾‘•lÇÇÿàúõëmŠ¢033C2™,éYUUÑu½0Ÿöù|x<TU%“qη·?þô—Ñ%=ÐÙÙ98::ZŸN§1M³¤aY–—5>ÿ¬ë:ªª"„À¶³ííÝcózÄB¥]]]]ÃÃÃõ¦i.k\Qˆ…÷¥Þ¹Ýn<š&¯ìîî8«´ÂD*¾qãÆ7…¤Ó¥ö9ijjbëÖ­ƒA*++Ñ4H$B("Ç Á¹D×uÇ¡¡¡î‹ýðOÀ)˜œœtWVV–4ì÷ûiii! ¢( ·oßfhhÓ4©¨¨`íÚµwÛ¶½È óË ë² ÒZ@ÒE¶m“Í.ÞðH’ĺuëèë룼¼¯×‹eY$ R©T៺º:E!™LÒØØXd\Ó4dYfffr%_^‰Dœšš—¢D’$…BK. ÀÍ›7ñù|ض͚5kðûýã’$‘Éd˜š YµçÇD£Ñ!Ã0êý~?áp¸ð>NF/é¡|"™L2<à6Œ+X§M®½˜×TZÔ„EMLf# hS{Œ»ÇqÃ+ ®çˆÉlT›·¨©” tq9áäìto>ã9Œ^™“jך>åÛL ÏxŽ8dJÃI³ýº2tjÇ€ßÒ¤ac £g„À÷gá‹<#U‘åõXÞß¶Ö©*¡ò ?n¶.,jj"M8¶Ù®hš¬Þœñi²V*E'ð#ÂVų7Ï-HŽ8dˆC†Ý‡l–ñlµFàGD•–&) [ ?"ÒT9žÚ%¨Ú½nó€ÌuòÛöí½£fTµí;ú×$ ªäO :]üÛžÁ’ |©[IEND®B`‚twinkle-1.4.2/src/gui/images/presence.png0000644000175000001440000000137410644227201015245 00000000000000‰PNG  IHDR szzôÃIDATX…Å×MhTWÆñß\¯÷ ã"È](éb!-ƒˆAB#¨‹¸•B—¶.»npÒu—-î‹[³Ð…J( bhA´’l‚‚$L èB™ú1ÓÅ|tMæ&™˜çå..çÜ÷ùsι‡÷ÍT«Ui”• Å8 È×(ÕŸyLcfÍÚ¿iòfÚv8køÝ]ºôµ,·DYÞâL¾ñ¦´#€^½YLà§ãŽçÎ9gذœÜ–ÀeeO=uÇ/¼Xů˜Z±²– __$º9h°xÚiÇÛÒt3½ôÒCÍ™›­¨\Z²´Üà„C‘èö˜±£ÖU¥;/µ`Á=÷+*ž{þϦ…¾Hô÷)§úóò© ÓÌ[¶ì‘GK•¯çÍ7W¢ 0l8‹?‡ 8²­äiõÊ+Ï<›ÅÙ'ž¬AÜ ÂD—®bV¶q’;‘•Õ£§XVžP;àµ8ãL =zr‡Ú•I;ز²×^¯bà¥É5ä"‘wÞuÔp£22INín¹š9_=°‚D[~¼[°>úàµËª7Â(ºw“t;:PºçhœHÆ[ êt{’‘‹[Wr<B¡uREeÛç ­ùg¶¸!¿qr¼÷¾c¿ß&æÉ'HTêÑ.y»ñ¨ŸQ>– öZqJøjŸüKq"Ù_€ ÌcdŸæã Lã‡}˜ŽɌڵ˜ê6ì Þb&S­V]wý7üø…~¿âÊÕ‚0‰ïiSqvN«˜¤¥"ºáÆ~þB¿\vy‚õѾEqÍg1ÕxYW”Þr«áè™/⛋.~Z”6t×Ý!ÜÞˆE\3¶yYÞÐ}÷ûpSç¶c—FŒ´oLþÿb¶ÙšÙùßÑlÍŠŠé[³V=öx]sšÒ¸ÙœžtrgÍéFÍ™ÛV{>h0U{þºûßs«íIEND®B`‚twinkle-1.4.2/src/gui/images/editdelete.png0000644000175000001440000000126710503576707015566 00000000000000‰PNG  IHDRóÿa~IDAT8}“KHTQÆçÜ{îÕó‘ö°¤èm… -$($¤ Eµ²Eë‚" Ê ¢ jcˆ ‘¢MD›@"…¤¢¬›^š¯ò=š:ÎLŒ÷Þ9§E3©0õ_Åá;ß÷ûþG´µ/ÌÏsµ1dFH&gð=Ÿñ‰¨ |=‹Åw[¶ýQJÉ·Î.œ;€í:Nxãú²æŒ1†¤§IÐÝÛO^87ÔÝ7üt`ht¿ëºÏæÞ•d!R‚iI–––°c[EɆu+[”m×êY³ØÙ DZéíë'2:J(œCà§œéèT“Öº¸þOB ¤€E% ñ´`t$JWw?NŽC<>Uÿ_Bø•åxIŸñØ ÃÃ(åÐþ¦- ‚/íÐñ ¥ˆ÷ô ¯Ö¡Z BaGaYVðºS˜=$¶×b¾wPtã,nk3¹+^áo®B.^ŽÙ –®•àɬŽ;„ß¶!»ºP/žã/[Í䱋X%KPB§CfÒ礴Õµˆ_3¨û·p?=‚È$þ¦J&Î7â¯*NJDZl1Ç‚¤@( [æ #04±$ þDhp–KdŠNCÔò¾‡s¯÷Ê‹’Ú².F½ûJñž]¸An(ýú¬ƒ¿-Ø/›Q—adïÀAbw[H\»É/ÀŠD(AâðQô‚,?˜ÁÎìu¸(.ÝÄ H¥ÀHí¬Æûðá ÛVó!F§§õW)ÿ4jÐ$ÆhŒ“þÆ0!$ñéØLFà7^†n~Í›IEND®B`‚twinkle-1.4.2/src/gui/images/edit16.png0000644000175000001440000000117410640017202014525 00000000000000‰PNG  IHDRóÿaCIDAT8…’ÏOAÇ?³?ºt»€-)bÐHDLlÔ‹‘˜ ‰'5¼r2ñæÁÿO^ü ñ¢w£‚&zÇ€cPA% ”ÒnwÛÝý!¥‰¼äM&“7Ÿ÷ï±òe]»®ÃáhD1Q#¡RüÃ…G„ÑÕêö·òüÚ›'3+ñÖáZËuÆÇF:ZkêQB)ª{/¾²†(öçÜÃí÷Æ0×àH!°LlpÂ}…(ðý-Á×Á¸1\ø »ê£F”pRŸ`ÇD•lVûn „3³³OŸ=?w,€z £öÃo€tØÝõ wÐ*™:(ïMð—±âˆz†¤:ÀÁè4ÙÂ$ýý.aXûÿ4 6æ0]bZ0B8v‹L.mÛ=½zLT;Ÿ13kPõ nSIÇ-ÜÄtRX–٪ʊÖݤЀŽCTé–††IT388u›ÜÐI¤” 5•J% ä[êk€T ©4ºü3U‚ÀÅ’`èþ]™!AàW}hKq-­@I–Sæþ~•jþ:V#&Š’8AIÙ”zÈ®.db"ä5=Á¯Í%Ô¥IH´Ò!B`†êíìì퇬/¯’ }ñvþ4ºÕÑ0 œ>‡Áì` (þ­*ŽåßEìËÓ¸g&0 Û¶ñ¼ ¹\×uI§Ó²}¹3F!š9|vœìƒÇ×C+H¤Â²,”Ò(¥BôþƒÍ­mßýsFë¦" º¹ [{߯õþjTíqÒmIEND®B`‚twinkle-1.4.2/src/gui/images/mwi_none.png0000644000175000001440000000410010541074406015245 00000000000000‰PNG  IHDR szzôIDATX…Í—klÕÇwž;Þ‡w×ÞuBb'Æ †@$…¦PU©*@EˆHí‡J(©¢E*B-ôS?Q‰•ú¥ñP´ª¨*µ¥Mò¦Mb'Ž?Ö›]{gw=;sïí‡]¯í””J¥¢W:º;3gçÿŸsþçÜ{…ÖšOsŸ*úÿëùòÍ›Ÿ}ùæ›/ËêÕWO¥''wßx±ÐZs÷ÝÏ£µFkMi¤¤e )5J-]Gh­¢H£5DQóÙÆÝû¶nÍ燆²ù Ò¹žžŽ”ãXŒŒõcíW|pÁ C,EÀ4á©§n#™tCÉGëR¯¸ッÿrÇŽÕù«¯îÎ dòëÖ¥rɤ뺮M,f‹ÙضIµºÀUWe…iæWdôk¯}Y þ!ž6´~DY;wî ™´éííºd8ïºëÅ—·lÉç³¹¾¾ÎüÞ½_ɹnÈu›fY+%!¾_Çql††º9xp†xÜäºër¼ûîŒ(«Z ±,“0”œ:5ņ «Ø½ûµ}W^™Ë÷÷§ó½½ÉÜ3ÏÜ–ZŠÅ,\×FqIÂFD©TE)M,æ°eK‡ðý …вÃOîÙst[__¶gbÂϯZ•È=þø-®ëZ4ÍÆq>^¯‹)’RQ©,P­¤ÓضÍ5×äX·®gŬTÊýîÎ[¾94ÔÓéyN;¤¦ùñªõG™¦^oP,ú8ŽI<îaF›ÀÅú2´&611—r]DZpë#Á+"Š Œ ¡Ñ€ ACŠ™™ a(Éd˜¦‰ÖH¸ d¸á†çWP°”ÒÇΜ)‹ ˆ‚ˆjÕ$‘ðð<!J-±V T‹Äâýå³i@¹ìS©ÔÉå’8޽":›7wsâDiÛ"#ŠÔðÄD…d2Žç¹AÈäd™ÙÙ µZƒ0Ò„!,M ZÖh´~·æHB½Þ`zzÓ4H$<„0QJ HCWå–§ ©¿ ˆÆÃP=s¦L<î‘É$ñ<›BažsçJg}‚ˆ(‚F¨—@[Öh4S…ÓÓeææjd2qÇAª&±ÅÆ64”[‘UXZ þ66v­!sÉf“äóH©˜ž.sv|–Zµ†RšHꥯ4A ‘RQ¯Õ8~|’L6F&Û‰ÒJ‰vº”‚Õ«StuwH¸z­-"¥–e‘JÅY³&K:íQ­Ö8thœR± :­š… ÙŽ• 9zô<©”Áå—¯n/~y-ÙÐP÷bÌ6)ÕðØØ…voWJÇqéY•¥}ÝÝ.û÷òá‡çðýyL3B) HÆO¨×ëô¯_e9H)V€†á’mÚØÖA¬-„FC.•êÓÓ~ïšÞ4h9Äãq®è%‘ô™ajªB&›¢¿?G­púÌ,ù|‚L¦“(ÿÒ”ݪ–ÁªIàZàOËÛÛð©…Þä骿Ãqˆß~F"Éü+/¡ ºîù*×_ßÏèh±±YŽ9OªÓE+ÅÚµ9„° Ë€õRùj}ý9lÛäÊ¡ž?¢M@DÑû¥7~s÷ì‘7ˆwzÈzÀÔ›¿ÛE¿w¡%µ·þLúû?dðÚ­d³)FF&xç î¼s3ÉTŠ0ZÙ.Õ3r?>¹T‹›NýõüÚÚq2·lÁN& аO3·w/6 ùþ~Š?x‚ì÷íÎqö—‘êLÓh”Kàˉ´L¶æË×u1<<®ÚvýêaÇr¬mÝ›úì§V,‚Ö˜]]ØÆRµZ€³°VgÅR"°¬Dü‰Îõk³=o¨éÊd!S<0Œ•ìÇ£Vð %ü©)Ôh‘ŒHÓ¤kÇš·^àäýÛ©VB/ŠMk~þ“¿,+=½LŒšùùf¦+€XÃÙ.úoß&òÕpÓÆ óÔß~…êìtŸ<óö ­“ÀÑg Ûú‚“èx|ðŽ7¥Öäì厥ӓáÉ7ßýCèמÐQtð}ú9V‹‹çωõ½ñu ó"ß²@ÿôkztæ“^ÿ[ •{ÇŽÌIEND®B`‚twinkle-1.4.2/src/gui/images/sys_encrypted_verified_dis.png0000644000175000001440000000151010507532266021050 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÖ |º;ÙIDAT8Ëu”]hSgÇç+'IgbÖ¨eÖ&6èjÔXc×­EÅ":ª7‚ˆìãbÈ6¶*ŒéEoÞ)N‡»»™"EÄ^øQqó¢v*•*j©íèl]¥vÕ&6'9ç䜼»˜ºhâûÞ<¼ü/ïû<ÿç‘(»tø‹M§š>ªü:°füóãÔñöi¥<ýj×Aÿœµ»WÍ«áªgëë+Üú=÷@õ}z´iÁ»ñ%úHþzê~6«ÄtmùèpãÝ!—"ïµÔÛÄôA««£/Ù_wþX¯1?8÷c»Ê‰Ï*.:·S“?;ð$whèoOÔTËjÕê9&çÀÑÉŒeacj)°¤µq^“R QÝQÑ ,-bZ*¾¼°ãà *˜FðfrKƒ>ÃÌüaîPÕæãÝzœÙ /_,ÈácœîCjòðªùþ@Øc´/¤¼U¥5Ѓ ôò> æ’Œ2°Cu¦Í«ý>ÀE #£Ÿð‡:'Ìr‘Á<§<¾Òßg­Ïò £"aÓI† yRŒsÂ,â6†ºe c6|s¶ßµ¦EÆÂÄ&ÈS ‚D1Èãà žÿêÑ¥íímY$lL,\À!@†µXäÉ“Ç)2Ÿ;uóF×ÃäŠ~©,qt B%—4{_IkEâĵzßNBC ñrƒ5“ÞóJ¥k—…} BÜÆ F^$~ùk_mQ¡Š­oã QC522‚ÄBu±3ôBSl>9²YGB`r5Û9™zž•$ËZ‹Dÿ‡Þ–æŒ Í¯Ãßmù¾qïéA·€„Âšíº§Lløa@Œˆ±õŒ·ú¿â;gŰè0«¢%rEkïýSü”iØ]|ê©ûä·Ë…¢¹­Ъö¦¾ˆ´_ó¯â_Ùv$½íB àõF>óT–Ÿ!së£[^Äÿ'ýZ„ü¡IEND®B`‚twinkle-1.4.2/src/gui/images/exit.png0000644000175000001440000000141110503576707014416 00000000000000‰PNG  IHDRóÿaÐIDAT8•“1l“W…¿ûÞóoû·­Æ[‚H. v†„ • ‘F$¦ˆ!2²0wè #+ˆHÌVš !nië„„ÆÔqˆëØ¿ý¿÷ÒX]¹Óî9:÷žså'cnþP*=Ì¥Ry¾¡:ý~{msó®ü<5µ7],æÿ-—Á˜Ñ€ÁhÖ£ÔQ¯J)”s„õ:µz½m2Éd¾S.sêêÕ8=1‹„…Î{ºÍ&ƒOŸÈv:(”‡Æi4òÆ{‹"ú»»¨ àÄåËŒÏÎ2è÷i6(ÆÏž%˜ekm Y]%£ÚZ¼÷ï=ÝFƒÌ™3LܸÁÉ™~}þœÎò2§³YR‰›€¹t‰ï¯\áÏ("XYAEÞ{”uŽÞÎ>Ž)\¸À/OŸ"/^p:ŽÉÎÍÑ›œÄ´ÛÕ*»¯^1uñ";aˆôûXçPÎ9ŒÖŒÍÏu»l?~Lòà×jQ¼vÉ…þþø¿·‡<{FÜë‘®TðÍ&Î9Œõž´ÖäÏŸgg}ï¶·v:H.‡(…âý}ÄZ¼µtëu å2(ÂzqΑADȃ‘/_F®Èþ>ÇGV„pΡbkIÃÁƧΣ$´Æh="8΀N&IW*|ÞØ`<•"¶öèˆ ­é¾~M2“áÄ;˜ÿþYYá¥%r‰F)R‹‹˜0¤U«‘6ëÆZ‹Ñš¸VcûåKæùÝÔ“'¸{÷HyO6—#¸}›paÕ*“ïÞ!É$ÖẔ£5½Ø*·n1¼~ƒ÷ïI‹žÆ„!ªU¢G(%“(‘#±µèã¬Grÿ>¿-/£çç›™Á--±ÿæ ¥õuJA€ ¶Ó ÚÝÁ 2F»½}‹^]E”bL$””BþÞjµèmùQäf! ZÓ;¬m><¼û/ü4”¤žÆIEND®B`‚twinkle-1.4.2/src/gui/images/transfer-disabled.png0000644000175000001440000000051510503576707017042 00000000000000‰PNG  IHDRüÇFÜbKGDÿ‡Ì¿ pHYs  d_‘tIMEÕ,ZK¥¼ÞIDATxœÑ=NÃ@†ág#:5ˆœ •¹®(8œ#âH¤… á‚:•%(iBå–&' Ii ÿml"å«vvÞof‡=â ­úseb`¿¨z0´È•³-›»›ìF˜7 Lêpˆ¬-”Ýͤ®¹Ü¼y´Ä‹´ê*A&“y²Á‰[¬‡ÓÕšºöƒD‚ézun6j>‚–΄hºKG*ån¨ï VVÊÑ~gc÷-‘8öa‚l8]T$~ÝD&_ž›µt»N+ð‰ Ü-¸[[™=ôƒº6^ÒÂÌLIEND®B`‚twinkle-1.4.2/src/gui/images/mime_video.png0000644000175000001440000000375411001733045015556 00000000000000‰PNG  IHDR szzô pHYs  šœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbIDATxÚbüÿÿ?C~~þÕß¿ÿñAÐÙŒŒŒ ÈY`“êgŠÿþüùå)S¦X`tŒR†At0èQ+V00 3Hˆ‹1ü¦vyu-`éÉÌÀô HÕ¯ß ê:Ú [¶íÛ¯ÁŽ…,@SÜÒÒÂP\\ .¾~ýÌ`nëÂà–ÈpîІWŸ0€Ìgb„8íJŠ »wí—®111à´€^ ‚@ Ë,X,‚9ž={Æ`íàÁ’[ÂàäéÂ`aëÌprßF†w¯^2°² ,€¦~ýþ‡ARJŠaÆŒ ‡'Lvvv  ¡*dù’%K~üøÁðôéS'7_†–Þi ¬,ÀÚò+ƒž±1ÐaWNîcà´ugbøùõ ë?†/™Àe¨øåPJKÈ €ðfÃææf†U«V1|ûö ˜¨žƒkÊÿ€åÿ?AÌà ÿ¬©Uµ´¸¸8Ü<Ïðë«7 Ão`• (%\p¹*¼@1!'6P!+©@–¯]»œ•?~ÌP×ÜÎp÷Ù)) †äÈ@†ÏŸ¾2p°Câü/0õË))-ùúá5Ãw ƒ£££ÁfJJPåkS €B P ÏA Tÿwtv3ÔW•1ðó²0L™5‡AVNž!/=‘áݧo ìœ àxÿÖM`”|fx l°€,ùtãÆàÂd9È\F„ƒåu…ˆÅP^VÂð 0Àdô1#C÷ä© ÒÀVSœÃððÙg†½;÷2\=w‚áåË— ¹¹y bbb kÖ¬[3= ‚@a¤¯ÃÃÃÁ­£•+W‚ÎéÓgLMM¾3BòùF&†ºÎ ÝMµ yñ~ _>}dàg¸{÷.CPPCoo/8Ja–cËÖ0@LØ$AQJ ‡œôö(zò`€ÂêXCd¨±AŽø Ìs?~ÿGÓ‘ÝxyxöîÛ.é@–ÃZÊ ÎÈǯ^½• /fÍš4sæL€Â[€4ƒÒ@[[Øå“&Mò3(³//0oGSww7ØrZ˜S= øðÔ ![ ’ ušœœœë  úø?0x00H€%âIIÉÿîîîÿ•””þ—––‚ÅÃÕãþ__ß Oÿ+!0™ laÿÖ¢Ïvª G @1a‹t ë7€ò7¨lË))) ð`GÏf qP‚BTŠÖÕÕ½˜6mš Pê²DR‹ä_`ëÇÇǤÈOt+÷_¼xJ/ Á~]@±`ó=¡tR+²qåsP#dù„ @–Û`³ˆ½$D/*É zÔLv>qúÔSeÈÎξ¢¨¨¨ ô¨wüŸËA½_`bd¶^Ó‹-zœ£G+@1B›\"@¾¨œ‰S¡Cĵø!¡t`nûúö©s6IEND®B`‚twinkle-1.4.2/src/gui/images/kontact_contacts32.png0000644000175000001440000000573710503576707017172 00000000000000‰PNG  IHDR szzôgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe< qIDATxÚbüÿÿ?Ã@€bŒŒŒ`޼0C½= Ã×\ ?8¾~û¥ÎÁÛ/&¯âÁ+ ñãëÇož<>v÷ÑË™S޼Ú3„ ¨_‚é?ƒƒƒ2DìîO†{?N|Ãm9ÈóÄã¸ið1¸j YoÀ Æ›ºútûĈ‰HH20ôÿÇ;Îϯ]:|Ð÷Õ·-³W{[ÔðóPý:qsY ïÌt†/_„®BFv@¸ƒ—ÿÿ7 ï€.gaøcW´@/´( ôÒÏ@üŽ‘…ƒOT’Á&؇UKC*‹»z¦Ðüï¢Aæ 2A,E¶‰° °åâïPit@ m Úl ,ÿ23~a`ü÷GJßÞu²^`"Ãï_@çƒLd†(ý4îÐ?_¿1©¨1ÔøEˆ3ÅÌø ŽK$“Qù,8B €À`gøÉÀÉô lˆ G¼¾[ÃO`øýú Ä@ßÿùô0hþÿb ªÿÿ~ûÎ §«Ëã(›6éëï· v¿¿3¤ÿùÉóçƒ÷— B¿ð?Øa\Ì¿ ¼? ’²Ò.Ü""À0{ô8Ð@%ÿ€©é0 ÿÓ¿? ÿþ1 ƒ´jñЇ%¼ZfÑ?"C Ø5ÔAýáϽ; _6m–ùlß´ÿþwñ›ˆ”àŽ&‚áï¯ÿŒâ†WÔ£k´€¦Œ=Ffˆ¯ÿþ€„ÄïÏ €Þüó÷ÃÇŸžö­fPÑ cà+*F:;PèПß@†10ü†âŽ SkZ6?yþ’Pr@mþÌB ÌMÿÿþùñ“á×'`п'<†Ÿo!4(*€–å–ÿføÍø—áÅæ“ †á |å5ÀH:øГ¿~1üa`:ù÷hŸ» Cö¤vß\ .l!@`ü1€I”NÞ>»öûë{`trÄ{°cþõè»ß~1üFÉëGx?r2%ë·@5@ÿ£œ…Á…„þûñÃSS†’ÔÈ &=tØÿ€d“à `Þ}õjùÛûW€ ò?0|cøõû+ÐSß~ÿþdÿÒ?¾~ÿÈðáêmq[` feøÿó;б úß ‡ü;˜PÀù TqgO‘ tØ·!µ“‡‘!OŽá$ÃÖ“‡ÖlüþþÃ`bûý d1 ÿñã3Ãç¯Þ¼|Èð÷ó.y†ÿßé¨ï búꈠ€E ?ƒšœ.ºœ Jø‰h(Ôêt¬¹ù¤ÿÛÂ`¢¬ËÀ!(, þBÌš?¾~bx÷âÃÿ_YY™â;¸$gb†˜T ¶Uÿ@¥äÿ¿ÁŽâäæàBw@ðƒ– RL3wÈñˉ¾–€^ßførz/?Ã_vf`&øÌðéõ+†O < ,æÂ ÿ>§˜(ås 4iÿ;âß?ˆå G€¢ˆáó{†go?†Ögàô÷Tü‡àÿ EÓÓ‡ {o>9 sŒáÚ|}¸ˆ Æà”®«s*T¼ú惭’-ƒ®€ã› ~6É Š‰5 êgÿ3G2øE”3È¿ÕepS,aøÏÍÃÀôô6Ãf`íô1ÿúø/È÷ ñ hñç ÀŒaÿŽ­<ÿ´™OŽ_#„Ào•æÏ L,ÿóW`ÙÍÆ -¬ÁÀÆÌÎð/:•áæ¡Ë ¢%E \Š ØdØYþ2씳a=´AÍž•á—€0¡)”@9ˆÙ>¾dø|ç)CÝ}µ þ9ÿ (V9Na5°ÕÄ žHs%uÞ‡Ÿï2Èð(1¼ùñœ‰ŒYþ²1°2±2Lid`füÏðá×KfÖŸ k}`¸úB“““!ÿênžÛ Œbâ ÿ˜YÁ éÛgÆWÏÞøÇ0å{ƒE‘uå‰K>~úðq2¨(ÿýí5Øv€0—ˆ ;׆ï?3üøÿèß ìLœÀêXK2±-ff`¦òÿÀ<ÅÆö—aÿá ßë3ø©ýa¸À&ÊðÆ®ˆáÖà _že`y ½ ¯¿³3|—1gxníÂÀò’Á’ë—SȤ҉? Zôçû{°ì~vnÅoÿß-`xÿë#Ä÷¬Lì@10fBfF†?1œ¾¨ÉP.Ìððþk†x/Q†»/^k:0üQw`XõË¿µÅ¸¸€…°XHsf`xð€ƒARâC”‹è´ú­‡O­½² €Àø÷ûÛç?ïXY™€Aüh9'³ƒ}ÏÂÈ Œ"f`*g:ì7ÃŽ}œ Vj ÷_|a’7䀕§(/0‘ò22èˈ1¼æ2=Q†OßAÍ5`–°ŠJü §®~dðu—æ^bàS}Ï!PC† ‰åÓñÒãìÏÅÍquR>¿›ÔFï‘ð"18l{œÝi~5z´ÚXåÒ˜ÎáspÓ×s æKÐöÉg>ÌîÀã‡Âʰý@9°Ì_Q<ù;@¨x#!„ae™qU€i»QVM 7-^íGCàÃÓ?‡î?z£É ,(¿ý?°fedûüLÀ4À l™Ý¸ýŸ—[†áÝÿ ìÜì ï€>dz ˜èÙ€!Á d3#•ø¨!t0`©Ÿƒáé»? Šj2\ìBF®@ew’ ¿±L8¼õc„˜Â?~.†o¿©Ÿ¬ g6æ¿ Ožˆ0SýûïÿDxXÞ‹~` ¶œˆY˜À 7xÙöÉ?ô¯¿Œ _þ]ÈÆÂÀ#¨lR@03Ýxq•!~í„/ -ƒóK*|càš ö=ĬÀ&Ûç¯Ü œìLÀ gbøÊê@ƒÙY –³B}τԄ;l9$~Íéefá© D[‘…qã‹w,Ö*ÖásUa“ågfâ&,`ó–ëÃÃ;oØå1|·ß!>ggÆîäøsÿ¦…wŸÿ0üúú ÜŽ X@Zl¿¾Ý`xð-ýíF¾· lÊÀ$ ”b.`s˜=ä$ùC_Õ~ù'Æðý4øY –³àpÀ_˜@XPË5†§>1|y}÷H@Að˜Lyù‘[kÀ6ÙÏóÀÎÉyH{¸ùÂî½é­ì¬f$( , ~@ãê&,QsÀoh«ô7ЗwžúûçÛ©m 5I3çî³ÂÂ9 áŸ½-<8qïçO¿3|Zþhð{ É Í{ ~÷ ÿ„ÈKc†Ï@›ÞˇC³/3Ü;Ð7È;2 €À­bXßà–\Äð÷;°Íúå» §G»œ­–¸ž ¯88[²ó$R6zû×÷? _ß|ax}ó ÃÃCG_¼¿»p&°ÝÕj†€ì ²ðØêýýý6ЖÀF¡’ ‡œ.+·3/7 ¨mÎȬp~ýýõõÇïoïßýþúÄ·O»«û€ò¹Y@ŒÝ=0dRÇÓašÎ…IEND®B`‚twinkle-1.4.2/src/gui/images/reject.png0000644000175000001440000000061010503576707014721 00000000000000‰PNG  IHDRVÎŽWOIDATxœ­”±mÃ0DŸ šÁ©4@º¯1’¬ î«ò Afp•ë²B1ôwpåÌÀŠ)dÉbbAàBäátŸ¼Ï*çÌ-°]ÛPÛfÂËE> Õ5~õÝ‘Ú6˜û5>!ü,„Ô¶9uûº^¯8¤DýöVˆm®‰„iU$LìëšÔu³ûB˜XøU±0açs¹6ïm–nG„œð 1Ü9 ‚pRw?»ÚœY4M€3þÑ\D„i}`®‚Ó4 ÓÍ¥(ÆÙl WaF¯³¡à,QåœQ¥¼{ßq÷ñ2 ûÉ\ÀlT:=<óùô‰g¯Ê@šcáØï:g®8->·ÓâñØñX×`"X¿~cVà—@ªm³¯¤y Ò¥eŠÒ)©Ž(OÕ5Rb™ÿ›µÈjÓNeN Ÿ­¿4m)Øg¾ÇÀ^ÿöŒü_Ü8´R„R(öIEND®B`‚twinkle-1.4.2/src/gui/images/sys_busy_estab_dis.png0000644000175000001440000000153510503576707017351 00000000000000‰PNG  IHDRJ~õsbKGDÿ‡Ì¿ pHYs  šœtIMEÕ $¬ÃuîIDAT8Ëu“YHTaÇ÷Þ™;3·qt2ËÒT,ÁÉÒ²Ú3é!‚"Šl± ( ¢‚|h¢žÚƒ (¢… *B¨ˆö"Jˬ©‡Âšš1s°4—qÉ™ñÎýzÉt:O‡sþÿs¾ïœó‡˜fÑR¶Êj¬Œ›ëv¹#!‹bSµ.óµãÐ=9Üds­](ùN_ËzUØþʼfoÛ®Õ˜þW5ë–î;Þ+ ØI˜2«´ñ°q`=f$PbæíÎyK4Éþü˜H ¾ülnÑÐ"×ËŠŒmLÉ«ü.«Ê:E\›¾ôÐSâvÖZž4‚ýþ°nÅ––MõNk”<–Óí}üàÀdÑ~zGÜÚíž”å1i´RK”Ô„=+2)¥Ù/k~4ŒZ¢xõë › Zð`Hy›Îôû,—圤3]C@Ê?61Es Q#³Óæ|ãÔPÈÄA5!âÉ'‰fž‘I —h­6E;§.˜¡Ù€(‚‡ ç¿XI÷Ô“H.t’K7ñiµòó©§*\8&NEÆÄC2RG‹¨ÇŒŠFo¤âþÞ|ß{BA¿–_ù<:-+QVxŸéxi¡‘4ìh˜×>z°}߇ó"Ü3¥v_Ù»€:y´ÝÀƒÌ |„h"‡x4"ÜëxR\{¾) tŒÞ±F½©¼ù=ÑH¿ÔˆbHÇÅ 4"ûç¶UÒ…ŽñÏñµyo—Ô…¶0œfî0ŽBhÀ»QGSß-dŽM²ÙÙHU\eÙXi¢N£‹îÞóþ‡706f3ŒŒÀ‘z!QoêÅôÝ´œ¾À‚„ Ä‹ß×ZÑÈä3v~Ð_×Z0Í)#rÑ»{ñÁ)îÕQ …™Ë-±ä:ïÈGáÏÅÒ2kjO…1›ý®^q!”œ1®˜KË¿ˆS“¶÷ªÙE•bZÉ‚9ÙݺíczA|?I)Ú„’ãÁew¬Öôb51¶Æ‡ŽÏXÜëÿ™þÂW ÊIEND®B`‚twinkle-1.4.2/src/gui/images/kontact_contacts-disabled.png0000644000175000001440000000101110503576707020547 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  šœtIMEÕ ;0²e}­šIDAT(Ïѽkq€ñç^r—^L›¶öÒŠEiˆ}Ž‚(U HA‡.bwWÑÀ¡ ˆ8 .\D)(h¡Š‹6‹ƒ´J2¨¤–hiHrIî~¹Üåë(:ù¬ŸñÑ„ÿèÚð½§[÷jm;U ‰öß°ou¥/M©Êz=Q µ¨ÿQNž_.ôP(–2—ïç.Í{/^½{B›¸»R’r _¥$/哈ˆt¤,… ²$ p~­f‡BUZ\$§ÍüÙg;qÅ„ôô·xŠ*§ñé#„ÖL˜1¯äW7/¸Ï9ä&Ǥèñú¨óÓÌ?˜s-¦¸E“Sl³Ë4‚OCDj]ãúú”­ðÑp(r‚<-ÊÄŒs53¹ðaÓ¬é <,lªøÌâ2ÎÐeéÌÌC¹cç""ʤIÒÁ£¢2lü,뻩½èK°ßË ØtðiÑ£‰âcWÃdˆ Fq£ËW&Lt &¢Ä£· c“$‘œwoçGm³/í°RÛÿ¬Þü}n€,“d°ÐbŽ~ñ©f±ÁÉûIEND®B`‚twinkle-1.4.2/src/gui/images/twinkle16-disabled.png0000644000175000001440000000070110503576707017037 00000000000000‰PNG  IHDRµú7êbKGDÿ‡Ì¿ pHYs  šœtIMEÖ6 ]ŸWRIDAT(Ï}Ï+ÃqÇ_û~¶e¿´6³qÓpœÊd”“ù8´íêà GíBJa9©-åàÇŠÅjÉ\‡6EÂ6s¡¾;𾽟çõô<ïª$êü³ü§É¥Øê¿û"–½©t ÊK’Üx=-cá?±°+(_"”Í]Ãè6y¦$§Êj´XHŠñø€C¯Á ™ ;iT8ÐòÂ;%ʬ_ˆ·kïD¿Ç]Û¢²°‡ ž X0£b; ‰ç‡äFÁèô™y’´bD"O™èÂæ<ø¼:¸>µlµG”(“ÅÆ].LíÈŽ¼8á6sy[¿ÏqÝ>º\\q‘ë]¼p¶v+Vn!š¯y\÷ù RáÆ4|Ù,%Û)ׄ¯Jºç­}çÏü±Aàò¶þ¤‚“ÑD|søé§Ðv  …‚¸u‹ÚØ8ÕÏ¿`>;U˜õûŸxøÌ©“ë½ÛM%r±­wëfßËуæíœá¬6(~v„¹/Nšæ½C§Nü©hm;–L>êñô‰§¥+ŸÇ©ÕÖ¥0q´x í·é€ÌεGö¨‹½}><çÝ·»ZEFÑ‚AŒT k¾€5_ÀYµñoÚ„ âÚòÀ.BŽ3´e&ߦ}¦a„íæ&œBÒÇ ïy#‘àŽtµ_®Ü~?‹ß~‡ùɧ´W–p•2;+Õ:Ð¥"…¢i ‹G¿&òøcx;Ú1ö&X:üŸOà]ZŸ¦áéÒÑ, -7ƒbø 07o¾±v½ñ ‚G¿ù/7W‚#¢”‹\wÊe¢SY"W®Ò|iŒ@(„÷d¶¦áƒCÿèu§ÁŠH^Utm´lÛeA4…¤{ÐÞ}g |ðxéÕu÷Ã÷°~lŸ¢í,_‹4«Á gk5áȬ*8Ï>³æùÐûëuŠ÷tSü8ÃêT¹¯‡ÚžAf•°àÑåâ±0Ò?б£-;vt-ѵs¹ E2R)ª—ÆX8w.ÿS[ë“Ó‰Øèz•¿ØÝ™´¬‘p:}·ÙÝÈÍd×…êä$¥‰‰üédâÀ¯ÉøéL&S¹ öåî[Sµ•×ÀqWÊô65P/±~Ï-ë;ŸˆžNÄ®d2™Ê†o6¶ÌäÛ:+Õ‘.GD­ˆä¯EšÆsñØ `1“ÉXÿâÿö_&ûјIEND®B`‚twinkle-1.4.2/src/gui/images/penguin.png0000644000175000001440000000374010503576707015121 00000000000000‰PNG  IHDR szzô pHYs  šœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFVIDATxÚbüÿÿ?Ã@€b$Q½‚´´t¾77·Áß¿@øû÷ï /^¼øðþýû @5x±±°´´¬WUU-’’bøùó'ï_¿À™ýáÆ0<~üøòïß¿ó€ú2 €˜‰°Ü &&f¿±±±Ðç ðòò2<þÃ!ÿþýc† ??¿øÇþüùó¨ÿ(>ÈP¤§§ï°··gpqqK¼y󆡫«‹áÖ­[XC-÷ïß±W•Gâ² €ðÆ·³³óûªªªÿ .ü |ùòåppðÿºººÿÀ‹?yòä?Ðáÿ%$$þ322‚Ry .K'âââÚ_XXø¿¸¸l :xúôéÿcÇNü߸qVÇÓÀooŸÿlll €°=6{ˆ ‡ý JJJ@×3üøñƒ˜òQ$ÿüùËpàÀ†Ý»w2ܾ}‹¡´´œ&@”­üø L_‚ƒÃ²y/È_è.ÔƒÈrP¼~ûö nøÏŸ¿>þưgÏ^†-[¶0<}ú œ>þ Ì’ÿ¾~ý¶üÃ‡Ï Ÿ>}:öÌLc B· €X°%}ú4ƒ­­-0aý:æ†3¼z¥ÈÀËÅÉ À¥Î ¨¨tÄW†/_¾ñw0^·n5ºÙaÐrâ3L €°9 D€ò4(@)zÉ’% jjš ŒŒÌ`Ëùøªäå20ü*|Ä/xS:ÃG¹m Ÿ9Õ€…Ò+†¥K2>¼‘ÝÁΊÂÈ lå@(@>WPP‡°„cØ¿ƒ0˜€Ž0`:ÎÀôëÃ{Pžd`ø$:‰]Å““ƒ¡¼¼€aíÚ•ˆxfbb`eee`aaa†ì  ÐU˜@a ~Xªý¯­­ýßÍÍí?° ø¿råJ”Tþ÷ÏÛÿÿ^Ëÿÿ…áÿ3ÿ¿}ûþÿÿqÿÿÍ›ÿÃÃ#ÁY™™ù?;;ûžÿ|||ÿÑ#@¡[þÙ@ÿ722ú?gάYíÿóÿ¿_øÿñã'`™ðíÿû÷Ÿþ¿zõþÿ³g¯ÿ?|øühhÄNNÎÿÀ’ó¿  à11±ÿ ³ó`–#’å @w°0¦ø=Xƒ ’P‹àÿ ¿ÿâ¿àT ÿ0ÄÄ„ë‡{ à‡E¸”|ùòe.Ј)ÄŒÏrØ·oÐÕ(b ìÊr @eÈBûœ s¬¬<°ÌضX(iP]Œ/`" @Lø,OHH'DtËA–þúõŒAAh“­¡¡Ã ¯o¶„auÈ`ôL P6lb ¤èðb)#??ÅrPmñ1j0#³ò¶››ÃÇ÷À«ë> Q7ø,ÈL€9`‹!• r €|n``€ßÿ0‚=¾±Y¢55õÁ¾•–@°ˆ¯ñwPy@°¢˜¡žA18;88@ƒœä¨ÁüÌFˆýFËx´ Ä~3¨ªj‚ ¶[ÐBè-¬0 lu¸9 H|£ZHL¼#‚pœ°°8¨ ±h4¨bù ³ €°9à/”““C²èF¢Cö!¦ãþ`8îÅ‹—Ÿ¡ÁÿÙ2€ÂU6k¹OèA‹-˜ ;î7ógÏÚµê9®6á`ÙÿÛÃÃÓ ÔÄ•èó<¶Ü›9³çÖÇw« ÕÖ'd‹o›PLL|ùþý‡#89¹Ñ,ÿK0GÀØóçOþ|øðîh qw€ø:º„+@¥O‚—×W“ë×6(89¾b`ý„áç×— ¿¿?føðE˜-A ôšå¯%Ü`Éy–AZü(ïϛ.;üVN‚AõÁS†@3ïñd‹[$ô÷óÍOHЬºA šÀhû ÌA_ß‚Óðï¯< ×_ø3<`LVµ,à¨50XÄ #lüç* ý†ôç3@=ßÀ9þÁ]†–Y çî`pÊžƒY@‰0+‹!¾ X6ó fš¯Ð\ 4ó?Ð^~ax±”åÝ)pBST\ ´ü$sý€10=@ü˜ôD€rÍ^ ü@‘4äê €0ZD›61\ úäà`zbùw8ýè€/ÀdôX\¼,B/οÅÀ¶é³„Ä=ÉɽϥDCÔÃô€B hùç@ l³ÎÞ¶â6´î74W",r°bð5Óa0æbaàÕ¦ˆ¿@åg.10||Çðùì=†³§1lv½`Kr€ƒ³*°ñ Œ6{m`ªÆøm`Ð?Éðìä]†³·^ƒõ€ê€»Ð,É@ør0Ô¥¼Xë_¤"õrÆAÒƒ~¡à @ŒÝ=0¹JEkiùEIEND®B`‚twinkle-1.4.2/src/gui/images/presence_offline.png0000644000175000001440000000152110637222346016750 00000000000000‰PNG  IHDRóÿaIDAT8U“ÏK+WÅÏ̽s3wâ˜F¤jiySg£«n á½fS¡uÑE©îtQêŸÐUÿ‡B]X^»zu¡ ‹‚¨´˜EÅI@II#Q‡I&óãæÎ}‹GÒ×gûáp¾ß£)¥P¯×!„€ý~œóç¹\îÛl6ûÌ4MÖï÷ÿ¸¾¾þeww÷Õýý½¢”b,m HÓžç=åœÿà8ÎÙlVÃ[ Ã';;;ßµZ­?9ç4MCÅÇÇÇß …Â¥TK’q#Š" ‡CH)á8Îó­­­W…BáS!Ä€4M­f³ù¥ô£8Žáº.z½‚ @ð<Ýn¾ï#ŸÏ?)—Ë?OMM½›¦éÀ`0ø$Š¢g㨷··8>>FEH’Ýn•Jq# CÌÎÎ>]^^þf4½ ‡ÃÏmÛFš¦ð}½^FBH)qww‡F£(Š ¥„eYpçkÓ4ŸP‚à³\.Î9„H’š¦A))%!0 išÂ0 (¥033ó¾aè ¥|϶m\^^b4¡X,bss£ÑRJÌÏÏc{{œóI2Ó4³º®¿£€eYÿPJáû>’$A6›…mÛ`ŒR Ó4aÛ6 Ã@§Ó¥J©hRb>Ÿÿ])ÆÎÎÎ`! ”‚R B!h·Ûð<¶mc0¸BˆGÎÏÏ•R¢T*M #„@Ó´‰=ÏCµZÅÜÜ,ËB«Õú+ Ãu8<<c,Ô4M¾½Ò×I¿ŸÕA?ýÇIEND®B`‚twinkle-1.4.2/src/gui/getprofilenameform.ui0000644000175000001440000001537111146625756015733 00000000000000 GetProfileNameForm GetProfileNameForm 0 0 430 127 Twinkle - Profile name unnamed userIconTextLabel WidgetOrigin penguin_big.png layout24 unnamed spacer41 Horizontal Expanding 81 20 okPushButton &OK true cancelPushButton &Cancel layout26 unnamed profileTextLabel 5 0 0 0 Enter a name for your profile: false AlignVCenter profileLineEdit <b>The name of your profile</b> <br><br> A profile contains your user settings, e.g. your user name and password. You have to give each profile a name. <br><br> If you have multiple SIP accounts, you can create multiple profiles. When you startup Twinkle it will show you the list of profile names from which you can select the profile you want to run. <br><br> To remember your profiles easily you could use your SIP user name as a profile name, e.g. <b>example@example.com</b> cancelPushButton clicked() GetProfileNameForm reject() okPushButton clicked() GetProfileNameForm validate() profileLineEdit okPushButton cancelPushButton qlineedit.h qregexp.h qvalidator.h protocol.h qmessagebox.h qdir.h qfile.h user.h getprofilenameform.ui.h validate() init() getProfileName() execNewName() execRename( const QString & oldName ) twinkle-1.4.2/src/gui/address_finder.h0000644000175000001440000000373311127714044014617 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ADDRESS_FINDER_H #define _ADDRESS_FINDER_H #include "twinkle_config.h" #include #include "user.h" #include "sockets/url.h" #include "threads/mutex.h" #include "qobject.h" #include "qimage.h" #ifdef HAVE_KDE #include #include #include #include #include #endif using namespace std; class t_address_finder : public QObject { private: Q_OBJECT static t_address_finder *instance; static t_mutex mtx_instance; t_mutex mtx_finder; #ifdef HAVE_KDE KABC::AddressBook *abook; #endif // Cached data for the last looked up URL. t_url last_url; string last_name; QImage last_photo; t_address_finder(); // Find the address based on a URL and put the found // data in the cache. void find_address(t_user *user_config, const t_url &u); public: // Preload KAddressbook static void preload(void); static t_address_finder *get_instance(void); // Find a name given a URL string find_name(t_user *user_config, const t_url &u); // Find a photo give a URL QImage find_photo(t_user *user_config, const t_url &u); public slots: void invalidate_cache(void); }; #endif twinkle-1.4.2/src/gui/redirectform.ui.h0000644000175000001440000000777711127714044014760 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void RedirectForm::init() { // Keeps track of which address book tool button is clicked. nrAddressBook = 0; getAddressForm = 0; // Set toolbutton icons for disabled options. QIconSet i; i = address1ToolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource("kontact_contacts-disabled.png"), QIconSet::Automatic, QIconSet::Disabled); address1ToolButton->setIconSet(i); address2ToolButton->setIconSet(i); address3ToolButton->setIconSet(i); } void RedirectForm::destroy() { if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } } void RedirectForm::show(t_user *user, const list &contacts) { user_config = user; int num = 0; for (list::const_iterator i = contacts.begin(); i != contacts.end(); i++, num++) { if (num == 0) contact1LineEdit->setText(i->c_str()); if (num == 1) contact2LineEdit->setText(i->c_str()); if (num == 2) contact3LineEdit->setText(i->c_str()); } QDialog::show(); } void RedirectForm::validate() { t_display_url destination; list dest_list; // 1st choice destination ui->expand_destination(user_config, contact1LineEdit->text().stripWhiteSpace().ascii(), destination); if (destination.is_valid()) { dest_list.push_back(destination); } else { contact1LineEdit->selectAll(); return; } // 2nd choice destination if (!contact2LineEdit->text().isEmpty()) { ui->expand_destination(user_config, contact2LineEdit->text().stripWhiteSpace().ascii(), destination); if (destination.is_valid()) { dest_list.push_back(destination); } else { contact2LineEdit->selectAll(); return; } } // 3rd choice destination if (!contact3LineEdit->text().isEmpty()) { ui->expand_destination(user_config, contact3LineEdit->text().stripWhiteSpace().ascii(), destination); if (destination.is_valid()) { dest_list.push_back(destination); } else { contact3LineEdit->selectAll(); return; } } emit destinations(dest_list); accept(); } void RedirectForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); getAddressForm->show(); } void RedirectForm::showAddressBook1() { nrAddressBook = 1; showAddressBook(); } void RedirectForm::showAddressBook2() { nrAddressBook = 2; showAddressBook(); } void RedirectForm::showAddressBook3() { nrAddressBook = 3; showAddressBook(); } void RedirectForm::selectedAddress(const QString &address) { switch(nrAddressBook) { case 1: contact1LineEdit->setText(address); break; case 2: contact2LineEdit->setText(address); break; case 3: contact3LineEdit->setText(address); break; } } twinkle-1.4.2/src/gui/transferform.ui0000644000175000001440000002517411131206211014527 00000000000000 TransferForm TransferForm 0 0 532 251 Twinkle - Transfer unnamed transferGroupBox Transfer call to unnamed toLabel &To: toLineEdit toLineEdit The address of the person you want to transfer the call to. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. addressToolButton TabFocus F10 kontact_contacts.png Address book Select an address from the address book. typeButtonGroup2 Type of transfer unnamed basicRadioButton &Blind transfer Alt+B true Transfer the call to a third party without contacting that third party yourself. consultRadioButton T&ransfer with consultation Alt+R Before transferring the call to a third party, first consult the party yourself. otherLineRadioButton Transfer to other &line Alt+L Connect the remote party on the active line with the remote party on the other line. spacer24 Vertical Expanding 20 20 layout28 unnamed spacer23 Horizontal Expanding 121 20 okPushButton &OK Alt+O true cancelPushButton &Cancel okPushButton clicked() TransferForm validate() cancelPushButton clicked() TransferForm reject() addressToolButton clicked() TransferForm showAddressBook() otherLineRadioButton toggled(bool) TransferForm setOtherLineAddress(bool) gui.h audits/memman.h qstring.h sockets/url.h getaddressform.h user.h protocol.h phone.h transferform.ui.h extern t_phone *phone int consult_line; t_user *user_config; GetAddressForm *getAddressForm; QString previousAddress; destination(const t_display_url&, t_transfer_type) initTransferOptions() show( t_user * user ) show( t_user * user, const string & dest, t_transfer_type transfer_type ) hide() reject() validate() closeEvent( QCloseEvent * ) showAddressBook() selectedAddress( const QString & address ) setOtherLineAddress( bool on ) init() destroy() twinkle-1.4.2/src/gui/mphoneform.ui.h0000644000175000001440000024674711150253414014442 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, pres:erving your code. Ceate an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinkle_config.h" #include "twinklesystray.h" // Time (s) that the conversation timer of a line should stay visible after // a call has ended #define HIDE_LINE_TIMER_AFTER 5 void MphoneForm::init() { // Forms dtmfForm = 0; inviteForm = 0; redirectForm = 0; transferForm = 0; termCapForm = 0; srvRedirectForm = 0; userProfileForm = 0; sysSettingsForm = 0; logViewForm = 0; historyForm = 0; selectUserForm = 0; selectProfileForm = 0; getAddressForm = 0; sysTray = 0; // Popup menu for a single buddy QIconSet inviteIcon(QPixmap::fromMimeSource("invite.png")); QIconSet messageIcon(QPixmap::fromMimeSource("message.png")); QIconSet editIcon(QPixmap::fromMimeSource("edit16.png")); QIconSet deleteIcon(QPixmap::fromMimeSource("editdelete.png")); buddyPopupMenu = new QPopupMenu(this); MEMMAN_NEW(buddyPopupMenu); buddyPopupMenu->insertItem(inviteIcon, tr("&Call..."), this, SLOT(doCallBuddy())); buddyPopupMenu->insertItem(messageIcon, tr("Instant &message..."), this, SLOT(doMessageBuddy())); buddyPopupMenu->insertItem(editIcon, tr("&Edit..."), this, SLOT(doEditBuddy())); buddyPopupMenu->insertItem(deleteIcon, tr("&Delete"), this, SLOT(doDeleteBuddy())); // Change availibility sub popup menu changeAvailabilityPopupMenu = new QPopupMenu(this); MEMMAN_NEW(changeAvailabilityPopupMenu); QIconSet availOnlineIcon(QPixmap::fromMimeSource("presence_online.png")); QIconSet availOfflineIcon(QPixmap::fromMimeSource("presence_offline.png")); changeAvailabilityPopupMenu->insertItem(availOfflineIcon, tr("O&ffline"), this, SLOT(doAvailabilityOffline())); changeAvailabilityPopupMenu->insertItem(availOnlineIcon, tr("&Online"), this, SLOT(doAvailabilityOnline())); // Popup menu for a buddy list (click on profile name) QIconSet changeAvailabilityIcon(QPixmap::fromMimeSource("presence_online.png")); QIconSet addIcon(QPixmap::fromMimeSource("buddy.png")); buddyListPopupMenu = new QPopupMenu(this); MEMMAN_NEW(buddyListPopupMenu); buddyListPopupMenu->insertItem(changeAvailabilityIcon, tr("&Change availability"), changeAvailabilityPopupMenu); buddyListPopupMenu->insertItem(addIcon, tr("&Add buddy..."), this, SLOT(doAddBuddy())); // Tool tip for buddy list buddyToolTip = new BuddyListViewTip(buddyListView); MEMMAN_NEW(buddyToolTip); // Line timers lineTimer1 = 0; lineTimer2 = 0; timer1TextLabel->hide(); timer2TextLabel->hide(); // Timer to hide the conversation timer after a conversation has ended. hideLineTimer1 = new QTimer(this); MEMMAN_NEW(hideLineTimer1); hideLineTimer2 = new QTimer(this); MEMMAN_NEW(hideLineTimer2); connect(hideLineTimer1, SIGNAL(timeout()), timer1TextLabel, SLOT(hide())); connect(hideLineTimer2, SIGNAL(timeout()), timer2TextLabel, SLOT(hide())); // Attach the MWI flash slot to the MWI flash timer connect(&tmrFlashMWI, SIGNAL(timeout()), this, SLOT(flashMWI())); // Set toolbar icons for disabled options. setDisabledIcon(callInvite, "invite-disabled.png"); setDisabledIcon(callAnswer, "answer-disabled.png"); setDisabledIcon(callBye, "bye-disabled.png"); setDisabledIcon(callReject, "reject-disabled.png"); setDisabledIcon(callRedirect, "redirect-disabled.png"); setDisabledIcon(callTransfer, "transfer-disabled.png"); setDisabledIcon(callHold, "hold-disabled.png"); setDisabledIcon(callConference, "conf-disabled.png"); setDisabledIcon(callMute, "mute-disabled.png"); setDisabledIcon(callDTMF, "dtmf-disabled.png"); setDisabledIcon(callRedial, "redial-disabled.png"); // Set tool button icons for disabled options setDisabledIcon(addressToolButton, "kontact_contacts-disabled.png"); // Some text labels on the main window are implemented as QLineEdit // objects as these do not automatically resize when a text set with setText // does not fit. The background of a QLineEdit is static however, it does not // automatically take a background color passed by the -bg parameter. // Set the background color of these QLineEdit objects here. from1Label->setPaletteBackgroundColor(paletteBackgroundColor()); to1Label->setPaletteBackgroundColor(paletteBackgroundColor()); subject1Label->setPaletteBackgroundColor(paletteBackgroundColor()); from2Label->setPaletteBackgroundColor(paletteBackgroundColor()); to2Label->setPaletteBackgroundColor(paletteBackgroundColor()); subject2Label->setPaletteBackgroundColor(paletteBackgroundColor()); // A QComboBox accepts a new line through copy/paste. QRegExp rxNoNewLine("[^\\n\\r]*"); callComboBox->setValidator(new QRegExpValidator(rxNoNewLine, this)); if (sys_config->get_gui_use_systray()) { // Create system tray icon sysTray = new t_twinkle_sys_tray(this, "twinkle_sys_tray"); MEMMAN_NEW(sysTray); sysTray->setPixmap( QPixmap::fromMimeSource("sys_idle_dis.png")); sysTray->setCaption(PRODUCT_NAME); QToolTip::add(sysTray, PRODUCT_NAME); // Add items to the system tray menu #ifdef HAVE_KDE KPopupMenu *menu; #else QPopupMenu *menu; #endif menu = sysTray->contextMenu(); // Call menu callInvite->addTo(menu); callAnswer->addTo(menu); callBye->addTo(menu); callReject->addTo(menu); callRedirect->addTo(menu); callTransfer->addTo(menu); callHold->addTo(menu); callConference->addTo(menu); callMute->addTo(menu); callDTMF->addTo(menu); callRedial->addTo(menu); menu->insertSeparator(); // Messaging actionSendMsg->addTo(menu); menu->insertSeparator(); // Line activation actgrActivateLine->addTo(menu); menu->insertSeparator(); // Service menu serviceDnd->addTo(menu); serviceRedirection->addTo(menu); serviceAutoAnswer->addTo(menu); servicesVoice_mailAction->addTo(menu); menu->insertSeparator(); // View menu viewCall_HistoryAction->addTo(menu); menu->insertSeparator(); // Diamondcard menu menu->insertItem("Diamondcard", Diamondcard); // Exit application when user selects Quit from the tray menu connect(sysTray, SIGNAL(quitSelected()), this, SLOT(fileExit())); sysTray->dock(); sysTray->show(); } } void MphoneForm::destroy() { if (dtmfForm) { MEMMAN_DELETE(dtmfForm); delete dtmfForm; } if (inviteForm) { MEMMAN_DELETE(inviteForm); delete inviteForm; } if (redirectForm) { MEMMAN_DELETE(redirectForm); delete redirectForm; } if (termCapForm) { MEMMAN_DELETE(termCapForm); delete termCapForm; } if (srvRedirectForm) { MEMMAN_DELETE(srvRedirectForm); delete srvRedirectForm; } if (userProfileForm) { MEMMAN_DELETE(userProfileForm); delete userProfileForm; } if (transferForm) { MEMMAN_DELETE(transferForm); delete transferForm; } if (sysSettingsForm) { MEMMAN_DELETE(sysSettingsForm); delete sysSettingsForm; } if (logViewForm) { if (logViewForm->isShown()) logViewForm->close(); MEMMAN_DELETE(logViewForm); delete logViewForm; } if (historyForm) { if (historyForm->isShown()) historyForm->close(); MEMMAN_DELETE(historyForm); delete historyForm; } if (selectUserForm) { MEMMAN_DELETE(selectUserForm); delete selectUserForm; } if (selectProfileForm) { MEMMAN_DELETE(selectProfileForm); delete selectProfileForm; } if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } if (sysTray) { MEMMAN_DELETE(sysTray); delete sysTray; } if (lineTimer1) { MEMMAN_DELETE(lineTimer1); delete lineTimer1; } if (lineTimer2) { MEMMAN_DELETE(lineTimer2); delete lineTimer2; } MEMMAN_DELETE(hideLineTimer1); delete hideLineTimer1; MEMMAN_DELETE(hideLineTimer2); delete hideLineTimer2; MEMMAN_DELETE(buddyPopupMenu); delete buddyPopupMenu; MEMMAN_DELETE(changeAvailabilityPopupMenu); delete changeAvailabilityPopupMenu; MEMMAN_DELETE(buddyListPopupMenu); delete buddyListPopupMenu; MEMMAN_DELETE(buddyToolTip); delete buddyToolTip; } QString MphoneForm::lineSubstate2str( int line) { QString reason; t_call_info call_info = phone->get_call_info(line); switch(phone->get_line_substate(line)) { case LSSUB_IDLE: return tr("idle"); case LSSUB_SEIZED: return tr("dialing"); case LSSUB_OUTGOING_PROGRESS: reason = call_info.last_provisional_reason.c_str(); if (reason == "") { return tr("attempting call, please wait"); } return reason; case LSSUB_INCOMING_PROGRESS: return QString("") + tr("incoming call") + ""; case LSSUB_ANSWERING: return tr("establishing call, please wait"); case LSSUB_ESTABLISHED: if (phone->has_line_media(line)) { return tr("established"); } else { return tr("established (waiting for media)"); } break; case LSSUB_RELEASING: return tr("releasing call, please wait"); default: return tr("unknown state"); } } void MphoneForm::closeEvent( QCloseEvent *e ) { if (sysTray && sys_config->get_gui_hide_on_close()) { hide(); } else { fileExit(); } } void MphoneForm::fileExit() { hide(); QApplication::exit(0); } // Append a string to the display window void MphoneForm::display( const QString &s ) { displayContents.push_back(s); if (displayContents.size() > 100) { displayContents.pop_front(); } displayTextEdit->setText(displayContents.join("\n")); // Set cursor position at the end of text displayTextEdit->setCursorPosition(displayTextEdit->paragraphs() - 1, 0); } // Print message header on display void MphoneForm::displayHeader() { display(""); display(current_time2str("%a %H:%M:%S").c_str()); } // Update the conversation timer void MphoneForm::showLineTimer(int line) { struct timeval t; gettimeofday(&t, NULL); QLabel *timerLabel; if (line == 0) { timerLabel = timer1TextLabel; } else { timerLabel = timer2TextLabel; } // Calculate duration of call t_call_record cr = phone->get_call_hist(line); unsigned long duration = t.tv_sec - cr.time_answer; timerLabel->setText(timer2str(duration).c_str()); } void MphoneForm::showLineTimer1() { showLineTimer(0); } void MphoneForm::showLineTimer2() { showLineTimer(1); } // Update visibility of the conversation timer for a line // Initialize the timer for a new established call. void MphoneForm::updateLineTimer(int line) { QLabel *timerLabel; QTimer **timer; QTimer *hideLineTimer; if (line == 0) { timerLabel = timer1TextLabel; timer = &lineTimer1; hideLineTimer = hideLineTimer1; } else { timerLabel = timer2TextLabel; timer = &lineTimer2; hideLineTimer = hideLineTimer2; } t_line_substate line_substate = phone->get_line_substate(line); // Stop hide timer if necessary switch(line_substate) { case LSSUB_IDLE: case LSSUB_RELEASING: // Timer can be shown as long as line is idle or releasing. break; default: // The timer showing the call duration should only stay // for a few seconds as long as the line is idle or being // released. // If a new call arrives on the line, the hide timer should // be stopped, otherwise the timer of the new call will // automatically disappear. if (hideLineTimer->isActive()) { hideLineTimer->stop(); if (*timer == NULL) timerLabel->hide(); } break; } switch(line_substate) { case LSSUB_ESTABLISHED: // Initialize and show call duration timer if (*timer == NULL) { timerLabel->setText(timer2str(0).c_str()); timerLabel->show(); *timer = new QTimer(this); MEMMAN_NEW(*timer); if (line == 0) { connect(*timer, SIGNAL(timeout()), this, SLOT(showLineTimer1())); } else { connect(*timer, SIGNAL(timeout()), this, SLOT(showLineTimer2())); } // Update timer every 1s (*timer)->start(1000, false); } break; default: // Hide call duration timer if (*timer != NULL) { // Hide the timer after a few seconds hideLineTimer->start(HIDE_LINE_TIMER_AFTER * 1000, true); (*timer)->stop(); MEMMAN_DELETE(*timer); *timer = NULL; } break; } } void MphoneForm::updateLineEncryptionState(int line) { QLabel *cryptLabel, *sasLabel; if (line == 0) { cryptLabel = crypt1Label; sasLabel = line1SasLabel; } else { cryptLabel = crypt2Label; sasLabel = line2SasLabel; } t_audio_session *as = phone->get_line(line)->get_audio_session(); if (as && phone->is_line_encrypted(line)) { string zrtp_sas = as->get_zrtp_sas(); bool zrtp_sas_confirmed = as->get_zrtp_sas_confirmed(); string srtp_cipher_mode = as->get_srtp_cipher_mode(); QToolTip::remove(cryptLabel); QString toolTip = tr("Voice is encrypted") + " ("; toolTip.append(srtp_cipher_mode.c_str()).append(")"); if (!zrtp_sas.empty()) { // Set tool tip on encryption icon toolTip.append("\nSAS = "); toolTip.append(zrtp_sas.c_str()); // Show SAS sasLabel->setText(zrtp_sas.c_str()); sasLabel->show(); } else { sasLabel->hide(); } if (!zrtp_sas_confirmed) { toolTip.append("\n").append(tr("Click to confirm SAS.")); cryptLabel->setFrameStyle(QFrame::Panel | QFrame::Raised); cryptLabel->setPixmap( QPixmap::fromMimeSource("encrypted.png")); } else { toolTip.append("\n").append(tr("Click to clear SAS verification.")); cryptLabel->setFrameStyle(QFrame::NoFrame); cryptLabel->setPixmap( QPixmap::fromMimeSource("encrypted_verified.png")); } QToolTip::add(cryptLabel, toolTip); cryptLabel->show(); } else { cryptLabel->hide(); sasLabel->hide(); } } void MphoneForm::updateLineStatus(int line) { QString state; bool on_hold; // indicates if a line is put on-hold bool in_conference; // indicates if a line is in a conference bool is_muted; // indicates is a line is muted t_refer_state refer_state; // indicates if a call transfer is in progress bool is_transfer_consult; // indicates if the call is a consultation bool to_be_transferred; // indicates if the line is to be transferred after consultation t_call_info call_info; unsigned short dummy; QLabel *statLabel, *holdLabel, *muteLabel, *confLabel, *referLabel, *statusTextLabel; if (line == 0) { statLabel = line1StatLabel; holdLabel = line1HoldLabel; muteLabel = line1MuteLabel; confLabel = line1ConfLabel; referLabel = line1ReferLabel; statusTextLabel = status1TextLabel; } else { statLabel = line2StatLabel; holdLabel = line2HoldLabel; muteLabel = line2MuteLabel; confLabel = line2ConfLabel; referLabel = line2ReferLabel; statusTextLabel = status2TextLabel; } state = lineSubstate2str(line); on_hold = phone->is_line_on_hold(line); if (on_hold) { holdLabel->show(); } else { holdLabel->hide(); } in_conference = phone->part_of_3way(line); if (in_conference) { confLabel->show(); } else { confLabel->hide(); } is_muted = phone->is_line_muted(line); if (is_muted) { muteLabel->show(); } else { muteLabel->hide(); } refer_state = phone->get_line_refer_state(line); is_transfer_consult = phone->is_line_transfer_consult(line, dummy); to_be_transferred = phone->line_to_be_transferred(line, dummy); if (refer_state != REFST_NULL || is_transfer_consult || to_be_transferred) { QString toolTip; QToolTip::remove(referLabel); referLabel->show(); if (is_transfer_consult) { referLabel->setPixmap( QPixmap::fromMimeSource("consult-xfer.png")); toolTip = tr("Transfer consultation"); } else { referLabel->setPixmap( QPixmap::fromMimeSource("cf.png")); toolTip = tr("Transferring call"); } QToolTip::add(referLabel, toolTip); } else { referLabel->hide(); } statusTextLabel->setText(state); t_line_substate line_substate; line_substate = phone->get_line_substate(line); switch (line_substate) { case LSSUB_IDLE: ((t_gui *)ui)->clearLineFields(line); statLabel->hide(); break; case LSSUB_SEIZED: case LSSUB_OUTGOING_PROGRESS: statLabel->setPixmap(QPixmap::fromMimeSource("stat_outgoing.png")); statLabel->show(); break; case LSSUB_INCOMING_PROGRESS: statLabel->setPixmap(QPixmap::fromMimeSource("stat_ringing.png")); statLabel->show(); break; case LSSUB_ANSWERING: statLabel->setPixmap(QPixmap::fromMimeSource("gear.png")); statLabel->show(); break; case LSSUB_ESTABLISHED: if (phone->has_line_media(line)) { statLabel->setPixmap(QPixmap::fromMimeSource( "stat_established.png")); } else { statLabel->setPixmap(QPixmap::fromMimeSource( "stat_established_nomedia.png")); } statLabel->show(); break; case LSSUB_RELEASING: statLabel->setPixmap(QPixmap::fromMimeSource("gear.png")); statLabel->show(); break; default: statLabel->hide(); break; } updateLineEncryptionState(line); updateLineTimer(line); } // Update line state and enable/disable buttons depending on state void MphoneForm::updateState() { QString state; int line, other_line; bool on_hold; // indicates if a line is put on-hold bool in_conference; // indicates if a line is in a conference bool is_muted; // indicates is a line is muted t_refer_state refer_state; // indicates if a call transfer is in progress bool is_transfer_consult; // indicates if the call is a consultation bool to_be_transferred; // indicates if the line is to be transferred after consultation bool has_media; // indicates if a media stream is present t_call_info call_info; unsigned short dummy; // Update status of line 1 updateLineStatus(0); // Update status of line 2 updateLineStatus(1); // Disable/enable controls depending on the active line state t_line_substate line_substate; line = phone->get_active_line(); line_substate = phone->get_line_substate(line); on_hold = phone->is_line_on_hold(line); in_conference = phone->part_of_3way(line); is_muted = phone->is_line_muted(line); refer_state = phone->get_line_refer_state(line); is_transfer_consult = phone->is_line_transfer_consult(line, dummy); to_be_transferred = phone->line_to_be_transferred(line, dummy); has_media = phone->has_line_media(line); other_line = (line == 0 ? 1 : 0); call_info = phone->get_call_info(line); t_user *user_config = phone->get_line_user(line); // The active line may change when one of the parties in a conference // releases the call. If this happens, then update the state of the // line radio buttons. if (line == 0 && line2RadioButton->isOn()) { line1RadioButton->setChecked(true); } else if (line == 1 && line1RadioButton->isOn()) { line2RadioButton->setChecked(true); } // Same logic for the activate line menu items if (line == 0 && actionLine2->isOn()) { actionLine1->setOn(true); } else if (line == 1 && actionLine1->isOn()) { actionLine2->setOn(true); } switch(line_substate) { case LSSUB_IDLE: enableCallOptions(true); callAnswer->setEnabled(false); callBye->setEnabled(false); callReject->setEnabled(false); callRedirect->setEnabled(false); callTransfer->setEnabled(false); callHold->setEnabled(false); callConference->setEnabled(false); callMute->setEnabled(false); callDTMF->setEnabled(false); callRedial->setEnabled(ui->can_redial()); break; case LSSUB_OUTGOING_PROGRESS: enableCallOptions(false); callAnswer->setEnabled(false); callBye->setEnabled(true); callReject->setEnabled(false); callRedirect->setEnabled(false); if (is_transfer_consult && user_config->get_allow_transfer_consultation_inprog()) { callTransfer->setEnabled(true); } else { callTransfer->setEnabled(false); } callHold->setEnabled(false); callConference->setEnabled(false); callMute->setEnabled(false); callDTMF->setEnabled(call_info.dtmf_supported); callRedial->setEnabled(false); break; case LSSUB_INCOMING_PROGRESS: enableCallOptions(false); callAnswer->setEnabled(true); callBye->setEnabled(false); callReject->setEnabled(true); callRedirect->setEnabled(true); callTransfer->setEnabled(false); callHold->setEnabled(false); callConference->setEnabled(false); callMute->setEnabled(false); callDTMF->setEnabled(call_info.dtmf_supported); callRedial->setEnabled(false); break; case LSSUB_ESTABLISHED: enableCallOptions(false); callInvite->setEnabled(false); callAnswer->setEnabled(false); callBye->setEnabled(true); callReject->setEnabled(false); callRedirect->setEnabled(false); if (in_conference) { callTransfer->setEnabled(false); callHold->setEnabled(false); callConference->setEnabled(false); callDTMF->setEnabled(false); } else { callTransfer->setEnabled(has_media && call_info.refer_supported && refer_state == REFST_NULL && !to_be_transferred); callHold->setEnabled(has_media); callDTMF->setEnabled(call_info.dtmf_supported); if (phone->get_line_substate(other_line) == LSSUB_ESTABLISHED) { // If one of the lines is transferring a call, then a // conference cannot be setup. if (refer_state != REFST_NULL || phone->get_line_refer_state(other_line) != REFST_NULL) { callConference->setEnabled(false); } else { callConference->setEnabled(has_media); } } else { callConference->setEnabled(false); } } callMute->setEnabled(true); callRedial->setEnabled(false); break; case LSSUB_SEIZED: case LSSUB_ANSWERING: case LSSUB_RELEASING: // During dialing, answering and call release no other actions are // possible enableCallOptions(false); callAnswer->setEnabled(false); callBye->setEnabled(false); callReject->setEnabled(false); callRedirect->setEnabled(false); callTransfer->setEnabled(false); callHold->setEnabled(false); callConference->setEnabled(false); callMute->setEnabled(false); callDTMF->setEnabled(false); callRedial->setEnabled(false); break; default: enableCallOptions(true); callAnswer->setEnabled(true); callBye->setEnabled(true); callReject->setEnabled(true); callRedirect->setEnabled(true); callTransfer->setEnabled(true); callHold->setEnabled(true); callConference->setEnabled(false); callMute->setEnabled(true); callDTMF->setEnabled(true); callRedial->setEnabled(ui->can_redial()); } // Set hold action in correct state callHold->setOn(on_hold); // Set mute action in correct state callMute->setOn(is_muted); // Set transfer action in correct state callTransfer->setOn(is_transfer_consult); // Hide redirect form if it is still visible, but not applicable anymore if (!callRedirect->isEnabled() && redirectForm && redirectForm->isVisible()) { redirectForm->hide(); } // Hide transfer form if it is still visible, but not applicable anymore if (!callTransfer->isEnabled() && transferForm && transferForm->isVisible()) { transferForm->hide(); } // Hide DTMF form if it is still visible, but not applicable anymore if (!callDTMF->isEnabled() && dtmfForm && dtmfForm->isVisible()) { dtmfForm->hide(); } // Set last called address in the redial tool tip t_url last_url; string last_display; string last_subject; t_user *last_user; bool hide_user; if (callRedial->isEnabled() && ui->get_last_call_info(last_url, last_display, last_subject, &last_user, hide_user)) { QString s = ""; s += tr("Repeat last call"); s += "
"; s += ""; s += ""; if (!last_subject.empty()) { s.append(""; } if (hide_user) { s.append(""; } s += "
"; s += tr("User:").append(""); s += last_user->get_profile_name().c_str(); s.append("
").append(tr("Call:")).append(""); s += ui->format_sip_address(last_user, last_display, last_url).c_str(); s += "
").append(tr("Subject:")).append(""); s += last_subject.c_str(); s += "
").append(tr("Hide identity")); s += "
"; callRedial->setToolTip(s); } else { callRedial->setToolTip(tr("Repeat last call")); } callRedial->setStatusTip(tr("Repeat last call")); updateSysTrayStatus(); } // Update registration status void MphoneForm::updateRegStatus() { size_t num_registered = 0; size_t num_failed = 0; QString toolTip = ""; toolTip.append(tr("Registration status:")); toolTip.append("
"); toolTip.append(""); // Count number of succesful and failed registrations. // Determine tool tip showing registration details for all users. listuser_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { toolTip.append(""); } toolTip.append("
"); toolTip.append((*i)->get_profile_name().c_str()); toolTip.append(""); if (phone->get_is_registered(*i)) { num_registered++; toolTip.append(tr("Registered")); } else if (phone->get_last_reg_failed(*i)) { num_failed++; toolTip.append(tr("Failed")); } else { toolTip.append(tr("Not registered").replace(' ', " ")); } toolTip.append("

"); toolTip.append(""); toolTip.append(tr("Click to show registrations.").replace(' ', " ")); toolTip.append(""); // Set registration status if (num_registered == user_list.size()) { // All users are registered statRegLabel->setPixmap(QPixmap::fromMimeSource("twinkle16.png")); } else if (num_failed == user_list.size()) { // All users failed to register statRegLabel->setPixmap(QPixmap::fromMimeSource("reg_failed.png")); } else if (num_registered > 0) { // Some users are registered statRegLabel->setPixmap(QPixmap::fromMimeSource( "twinkle16.png")); } else if (num_failed > 0) { // Some users failed, none are registered statRegLabel->setPixmap(QPixmap::fromMimeSource("reg_failed.png")); } else { // No users are registered, no users failed statRegLabel->setPixmap(QPixmap::fromMimeSource("twinkle16-disabled.png")); } // Set tool tip with detailed info. QToolTip::remove(statRegLabel); if (num_registered > 0 || num_failed > 0) { QToolTip::add(statRegLabel, toolTip); } else { QToolTip::add(statRegLabel, tr("No users are registered.")); } updateSysTrayStatus(); } // Create a status message based on the number of waiting messages. // On return, msg_waiting will indicate if the MWI indicator should show // waiting messages. QString MphoneForm::getMWIStatus(const t_mwi &mwi, bool &msg_waiting) const { QString status; msg_waiting = false; t_msg_summary summary = mwi.get_voice_msg_summary(); if (summary.newmsgs > 0 && summary.oldmsgs > 0) { if (summary.oldmsgs == 1) { status = tr("%1 new, 1 old message"). arg(summary.newmsgs); } else { status = tr("%1 new, %2 old messages"). arg(summary.newmsgs). arg(summary.oldmsgs); } msg_waiting = true; } else if (summary.newmsgs > 0 && summary.oldmsgs == 0) { if (summary.newmsgs == 1) { status = tr("1 new message"); } else { status = tr("%1 new messages"). arg(summary.newmsgs); } msg_waiting = true; } else if (summary.oldmsgs > 0) { if (summary.oldmsgs == 1) { status = tr("1 old message"); } else { status = tr("%1 old messages"). arg(summary.oldmsgs); } } else { if (mwi.get_msg_waiting()) { status = tr("Messages waiting"); msg_waiting = true; } else { status = tr("No messages"); } } return status.replace(' ', " "); } // Flash the MWI icon void MphoneForm::flashMWI() { if (mwiFlashStatus) { mwiFlashStatus = false; statMWILabel->setPixmap(QPixmap::fromMimeSource( "mwi_none16.png")); } else { mwiFlashStatus = true; statMWILabel->setPixmap(QPixmap::fromMimeSource( "mwi_new16.png")); } } // Update MWI void MphoneForm::updateMwi() { bool mwi_known = false; bool mwi_new_msgs = false; bool mwi_failure = false; // Determine tool tip QString toolTip = tr("Voice mail status:").append("\n"); toolTip.append("
"); listuser_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { toolTip.append(""); } toolTip.append("
"); toolTip.append((*i)->get_profile_name().c_str()); t_mwi mwi = phone->get_mwi(*i); toolTip.append(""); if (phone->is_mwi_subscribed(*i)) { if (mwi.get_status() == t_mwi::MWI_KNOWN) { bool new_msgs; QString status = getMWIStatus(mwi, new_msgs); toolTip.append(status); mwi_known = true; mwi_new_msgs |= new_msgs; } else if (mwi.get_status() == t_mwi::MWI_FAILED) { toolTip.append(tr("Failure")); mwi_failure = true; } else { toolTip.append(tr("Unknown")); } } else { if ((*i)->get_mwi_sollicited()) { if (mwi.get_status() == t_mwi::MWI_FAILED) { toolTip.append(tr("Failure")); mwi_failure = true; } else { toolTip.append(tr("Unknown")); } } else { // Unsollicited MWI if (mwi.get_status() == t_mwi::MWI_KNOWN) { bool new_msgs; QString status = getMWIStatus(mwi, new_msgs); toolTip.append(status); mwi_known = true; mwi_new_msgs |= new_msgs; } else { toolTip.append(tr("Unknown")); } } } toolTip.append("

"); toolTip.append(""); toolTip.append(tr("Click to access voice mail.").replace(' ', " ")); toolTip.append(""); // Set MWI icon if (mwi_new_msgs) { statMWILabel->setPixmap(QPixmap::fromMimeSource( "mwi_new16.png")); mwiFlashStatus = true; // Start the flash MWI timer to flash the indicator tmrFlashMWI.start(1000); } else if (mwi_failure) { tmrFlashMWI.stop(); statMWILabel->setPixmap(QPixmap::fromMimeSource( "mwi_failure16.png")); } else if (mwi_known) { tmrFlashMWI.stop(); statMWILabel->setPixmap(QPixmap::fromMimeSource( "mwi_none16.png")); } else { tmrFlashMWI.stop(); statMWILabel->setPixmap(QPixmap::fromMimeSource( "mwi_none16_dis.png")); } // Set tool tip QToolTip::remove(statMWILabel); QToolTip::add(statMWILabel, toolTip); updateSysTrayStatus(); } // Update active services status void MphoneForm::updateServicesStatus() { size_t num_dnd = 0; size_t num_cf = 0; size_t num_auto_answer = 0; QString tipDnd = ""; tipDnd += tr("Do not disturb active for:").replace(' ', " "); tipDnd += "
\n"; QString tipCf = ""; tipCf += tr("Redirection active for:").replace(' ', " "); tipCf += "
\n
"; QString tipAa = ""; tipAa += tr("Auto answer active for:").replace(' ', " "); tipAa += "
\n
"; // Calculate number of services active. // Determine tool tips with detailed service status for all users. listuser_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if (phone->ref_service(*i)->is_dnd_active()) { num_dnd++; tipDnd.append(""); } if (phone->ref_service(*i)->is_cf_active()) { num_cf++; tipCf.append(""); } if (phone->ref_service(*i)->is_auto_answer_active()) { num_auto_answer++; tipAa.append(""); } } QString footer = ""; footer += tr("Click to activate/deactivate").replace(' ', " "); footer += ""; tipDnd.append("
"); tipDnd.append((*i)->get_profile_name().c_str()); tipDnd.append("
"); tipCf.append((*i)->get_profile_name().c_str()); tipCf.append("
"); tipAa.append((*i)->get_profile_name().c_str()); tipAa.append("

"); tipDnd.append(footer); tipCf.append("
"); tipCf.append(footer); tipAa.append("
"); tipAa.append(footer); // Set service status if (num_dnd == user_list.size()) { // All users enabled dnd statDndLabel->setPixmap(QPixmap::fromMimeSource("cancel.png")); } else if (num_dnd > 0) { // Some users enabled dnd statDndLabel->setPixmap(QPixmap::fromMimeSource("cancel.png")); } else { // No users enabeld dnd statDndLabel->setPixmap(QPixmap::fromMimeSource("cancel-disabled.png")); } if (num_cf == user_list.size()) { // All users enabled redirecton statCfLabel->setPixmap(QPixmap::fromMimeSource("cf.png")); } else if (num_cf > 0) { // Some users enabled redirection statCfLabel->setPixmap(QPixmap::fromMimeSource("cf.png")); } else { // No users enabled redirection statCfLabel->setPixmap(QPixmap::fromMimeSource("cf-disabled.png")); } if (num_auto_answer == user_list.size()) { // All users enabled auto answer statAaLabel->setPixmap(QPixmap::fromMimeSource("auto_answer.png")); } else if (num_auto_answer > 0) { // Some users enabled auto answer statAaLabel->setPixmap(QPixmap::fromMimeSource( "auto_answer.png")); } else { // No users enabeld auto answer statAaLabel->setPixmap(QPixmap::fromMimeSource( "auto_answer-disabled.png")); } // Set tool tip with detailed info for multiple users. QToolTip::remove(statDndLabel); QToolTip::remove(statCfLabel); QToolTip::remove(statAaLabel); QString clickToActivate(""); clickToActivate += tr("Click to activate").replace(' ', " "); clickToActivate += ""; if (num_dnd > 0) { QToolTip::add(statDndLabel, tipDnd); } else { QString status("

"); status += tr("Do not disturb is not active.").replace(' ', " "); status += "

"; status += clickToActivate; QToolTip::add(statDndLabel, status); } if (num_cf > 0) { QToolTip::add(statCfLabel, tipCf); } else { QString status("

"); status += tr("Redirection is not active.").replace(' ', " "); status += "

"; status += clickToActivate; QToolTip::add(statCfLabel, status); } if (num_auto_answer > 0) { QToolTip::add(statAaLabel, tipAa); } else { QString status("

"); status += tr("Auto answer is not active.").replace(' ', " "); status += "

"; status += clickToActivate; QToolTip::add(statAaLabel, status); } updateSysTrayStatus(); } void MphoneForm::updateMissedCallStatus(int num_missed_calls) { QToolTip::remove(statMissedLabel); QString clickDetails(""); clickDetails += tr("Click to see call history for details.").replace(' ', " "); clickDetails += ""; if (num_missed_calls == 0) { statMissedLabel->setPixmap(QPixmap::fromMimeSource("missed-disabled.png")); QString status("

"); status += tr("You have no missed calls.").replace(' ', " "); status += "

"; status += clickDetails; QToolTip::add(statMissedLabel, status); } else { statMissedLabel->setPixmap( QPixmap::fromMimeSource("missed.png")); QString tip("

"); if (num_missed_calls == 1) { tip += tr("You missed 1 call.").replace(' ', " "); } else { tip += tr("You missed %1 calls.").arg(num_missed_calls). replace(' ', " "); } tip += "

"; tip += clickDetails; QToolTip::add(statMissedLabel, tip); } updateSysTrayStatus(); } // Update system tray status void MphoneForm::updateSysTrayStatus() { QString icon_name; bool cf_active = false; bool dnd_active = false; bool auto_answer_active = false; bool multi_services = false; int num_services; bool msg_waiting = false; if (!sysTray) return; // Get status of active line int line = phone->get_active_line(); t_line_substate line_substate = phone->get_line_substate(line); list user_list = phone->ref_users(); switch(line_substate) { case LSSUB_IDLE: case LSSUB_SEIZED: // Determine MWI and service status user_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { t_mwi mwi = phone->get_mwi(*i); if (mwi.get_status() == t_mwi::MWI_KNOWN && mwi.get_msg_waiting() && mwi.get_voice_msg_summary().newmsgs > 0) { msg_waiting = true; } else if (phone->ref_service(*i)->multiple_services_active()) { multi_services = true; } else { if (phone->ref_service(*i)->is_dnd_active()) { dnd_active = true; } if (phone->ref_service(*i)->is_cf_active()) { cf_active = true; } if (phone->ref_service(*i)->is_auto_answer_active()) { auto_answer_active = true; } } } // If there are messages waiting, then show MWI icon if (msg_waiting) { icon_name = "sys_mwi"; break; } // If there are missed calls, then show the missed call icon if (call_history->get_num_missed_calls() > 0) { icon_name = "sys_missed"; break; } // If a service is active, then show the service icon num_services = (dnd_active ? 1 : 0) + (cf_active ? 1 : 0) + (auto_answer_active ? 1 : 0); if (multi_services || num_services > 1) { icon_name = "sys_services"; } else if (dnd_active) { icon_name = "sys_dnd"; } else if (cf_active) { icon_name = "sys_redir"; } else if (auto_answer_active) { icon_name = "sys_auto_ans"; } else { // No service is active, show the idle icon if (icon_name.isEmpty()) icon_name = "sys_idle"; } break; case LSSUB_ESTABLISHED: if (phone->is_line_on_hold(line)) { icon_name = "sys_hold"; } else if (phone->is_line_muted(line)) { icon_name = "sys_mute"; } else if (phone->is_line_encrypted(line)) { t_audio_session *as = phone->get_line(line)->get_audio_session(); if (as && as->get_zrtp_sas_confirmed()) { icon_name = "sys_encrypted_verified"; } else { icon_name = "sys_encrypted"; } } else { icon_name = "sys_busy_estab"; } break; default: // Line is in a busy transient state icon_name = "sys_busy_trans"; } // Based on the registration status use the active or disabled version // of the icon. bool registered = false; for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if (phone->get_is_registered(*i)) { registered = true; break; } } if (registered) { icon_name += ".png"; } else { icon_name += "_dis.png"; } sysTray->setPixmap(QPixmap::fromMimeSource(icon_name)); } // Update menu status based on the number of active users void MphoneForm::updateMenuStatus() { // Some menu options should be toggle actions when there is only // 1 user active, but they should be normal actions when there are // multiple users. disconnect(serviceDnd, 0, 0, 0); disconnect(serviceAutoAnswer, 0, 0, 0); if (phone->ref_users().size() == 1) { t_service *srv = phone->ref_service(phone->ref_users().front()); serviceDnd->setToggleAction(true); serviceDnd->setOn(srv->is_dnd_active()); connect(serviceDnd, SIGNAL(toggled(bool)), this, SLOT(srvDnd(bool))); serviceAutoAnswer->setToggleAction(true); serviceAutoAnswer->setOn(srv->is_auto_answer_active()); connect(serviceAutoAnswer, SIGNAL(toggled(bool)), this, SLOT(srvAutoAnswer(bool))); } else { serviceDnd->setOn(false); serviceDnd->setToggleAction(false); connect(serviceDnd, SIGNAL(activated()), this, SLOT(srvDnd())); serviceAutoAnswer->setOn(false); serviceAutoAnswer->setToggleAction(false); connect(serviceAutoAnswer, SIGNAL(activated()), this, SLOT(srvAutoAnswer())); } updateDiamondcardMenu(); } void MphoneForm::updateDiamondcardMenu() { // If one Diamondcard user is active, then create actions in the Diamondcard // main menu for recharging, call history, etc. These actions will show the // Diamondcard web page. // If multiple Diamondcard users are active then create a submenu of each // Diamondcard action. In each submenu create an item for each user. // When a user item is clicked, the web page for the action and that user is // shown. list diamondcard_users = diamondcard_get_users(phone); // Menu item identifiers static int rechargeId = -1; static int balanceHistoryId = -1; static int callHistoryId = -1; static int adminCenterId = -1; // Sub menu's static QPopupMenu *rechargeMenu = NULL; static QPopupMenu *balanceHistoryMenu = NULL; static QPopupMenu *callHistoryMenu = NULL; static QPopupMenu *adminCenterMenu = NULL; // Clear old menu removeDiamondcardAction(rechargeId); removeDiamondcardAction(balanceHistoryId); removeDiamondcardAction(callHistoryId); removeDiamondcardAction(adminCenterId); removeDiamondcardMenu(rechargeMenu); removeDiamondcardMenu(balanceHistoryMenu); removeDiamondcardMenu(callHistoryMenu); removeDiamondcardMenu(adminCenterMenu); if (diamondcard_users.size() <= 1) { rechargeId = Diamondcard->insertItem(tr("Recharge..."), this, SLOT(DiamondcardRecharge(int))); Diamondcard->setItemParameter(rechargeId, 0); balanceHistoryId = Diamondcard->insertItem(tr("Balance history..."), this, SLOT(DiamondcardBalanceHistory(int))); Diamondcard->setItemParameter(balanceHistoryId, 0); callHistoryId = Diamondcard->insertItem(tr("Call history..."), this, SLOT(DiamondcardCallHistory(int))); Diamondcard->setItemParameter(callHistoryId, 0); adminCenterId = Diamondcard->insertItem(tr("Admin center..."), this, SLOT(DiamondcardAdminCenter(int))); Diamondcard->setItemParameter(adminCenterId, 0); // Disable actions as there is no active Diamondcard users. if (diamondcard_users.empty()) { Diamondcard->setItemEnabled(rechargeId, false); Diamondcard->setItemEnabled(balanceHistoryId, false); Diamondcard->setItemEnabled(callHistoryId, false); Diamondcard->setItemEnabled(adminCenterId, false); } } else { rechargeMenu = new QPopupMenu(this); balanceHistoryMenu = new QPopupMenu(this); callHistoryMenu = new QPopupMenu(this); adminCenterMenu = new QPopupMenu(this); // No MEMMAN registration as the popup menu may be automatically // deleted by Qt on application close down. This would show up as // a memory leak in MEMMAN. // Insert a menu item for each Diamondcard user. int idx = 0; for (list::const_iterator it = diamondcard_users.begin(); it != diamondcard_users.end(); ++it) { int menuId; t_user *user = *it; // Set the index in the user list as parameter to the menu item. // When the menu item gets clicked, then the receiver of the signal // received this parameter and can use it as an index in the user list // to find the user. menuId = rechargeMenu->insertItem(user->get_profile_name().c_str(), this, SLOT(DiamondcardRecharge(int))); rechargeMenu->setItemParameter(menuId, idx); menuId = balanceHistoryMenu->insertItem(user->get_profile_name().c_str(), this, SLOT(DiamondcardBalanceHistory(int))); balanceHistoryMenu->setItemParameter(menuId, idx); menuId = callHistoryMenu->insertItem(user->get_profile_name().c_str(), this, SLOT(DiamondcardCallHistory(int))); callHistoryMenu->setItemParameter(menuId, idx); menuId = adminCenterMenu->insertItem(user->get_profile_name().c_str(), this, SLOT(DiamondcardAdminCenter(int))); adminCenterMenu->setItemParameter(menuId, idx); ++idx; } // Add the Diamondcard popup menus to the main Diamondcard menu. Diamondcard->insertItem(tr("Recharge"), rechargeMenu); Diamondcard->insertItem(tr("Balance history"), balanceHistoryMenu); Diamondcard->insertItem(tr("Call history"), callHistoryMenu); Diamondcard->insertItem(tr("Admin center"), adminCenterMenu); } } void MphoneForm::removeDiamondcardAction(int &id) { if (id != -1) { Diamondcard->removeItem(id); id = -1; } } void MphoneForm::removeDiamondcardMenu(QPopupMenu* &menu) { if (menu) { delete menu; menu = NULL; } } void MphoneForm::phoneRegister() { t_gui *gui = (t_gui *)ui; list user_list = phone->ref_users(); if (user_list.size() > 1) { if (selectUserForm) { MEMMAN_DELETE(selectUserForm); delete (selectUserForm); } selectUserForm = new SelectUserForm(this, "register", true); MEMMAN_NEW(selectUserForm); connect(selectUserForm, SIGNAL(selection(list)), this, SLOT(do_phoneRegister(list))); selectUserForm->show(SELECT_REGISTER); } else { gui->action_register(user_list); } } void MphoneForm::do_phoneRegister(list user_list) { ((t_gui *)ui)->action_register(user_list); } void MphoneForm::phoneDeregister() { t_gui *gui = (t_gui *)ui; list user_list = phone->ref_users(); if (user_list.size() > 1) { if (selectUserForm) { MEMMAN_DELETE(selectUserForm); delete (selectUserForm); } selectUserForm = new SelectUserForm(this, "deregister", true); MEMMAN_NEW(selectUserForm); connect(selectUserForm, SIGNAL(selection(list)), this, SLOT(do_phoneDeregister(list))); selectUserForm->show(SELECT_DEREGISTER); } else { gui->action_deregister(user_list, false); } } void MphoneForm::do_phoneDeregister(list user_list) { ((t_gui *)ui)->action_deregister(user_list, false); } void MphoneForm::phoneDeregisterAll() { t_gui *gui = (t_gui *)ui; list user_list = phone->ref_users(); if (user_list.size() > 1) { if (selectUserForm) { MEMMAN_DELETE(selectUserForm); delete (selectUserForm); } selectUserForm = new SelectUserForm(this, "deregister all", true); MEMMAN_NEW(selectUserForm); connect(selectUserForm, SIGNAL(selection(list)), this, SLOT(do_phoneDeregisterAll(list))); selectUserForm->show(SELECT_DEREGISTER_ALL); } else { gui->action_deregister(user_list, true); } } void MphoneForm::do_phoneDeregisterAll(list user_list) { ((t_gui *)ui)->action_deregister(user_list, true); } void MphoneForm::phoneShowRegistrations() { list user_list = phone->ref_users(); ((t_gui *)ui)->action_show_registrations(user_list); } // Show the semi-modal invite window void MphoneForm::phoneInvite(t_user * user_config, const QString &dest, const QString &subject, bool anonymous) { // Seize the line, so no incoming call can take the line if (!((t_gui *)ui)->action_seize()) return; if (inviteForm) { inviteForm->clear(); } else { inviteForm = new InviteForm(this, "invite", true); MEMMAN_NEW(inviteForm); // Initialize the destination history list for (int i = callComboBox->count() - 1; i >= 0; i--) { inviteForm->addToInviteComboBox(callComboBox->text(i)); } connect(inviteForm, SIGNAL(destination(t_user *, const QString &, const t_url &, const QString &, bool)), this, SLOT(do_phoneInvite(t_user *, const QString &, const t_url &, const QString &, bool))); connect(inviteForm, SIGNAL(raw_destination(const QString &)), this, SLOT(addToCallComboBox(const QString &))); } inviteForm->show(user_config, dest, subject, anonymous); updateState(); } void MphoneForm::phoneInvite(const QString &dest, const QString &subject, bool anonymous) { t_user *user = phone->ref_user_profile(userComboBox->currentText().ascii()); if (!user) { log_file->write_report("Cannot find user profile.", "MphoneForm::phoneInvite", LOG_NORMAL, LOG_CRITICAL); return; } phoneInvite(user, dest, subject, anonymous); } void MphoneForm::phoneInvite() { t_user *user = phone->ref_user_profile(userComboBox->currentText().ascii()); if (!user) { log_file->write_report("Cannot find user profile.", "MphoneForm::phoneInvite", LOG_NORMAL, LOG_CRITICAL); return; } phoneInvite(user, "", "", false); } // Execute the invite action. This slot is connected to the destination // signal of the invite window. void MphoneForm::do_phoneInvite(t_user *user_config, const QString &display, const t_url &destination, const QString &subject, bool anonymous) { ((t_gui *)ui)->action_invite(user_config, destination, display.ascii(), subject.ascii(), anonymous); updateState(); } // Redial last call void MphoneForm::phoneRedial(void) { t_url url; string display, subject; t_user *user_config; bool hide_user; if (!ui->get_last_call_info(url, display, subject, &user_config, hide_user)) return; ((t_gui *)ui)->action_invite(user_config, url, display, subject, hide_user); updateState(); } void MphoneForm::phoneAnswer() { ((t_gui *)ui)->action_answer(); updateState(); } // A call can be answered from the systray popup. The user may have // switched lines, the systray popup answer button should answer the // correct line. void MphoneForm::phoneAnswerFromSystrayPopup() { #ifdef HAVE_KDE unsigned short line = ((t_gui *)ui)->get_line_sys_tray_popup(); unsigned short active_line = phone->get_active_line(); if (line != active_line) { ((t_gui *)ui)->action_activate_line(line); } ((t_gui *)ui)->action_answer(); updateState(); #endif } void MphoneForm::phoneBye() { ((t_gui *)ui)->action_bye(); updateState(); } void MphoneForm::phoneReject() { ((t_gui *)ui)->action_reject(); updateState(); } // A call can be rejected from the systray popup. The user may have // switched lines, the systray popup reject button should answer the // correct line. void MphoneForm::phoneRejectFromSystrayPopup() { #ifdef HAVE_KDE unsigned short line = ((t_gui *)ui)->get_line_sys_tray_popup(); ((t_gui *)ui)->action_reject(line); updateState(); #endif } // Show the semi-modal redirect form void MphoneForm::phoneRedirect(const list &contacts) { int active_line = phone->get_active_line(); t_user *user_config = phone->get_line_user(active_line); if (redirectForm) { MEMMAN_DELETE(redirectForm); delete (redirectForm); } redirectForm = new RedirectForm(this, "redirect", true); MEMMAN_NEW(redirectForm); connect(redirectForm, SIGNAL(destinations(const list &)), this, SLOT(do_phoneRedirect(const list &))); redirectForm->show(user_config, contacts); } void MphoneForm::phoneRedirect() { const list l; phoneRedirect(l); } // Execute the redirect action. void MphoneForm::do_phoneRedirect(const list &destinations) { ((t_gui *)ui)->action_redirect(destinations); updateState(); } // Show the semi-modal call transfer window void MphoneForm::phoneTransfer(const string &dest, t_transfer_type transfer_type) { int active_line = phone->get_active_line(); t_user *user_config = phone->get_line_user(active_line); // Hold the call if setting in user profile indicates call hold if (user_config->get_referrer_hold()) { phoneHold(true); } if (transferForm) { MEMMAN_DELETE(transferForm); delete transferForm; } transferForm = new TransferForm(this, "transfer", true); MEMMAN_NEW(transferForm); connect(transferForm, SIGNAL(destination(const t_display_url &, t_transfer_type)), this, SLOT(do_phoneTransfer(const t_display_url &, t_transfer_type))); if (dest.empty() && transfer_type == TRANSFER_BASIC) { // Let form pick a default transfer type based on the current // call status. transferForm->show(user_config); } else { // Set passed destination and transfer type in form transferForm->show(user_config, dest, transfer_type); } updateState(); } void MphoneForm::phoneTransfer() { unsigned short active_line = phone->get_active_line(); unsigned short dummy; if (phone->is_line_transfer_consult(active_line, dummy)) { do_phoneTransferLine(); } else { phoneTransfer("", TRANSFER_BASIC); } } // Execute the transfer action. This slot is connected to the destination // signal of the transfer window. void MphoneForm::do_phoneTransfer(const t_display_url &destination, t_transfer_type transfer_type) { unsigned short active_line; unsigned short other_line; switch (transfer_type) { case TRANSFER_BASIC: ((t_gui *)ui)->action_refer(destination.url, destination.display); break; case TRANSFER_CONSULT: ((t_gui *)ui)->action_setup_consultation_call( destination.url, destination.display); break; case TRANSFER_OTHER_LINE: active_line = phone->get_active_line(); other_line = (active_line == 0 ? 1 : 0); if (phone->get_line_substate(other_line) == LSSUB_ESTABLISHED) { ((t_gui *)ui)->action_refer(active_line, other_line); } else { // The other line was released while the user was entering // the refer-target. t_user *user_config = phone->get_line_user(active_line); if (user_config->get_referrer_hold()) { phoneHold(false); } } break; default: assert(false); } updateState(); } // Transfer the remote party on the held line to the remote party on the // active line. void MphoneForm::do_phoneTransferLine() { unsigned short active_line = phone->get_active_line(); unsigned short line_to_be_transferred; if (!phone->is_line_transfer_consult(active_line, line_to_be_transferred)) { // Somehow the line is not a consultation call. updateState(); return; } ((t_gui *)ui)->action_refer(line_to_be_transferred, active_line); updateState(); } void MphoneForm::phoneHold(bool on) { if (on) { ((t_gui *)ui)->action_hold(); } else { ((t_gui *)ui)->action_retrieve(); } updateState(); } void MphoneForm::phoneConference() { ((t_gui *)ui)->action_conference(); updateState(); } void MphoneForm::phoneMute(bool on) { ((t_gui *)ui)->action_mute(on); updateState(); } void MphoneForm::phoneTermCap(const QString &dest) { // In-dialog OPTIONS request int line = phone->get_active_line(); if (phone->get_line_substate(line) == LSSUB_ESTABLISHED) { ((t_gui *)ui)->action_options(); return; } // Out-of-dialog OPTIONS request if (termCapForm) { MEMMAN_DELETE(termCapForm); delete (termCapForm); } termCapForm = new TermCapForm(this, "termcap", true); MEMMAN_NEW(termCapForm); connect(termCapForm, SIGNAL(destination(t_user *, const t_url &)), this, SLOT(do_phoneTermCap(t_user *, const t_url &))); t_user *user = phone->ref_user_profile(userComboBox->currentText().ascii()); if (!user) { log_file->write_report("Cannot find user profile.", "MphoneForm::phoneTermcap", LOG_NORMAL, LOG_CRITICAL); return; } termCapForm->show(user, dest); } void MphoneForm::phoneTermCap() { phoneTermCap(""); } void MphoneForm::do_phoneTermCap(t_user *user_config, const t_url &destination) { ((t_gui *)ui)->action_options(user_config, destination); } void MphoneForm::phoneDTMF() { if (!dtmfForm) { dtmfForm = new DtmfForm(this); MEMMAN_NEW(dtmfForm); connect(dtmfForm, SIGNAL(digits(const QString &)), this, SLOT(sendDTMF(const QString &))); } dtmfForm->show(); } void MphoneForm::sendDTMF(const QString &digits) { ((t_gui *)ui)->action_dtmf(digits.ascii()); } void MphoneForm::startMessageSession(void) { t_user *user = phone->ref_user_profile(userComboBox->currentText().ascii()); if (!user) { log_file->write_report("Cannot find user profile.", "MphoneForm::startMessageSession", LOG_NORMAL, LOG_CRITICAL); return; } im::t_msg_session *session = new im::t_msg_session(user); MEMMAN_NEW(session); ((t_gui *)ui)->addMessageSession(session); MessageFormView *messageFormView = new MessageFormView(NULL, session); MEMMAN_NEW(messageFormView); messageFormView->show(); } void MphoneForm::startMessageSession(t_buddy *buddy) { t_user *user_config = buddy->get_user_profile(); t_url dest_url(ui->expand_destination(user_config, buddy->get_sip_address())); if (!dest_url.is_valid()) return; string display = buddy->get_name(); // Find an existing session im::t_msg_session *session = ((t_gui *)ui)->getMessageSession(user_config, dest_url, display); if (!session) { // There is no session yet, create one. session = new im::t_msg_session(user_config, t_display_url(dest_url, display)); MEMMAN_NEW(session); ((t_gui *)ui)->addMessageSession(session); MessageFormView *view = new MessageFormView(NULL, session); MEMMAN_NEW(view); view->show(); } } void MphoneForm::phoneConfirmZrtpSas(int line) { ((t_gui *)ui)->action_confirm_zrtp_sas(line); updateState(); } void MphoneForm::phoneConfirmZrtpSas() { ((t_gui *)ui)->action_confirm_zrtp_sas(); updateState(); } void MphoneForm::phoneResetZrtpSasConfirmation(int line) { ((t_gui *)ui)->action_reset_zrtp_sas_confirmation(line); updateState(); } void MphoneForm::phoneResetZrtpSasConfirmation() { ((t_gui *)ui)->action_reset_zrtp_sas_confirmation(); updateState(); } void MphoneForm::phoneEnableZrtp(bool on) { if (on) { ((t_gui *)ui)->action_enable_zrtp(); } else { ((t_gui *)ui)->action_zrtp_request_go_clear(); } updateState(); } void MphoneForm::phoneZrtpGoClearOk(unsigned short line) { ((t_gui *)ui)->action_zrtp_go_clear_ok(line); updateState(); } // Radio button for line 1 changed state void MphoneForm::line1rbChangedState( bool on ) { // If the radio button is switched off, then return, the toggle // on the other line will handle the action if (!on) return; ((t_gui *)ui)->action_activate_line(0); } void MphoneForm::line2rbChangedState( bool on ) { // If the radio button is switched off, then return, the toggle // on the other line will handle the action if (!on) return; ((t_gui *)ui)->action_activate_line(1); } void MphoneForm::actionLine1Toggled( bool on) { if (!on) return; ((t_gui *)ui)->action_activate_line(0); } void MphoneForm::actionLine2Toggled( bool on) { if (!on) return; ((t_gui *)ui)->action_activate_line(1); } // Enable/disable dnd when there is 1 user active void MphoneForm::srvDnd( bool on ) { ((t_gui *)ui)->srv_dnd(phone->ref_users(), on); updateServicesStatus(); } // Enable/disable dnd when there are multiple users active void MphoneForm::srvDnd() { if (selectUserForm) { MEMMAN_DELETE(selectUserForm); delete (selectUserForm); } selectUserForm = new SelectUserForm(this, "dnd", true); MEMMAN_NEW(selectUserForm); connect(selectUserForm, SIGNAL(selection(list)), this, SLOT(do_srvDnd_enable(list))); connect(selectUserForm, SIGNAL(not_selected(list)), this, SLOT(do_srvDnd_disable(list))); selectUserForm->show(SELECT_DND); } void MphoneForm::do_srvDnd_enable(list user_list) { ((t_gui *)ui)->srv_dnd(user_list, true); updateServicesStatus(); } void MphoneForm::do_srvDnd_disable(list user_list) { ((t_gui *)ui)->srv_dnd(user_list, false); updateServicesStatus(); } // Enable/disable auto answer when there is 1 user active void MphoneForm::srvAutoAnswer( bool on ) { ((t_gui *)ui)->srv_auto_answer(phone->ref_users(), on); updateServicesStatus(); } // Enable/disable auto answer when there are multiple users active void MphoneForm::srvAutoAnswer() { if (selectUserForm) { MEMMAN_DELETE(selectUserForm); delete (selectUserForm); } selectUserForm = new SelectUserForm(this, "auto answer", true); MEMMAN_NEW(selectUserForm); connect(selectUserForm, SIGNAL(selection(list)), this, SLOT(do_srvAutoAnswer_enable(list))); connect(selectUserForm, SIGNAL(not_selected(list)), this, SLOT(do_srvAutoAnswer_disable(list))); selectUserForm->show(SELECT_AUTO_ANSWER); } void MphoneForm::do_srvAutoAnswer_enable(list user_list) { ((t_gui *)ui)->srv_auto_answer(user_list, true); updateServicesStatus(); } void MphoneForm::do_srvAutoAnswer_disable(list user_list) { ((t_gui *)ui)->srv_auto_answer(user_list, false); updateServicesStatus(); } void MphoneForm::srvRedirect() { if (!srvRedirectForm) { srvRedirectForm = new SrvRedirectForm(this, "call redirection", true); MEMMAN_NEW(srvRedirectForm); connect(srvRedirectForm, SIGNAL(destinations(t_user *, const list &, const list &, const list &)), this, SLOT(do_srvRedirect(t_user *, const list &, const list &, const list &))); } srvRedirectForm->show(); } void MphoneForm::do_srvRedirect(t_user *user_config, const list &always, const list &busy, const list &noanswer) { // Redirection always if (always.empty()) { ((t_gui *)ui)->srv_disable_cf(user_config, CF_ALWAYS); } else { ((t_gui *)ui)->srv_enable_cf(user_config, CF_ALWAYS, always); } // Redirection busy if (busy.empty()) { ((t_gui *)ui)->srv_disable_cf(user_config, CF_BUSY); } else { ((t_gui *)ui)->srv_enable_cf(user_config, CF_BUSY, busy); } // Redirection no answer if (noanswer.empty()) { ((t_gui *)ui)->srv_disable_cf(user_config, CF_NOANSWER); } else { ((t_gui *)ui)->srv_enable_cf(user_config, CF_NOANSWER, noanswer); } updateServicesStatus(); } void MphoneForm::about() { QString s = sys_config->about(true).c_str(); QMessageBox mbAbout(PRODUCT_NAME, s.replace(' ', " "), QMessageBox::Information, QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton, QMessageBox::NoButton); mbAbout.setIconPixmap(QPixmap::fromMimeSource("twinkle48.png")); mbAbout.exec(); } void MphoneForm::aboutQt() { QMessageBox::aboutQt(this, PRODUCT_NAME); } void MphoneForm::manual() { ((t_gui *)ui)->open_url_in_browser("http://www.twinklephone.com"); } void MphoneForm::editUserProfile() { if (!userProfileForm) { userProfileForm = new UserProfileForm(this, "user profile", true); MEMMAN_NEW(userProfileForm); connect(userProfileForm, SIGNAL(authCredentialsChanged(t_user *, const string&)), this, SLOT(updateAuthCache(t_user *, const string&))); connect(userProfileForm, SIGNAL(stunServerChanged(t_user *)), this, SLOT(updateStunSettings(t_user *))); // MWI settings change triggers an unsubscribe connect(userProfileForm, SIGNAL(mwiChangeUnsubscribe(t_user *)), this, SLOT(unsubscribeMWI(t_user *))); // MWI settings change triggers a subscribe connect(userProfileForm, SIGNAL(mwiChangeSubscribe(t_user *)), this, SLOT(subscribeMWI(t_user *))); } userProfileForm->show(phone->ref_users(), userComboBox->currentText()); } void MphoneForm::editSysSettings() { if (!sysSettingsForm) { sysSettingsForm = new SysSettingsForm(this, "system settings", true); MEMMAN_NEW(sysSettingsForm); connect(sysSettingsForm, SIGNAL(sipUdpPortChanged()), this, SLOT(updateSipUdpPort())); connect(sysSettingsForm, SIGNAL(rtpPortChanged()), this, SLOT(updateRtpPorts())); } sysSettingsForm->show(); } void MphoneForm::selectProfile() { if (!selectProfileForm) { selectProfileForm = new SelectProfileForm(this, "select profile", true); MEMMAN_NEW(selectProfileForm); connect(selectProfileForm, SIGNAL(selection(const list &)), this, SLOT(newUsers(const list &))); connect(selectProfileForm, SIGNAL(profileRenamed()), this, SLOT(updateUserComboBox())); connect(selectProfileForm, SIGNAL(profileRenamed()), this, SLOT(populateBuddyList())); } selectProfileForm->showForm(this); } // A new set of users has been selected. // Remove users from the current user set that are not in the selection. // Add users from the selection that are not in the current set of users. void MphoneForm::newUsers(const list &profiles) { string error_msg; // NOTE: First users must be removed. It could be that a // user profile of an active was renamed. In this case, the user // with the old profile name is first removed and then added again. list user_list = phone->ref_users(); // Remove current users that are not selected anymore. for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if (std::find(profiles.begin(), profiles.end(), (*i)->get_filename().c_str()) == profiles.end()) { // User is not selected anymore. // Unsubscribe MWI if (phone->is_mwi_subscribed(*i)) { phone->pub_unsubscribe_mwi(*i); } // Unpublish presence of user phone->pub_unpublish_presence(*i); // Unsubscribe presence phone->pub_unsubscribe_presence(*i); // Deregister user if (phone->get_is_registered(*i)) { phone->pub_registration(*i, REG_DEREGISTER); } log_file->write_header("MphoneForm::newUsers"); log_file->write_raw("Stop user profile: "); log_file->write_raw((*i)->get_profile_name()); log_file->write_endl(); log_file->write_footer(); phone->remove_phone_user(*(*i)); } } // Determine which users to add list add_profile_list; for (list::const_iterator i = profiles.begin(); i != profiles.end(); i++) { QString profile = (*i).c_str(); // Strip off the .cfg extension profile.truncate(profile.length() - 4); if (!phone->ref_user_profile(profile.ascii())) { add_profile_list.push_back(*i); } } // Add new phone users QProgressDialog progress(tr("Starting user profiles..."), "Abort", add_profile_list.size(), this, "starting user profiles", true); progress.setCaption(PRODUCT_NAME); progress.setMinimumDuration(200); int progressStep = 0; for (list::iterator i = add_profile_list.begin(); i != add_profile_list.end(); i++) { progress.setProgress(progressStep); qApp->processEvents(); if (progress.wasCancelled()) { log_file->write_report("User aborted startup of new users.", "MphoneForm::newUsers"); break; } t_user user_config; // Read user configuration if (user_config.read_config(*i, error_msg)) { t_user *dup_user; log_file->write_header("MphoneForm::newUsers"); log_file->write_raw("Run user profile: "); log_file->write_raw(user_config.get_profile_name()); log_file->write_endl(); log_file->write_footer(); if (phone->add_phone_user(user_config, &dup_user)) { // NAT discovery if (!phone->stun_discover_nat(&user_config, error_msg)) { // Warn user that the STUN settings will not work. ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_WARNING); } // Register at startup if (user_config.get_register_at_startup()) { phone->pub_registration(&user_config, REG_REGISTER, DUR_REGISTRATION(&user_config)); } else { // No registration needed, initialize extensions now. phone->init_extensions(&user_config); } // Extension initialization will be done after // registration succeeded. } else { error_msg = tr("The following profiles are both for user %1").arg(user_config.get_name().c_str()).ascii(); error_msg += '@'; error_msg += user_config.get_domain(); error_msg += ":\n\n"; error_msg += user_config.get_profile_name(); error_msg += "\n"; error_msg += dup_user->get_profile_name(); error_msg += "\n\n"; error_msg += tr("You can only run multiple profiles for different users."); log_file->write_report(error_msg, "MphoneForm::newUsers", LOG_NORMAL, LOG_WARNING); ui->cb_display_msg(error_msg, MSG_WARNING); } } else { log_file->write_report(error_msg, "MphoneForm::newUsers", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(error_msg, MSG_CRITICAL); } progressStep++; } progress.setProgress(add_profile_list.size()); populateBuddyList(); updateUserComboBox(); updateRegStatus(); updateMwi(); updateServicesStatus(); updateSysTrayStatus(); updateMenuStatus(); updateState(); call_history->clear_num_missed_calls(); } void MphoneForm::updateUserComboBox() { QString current_user; if (userComboBox->count() == 0) { // The last used profile current_user = sys_config->get_last_used_profile().c_str(); } else { // Keep the current active profile current_user = userComboBox->currentText(); } ((t_gui *)ui)->fill_user_combo(userComboBox); // If previous selected user is still active, make it the current user for (int i = 0; i < userComboBox->count(); i++) { if (userComboBox->text(i) == current_user) { userComboBox->setCurrentItem(i); } } } void MphoneForm::updateSipUdpPort() { ((t_gui *)ui)->cb_show_msg(sysSettingsForm, tr("You have changed the SIP UDP port. This setting will only become "\ "active when you restart Twinkle.").ascii(), MSG_INFO); } void MphoneForm::updateRtpPorts() { phone->init_rtp_ports(); } void MphoneForm::updateStunSettings(t_user *user_config) { string s; if (!phone->stun_discover_nat(user_config, s)) { // Warn user that the STUN settings will not work. ((t_gui *)ui)->cb_show_msg(this, s, MSG_WARNING); } if (!user_config->get_use_stun()) { // Disable STUN phone->disable_stun(user_config); } // Synchronize the sending of NAT keep alives with the user profile settings. phone->sync_nat_keepalive(user_config); } void MphoneForm::updateAuthCache(t_user *user_config, const string &realm) { phone->remove_cached_credentials(user_config, realm); } void MphoneForm::unsubscribeMWI(t_user *user_config) { phone->pub_unsubscribe_mwi(user_config); } void MphoneForm::subscribeMWI(t_user *user_config) { phone->pub_subscribe_mwi(user_config); } void MphoneForm::viewLog() { if (!logViewForm) { logViewForm = new LogViewForm(NULL); MEMMAN_NEW(logViewForm); } logViewForm->show(); } void MphoneForm::updateLog(bool log_zapped) { if (logViewForm) logViewForm->update(log_zapped); } void MphoneForm::viewHistory() { if (!historyForm) { historyForm = new HistoryForm(NULL); MEMMAN_NEW(historyForm); } connect(historyForm, SIGNAL(call(t_user *, const QString &, const QString &, bool)), this, SLOT(phoneInvite(t_user *, const QString &, const QString &, bool))); historyForm->show(); } void MphoneForm::updateCallHistory() { if (historyForm) historyForm->update(); } t_twinkle_sys_tray *MphoneForm::getSysTray() { return sysTray; } // Execute call directly from the main window (press call button) void MphoneForm::quickCall() { string display, dest_str; t_user *from_user = phone->ref_user_profile( userComboBox->currentText().ascii()); if (!from_user) { log_file->write_report("Cannot find user profile.", "MphoneForm::quickCall", LOG_NORMAL, LOG_CRITICAL); return; } ui->expand_destination(from_user, callComboBox->currentText().stripWhiteSpace().ascii(), display, dest_str); t_url dest(dest_str); if (dest.is_valid()) { QString destination = callComboBox->currentText(); addToCallComboBox(destination); if (inviteForm) inviteForm->addToInviteComboBox(destination); callComboBox->setFocus(); do_phoneInvite(from_user, display.c_str(), dest, "", false); } } // Add a destination to the list of callComboBox void MphoneForm::addToCallComboBox(const QString &destination) { // Remove duplicate entries for (int i = callComboBox->count() - 1; i >= 0; i--) { if (callComboBox->text(i) == destination) { callComboBox->removeItem(i); } } // Add entry callComboBox->insertItem(destination, 0); callComboBox->setCurrentItem(0); // Remove last entry is list exceeds maximum size if (callComboBox->count() > SIZE_REDIAL_LIST) { callComboBox->removeItem(callComboBox->count() - 1); } // Clearing the edit line must be done here as this function is // also called when a call is made through the inviteForm. // The insertItem puts the text also in the edit field. So it must // be cleared here. callComboBox->clearEdit(); } void MphoneForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); getAddressForm->show(); } void MphoneForm::selectedAddress(const QString &address) { callComboBox->setEditText(address); } // Enable/disable the various call widgets void MphoneForm::enableCallOptions(bool enable) { // Enable/disable widgets callInvite->setEnabled(enable); callPushButton->setEnabled(enable); callComboBox->setEnabled(enable); addressToolButton->setEnabled(enable); // Set focus on callComboBox if (enable) { callComboBox->setFocus(); } } void MphoneForm::keyPressEvent(QKeyEvent *e) { if (callPushButton->isEnabled()) { // Quick dial switch (e->key()) { case Qt::Key_Return: case Qt::Key_Enter: quickCall(); break; default: e->ignore(); } } else if (callDTMF->isEnabled()) { // DTMF keys switch (e->key()) { case Qt::Key_1: sendDTMF("1"); break; case Qt::Key_2: case Qt::Key_A: case Qt::Key_B: case Qt::Key_C: sendDTMF("2"); break; case Qt::Key_3: case Qt::Key_D: case Qt::Key_E: case Qt::Key_F: sendDTMF("3"); break; case Qt::Key_4: case Qt::Key_G: case Qt::Key_H: case Qt::Key_I: sendDTMF("4"); break; case Qt::Key_5: case Qt::Key_J: case Qt::Key_K: case Qt::Key_L: sendDTMF("5"); break; case Qt::Key_6: case Qt::Key_M: case Qt::Key_N: case Qt::Key_O: sendDTMF("6"); break; case Qt::Key_7: case Qt::Key_P: case Qt::Key_Q: case Qt::Key_R: case Qt::Key_S: sendDTMF("7"); break; case Qt::Key_8: case Qt::Key_T: case Qt::Key_U: case Qt::Key_V: sendDTMF("8"); break; case Qt::Key_9: case Qt::Key_W: case Qt::Key_X: case Qt::Key_Y: case Qt::Key_Z: sendDTMF("9"); break; case Qt::Key_0: case Qt::Key_Space: sendDTMF("0"); break; case Qt::Key_Asterisk: sendDTMF("*"); break; case Qt::Key_NumberSign: sendDTMF("#"); break; default: e->ignore(); } } else { e->ignore(); } } // QLabels do not have mouse click events. I want the status labels // to be clickable however. Explicitly check here if a status label has // been clicked. void MphoneForm::mouseReleaseEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton && e->type() == QEvent::MouseButtonRelease) { processLeftMouseButtonRelease(e); } else if (e->button() == Qt::RightButton && e->type() == QEvent::MouseButtonRelease) { processRightMouseButtonRelease(e); } else { e->ignore(); } } void MphoneForm::processLeftMouseButtonRelease(QMouseEvent *e) { if (statAaLabel->hasMouse()) { if (phone->ref_users().size() == 1) { bool enable = !serviceAutoAnswer->isOn(); srvAutoAnswer(enable); serviceAutoAnswer->setOn(enable); } else { srvAutoAnswer(); } } else if (statDndLabel->hasMouse()) { if (phone->ref_users().size() == 1) { bool enable = !serviceDnd->isOn(); srvDnd(enable); serviceDnd->setOn(enable); } else { srvDnd(); } } else if (statCfLabel->hasMouse()) { srvRedirect(); } else if (statMWILabel->hasMouse()) { popupMenuVoiceMail(e->globalPos()); } else if (statMissedLabel->hasMouse()) { // Open the history form, when the user clicks on the // missed calls indication. viewHistory(); } else if (statRegLabel->hasMouse()) { // Fetch registration status phoneShowRegistrations(); } else if (crypt1Label->hasMouse()) { processCryptLabelClick(0); } else if (crypt2Label->hasMouse()) { processCryptLabelClick(1); } else { e->ignore(); } } void MphoneForm::processRightMouseButtonRelease(QMouseEvent *e) { e->ignore(); } void MphoneForm::processCryptLabelClick(int line) { t_audio_session *as = phone->get_line(line)->get_audio_session(); if (!as) return; if (as->get_zrtp_sas_confirmed()) { phoneResetZrtpSasConfirmation(line); } else { phoneConfirmZrtpSas(line); } } // Show popup menu to access voice mail void MphoneForm::popupMenuVoiceMail(const QPoint &pos) { QPopupMenu menu(this); QIconSet vmIcon(QPixmap::fromMimeSource("mwi_none16.png")); vmIcon.setPixmap(QPixmap::fromMimeSource("mwi_none16_dis.png"), QIconSet::Automatic, QIconSet::Disabled); listuser_list = phone->ref_users(); map vm; for (list::iterator i = user_list.begin(); i != user_list.end(); ++i) { QString address = (*i)->get_mwi_vm_address().c_str(); QString entry = (*i)->get_profile_name().c_str(); entry += " - "; if (address.isEmpty()) { entry += tr("not provisioned"); } else { entry += address; } int id = menu.insertItem(vmIcon, entry); if (address.isEmpty()) { menu.setItemEnabled(id, false); } vm.insert(make_pair(id, *i)); } int selected; // If multiple profiles are active, then show the popup menu. // If one profile is active, then call voice mail immediately. if (user_list.size() > 1) { selected = menu.exec(pos); if (selected == -1) return; } else { if (vm.begin()->second->get_mwi_vm_address().empty()) { ui->cb_show_msg( tr("You must provision your voice mail address in your " "user profile, before you can access it.").ascii(), MSG_INFO); return; } selected = vm.begin()->first; } // Call can only be made if line is idle int line = phone->get_active_line(); if (phone->get_line_state(line) == LS_BUSY) { ui->cb_show_msg(tr("The line is busy. Cannot access voice mail.").ascii(), MSG_WARNING); return; } t_user *selectedUser = vm[selected]; string display, dest_str; ui->expand_destination(selectedUser, selectedUser->get_mwi_vm_address(), display, dest_str); t_url dest(dest_str); if (dest.is_valid()) { QString destination = selectedUser->get_mwi_vm_address().c_str(); addToCallComboBox(destination); if (inviteForm) inviteForm->addToInviteComboBox(destination); callComboBox->setFocus(); do_phoneInvite(selectedUser, display.c_str(), dest, "", false); } else { QString msg(tr("The voice mail address %1 is an invalid address. " "Please provision a valid address in your user profile.")); ui->cb_show_msg(msg.arg(selectedUser->get_mwi_vm_address().c_str()).ascii(), MSG_CRITICAL); } } void MphoneForm::popupMenuVoiceMail(void) { popupMenuVoiceMail(QCursor::pos()); } void MphoneForm::showDisplay(bool on) { if (on) { displayGroupBox->show(); } else { int hDisplay = displayGroupBox->height(); displayGroupBox->hide(); if (hDisplay < minimumHeight()) { setMinimumHeight(minimumHeight() - hDisplay); } resize(width(), minimumHeight()); } viewDisplay = on; viewDisplayAction->setOn(on); } void MphoneForm::showBuddyList(bool on) { if (on) { buddyListView->show(); } else { buddyListView->hide(); } viewBuddyList = on; viewBuddyListAction->setOn(on); } void MphoneForm::showCompactLineStatus(bool on) { if (on) { int hLabels = fromhead1Label->height() + tohead1Label->height() + subjecthead1Label->height() + fromhead2Label->height() + tohead2Label->height() + subjecthead2Label->height(); fromhead1Label->hide(); tohead1Label->hide(); subjecthead1Label->hide(); from1Label->hide(); to1Label->hide(); subject1Label->hide(); photo1Label->hide(); fromhead2Label->hide(); tohead2Label->hide(); subjecthead2Label->hide(); from2Label->hide(); to2Label->hide(); subject2Label->hide(); photo2Label->hide(); if (hLabels < minimumHeight()) { setMinimumHeight(minimumHeight() - hLabels); } resize(width(), minimumHeight()); } else { fromhead1Label->show(); tohead1Label->show(); subjecthead1Label->show(); from1Label->show(); to1Label->show(); subject1Label->show(); fromhead2Label->show(); tohead2Label->show(); subjecthead2Label->show(); from2Label->show(); to2Label->show(); subject2Label->show(); } viewCompactLineStatus = on; //viewCompactLineStatusAction->setOn(on); } bool MphoneForm::getViewDisplay() { return viewDisplay; } bool MphoneForm::getViewBuddyList() { return viewBuddyList; } bool MphoneForm::getViewCompactLineStatus() { return viewCompactLineStatus; } void MphoneForm::populateBuddyList() { buddyListView->clear(); list user_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); ++i) { t_presence_epa *epa = phone->ref_presence_epa(*i); if (!epa) continue; BLViewUserItem *profileItem = new BLViewUserItem(buddyListView, epa); t_buddy_list *buddy_list = phone->ref_buddy_list(*i); list *buddies = buddy_list->get_records(); for (list::iterator bit = buddies->begin(); bit != buddies->end(); ++bit) { QString name = bit->get_name().c_str(); new BuddyListViewItem(profileItem, &(*bit)); } profileItem->setOpen(true); } } void MphoneForm::showBuddyListPopupMenu(QListViewItem *item, const QPoint &pos) { if (!item) return; BuddyListViewItem *buddyItem = dynamic_cast(item); if (buddyItem) { buddyPopupMenu->popup(pos); } else { buddyListPopupMenu->popup(pos); } } void MphoneForm::doCallBuddy() { QListViewItem *qitem = buddyListView->currentItem(); BuddyListViewItem *item = dynamic_cast(qitem); if (!item) return; t_buddy *buddy = item->get_buddy(); t_user *user_config = buddy->get_user_profile(); phoneInvite(user_config, buddy->get_sip_address().c_str(), "", false); } void MphoneForm::doMessageBuddy(QListViewItem *qitem) { BuddyListViewItem *item = dynamic_cast(qitem); if (!item) return; t_buddy *buddy = item->get_buddy(); startMessageSession(buddy); } void MphoneForm::doMessageBuddy() { QListViewItem *item = buddyListView->currentItem(); doMessageBuddy(item); } void MphoneForm::doEditBuddy() { QListViewItem *qitem = buddyListView->currentItem(); BuddyListViewItem *item = dynamic_cast(qitem); if (!item) return; t_buddy *buddy = item->get_buddy(); BuddyForm *form = new BuddyForm(this, "new_buddy", true, Qt::WDestructiveClose); // Do not call MEMMAN as this form will be deleted automatically. form->showEdit(*buddy); } void MphoneForm::doDeleteBuddy() { QListViewItem *qitem = buddyListView->currentItem(); BuddyListViewItem *item = dynamic_cast(qitem); if (!item) return; t_buddy *buddy = item->get_buddy(); t_buddy_list *buddy_list = buddy->get_buddy_list(); // Delete the list item before deleting the buddy as // deleting the item will detach the item from the buddy. delete item; if (buddy->is_presence_terminated()) { buddy_list->del_buddy(*buddy); } else { buddy->unsubscribe_presence(true); } string err_msg; if (!buddy_list->save(err_msg)) { QString msg = tr("Failed to save buddy list: %1").arg(err_msg.c_str()); ((t_gui *)ui)->cb_show_msg(this, msg.ascii(), MSG_CRITICAL); } } void MphoneForm::doAddBuddy() { QListViewItem *qitem = buddyListView->currentItem(); BLViewUserItem *item = dynamic_cast(qitem); if (!item) return; t_phone_user *pu = item->get_presence_epa()->get_phone_user(); if (!pu) return; t_buddy_list *buddy_list = pu->get_buddy_list(); if (!buddy_list) return; BuddyForm *form = new BuddyForm(this, "new_buddy", true, Qt::WDestructiveClose); // Do not call MEMMAN as this form will be deleted automatically. form->showNew(*buddy_list, item); } void MphoneForm::doAvailabilityOffline() { QListViewItem *qitem = buddyListView->currentItem(); BLViewUserItem *item = dynamic_cast(qitem); if (!item) return; t_phone_user *pu = item->get_presence_epa()->get_phone_user(); if (!pu) return; pu->publish_presence(t_presence_state::ST_BASIC_CLOSED); } void MphoneForm::doAvailabilityOnline() { QListViewItem *qitem = buddyListView->currentItem(); BLViewUserItem *item = dynamic_cast(qitem); if (!item) return; t_phone_user *pu = item->get_presence_epa()->get_phone_user(); if (!pu) return; pu->publish_presence(t_presence_state::ST_BASIC_OPEN); } void MphoneForm::DiamondcardSignUp() { DiamondcardProfileForm *f = new DiamondcardProfileForm(this, "select profile", true, Qt::WDestructiveClose); connect(f, SIGNAL(newDiamondcardProfile(const QString&)), this, SLOT(newDiamondcardUser(const QString &))); f->show(NULL); } void MphoneForm::newDiamondcardUser(const QString &filename) { list profileFilenames; list users = phone->ref_users(); for (list::const_iterator it = users.begin(); it != users.end(); ++it) { t_user *user = *it; profileFilenames.push_back(user->get_filename()); } profileFilenames.push_back(filename.ascii()); newUsers(profileFilenames); } void MphoneForm::DiamondcardAction(t_dc_action action, int userIdx) { list diamondcard_users = diamondcard_get_users(phone); vector v(diamondcard_users.begin(), diamondcard_users.end()); if (userIdx < 0 || (unsigned int)userIdx >= v.size()) return; t_user *user = v[userIdx]; QString url(diamondcard_url(action, user->get_name(), user->get_auth_pass()).c_str()); ((t_gui *)ui)->open_url_in_browser(url); } void MphoneForm::DiamondcardRecharge(int userIdx) { DiamondcardAction(DC_ACT_RECHARGE, userIdx); } void MphoneForm::DiamondcardBalanceHistory(int userIdx) { DiamondcardAction(DC_ACT_BALANCE_HISTORY, userIdx); } void MphoneForm::DiamondcardCallHistory(int userIdx) { DiamondcardAction(DC_ACT_CALL_HISTORY, userIdx); } void MphoneForm::DiamondcardAdminCenter(int userIdx) { DiamondcardAction(DC_ACT_ADMIN_CENTER, userIdx); } twinkle-1.4.2/src/gui/selectnicform.ui.h0000644000175000001440000000544511127714044015116 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void SelectNicForm::init() { idxDefault = -1; } void SelectNicForm::setAsDefault(bool setIp) { #if 0 // DEPRECATED // Only show the information when the default button is // pressed for the first time. if (idxDefault == -1) { QMessageBox::information(this, PRODUCT_NAME, tr( "If you want to remove or " "change the default at a later time, you can do that " "via the system settings.")); } // Store current index as the changeItem method also changes // the current index as a side effect. int idxNewDefault = nicListBox->currentItem(); // Restore pixmap of the old default if (idxDefault != -1) { nicListBox->changeItem( QPixmap::fromMimeSource("kcmpci16.png"), nicListBox->text(idxDefault), idxDefault); } // Set pixmap of the default idxDefault = idxNewDefault; nicListBox->changeItem( QPixmap::fromMimeSource("twinkle16.png"), nicListBox->text(idxDefault), idxDefault); // Write default to system settings int pos = nicListBox->currentText().findRev(':'); if (setIp) { sys_config->set_start_user_host(nicListBox->currentText().mid(pos + 1).ascii()); sys_config->set_start_user_nic(""); } else { sys_config->set_start_user_nic(nicListBox->currentText().left(pos).ascii()); sys_config->set_start_user_host(""); } string error_msg; if (!sys_config->write_config(error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); } #endif } void SelectNicForm::setAsDefaultIp() { setAsDefault(true); } void SelectNicForm::setAsDefaultNic() { setAsDefault(false); } twinkle-1.4.2/src/gui/syssettingsform.ui.h0000644000175000001440000004152111143565666015553 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Indices of categories in the category list box #define idxCatGeneral 0 #define idxCatAudio 1 #define idxCatRingtones 2 #define idxCatAddressBook 3 #define idxCatNetwork 4 #define idxCatLog 5 void SysSettingsForm::init() { // Set toolbutton icons for disabled options. QIconSet i; i = openRingtoneToolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource("fileopen-disabled.png"), QIconSet::Automatic, QIconSet::Disabled); openRingtoneToolButton->setIconSet(i); i = openRingbackToolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource("fileopen-disabled.png"), QIconSet::Automatic, QIconSet::Disabled); openRingbackToolButton->setIconSet(i); QRegExp rxNumber("[0-9]+"); maxUdpSizeLineEdit->setValidator(new QRegExpValidator(rxNumber, this)); maxTcpSizeLineEdit->setValidator(new QRegExpValidator(rxNumber, this)); } void SysSettingsForm::showCategory( int index ) { if (index == idxCatGeneral) { settingsWidgetStack->raiseWidget(pageGeneral); } else if (index == idxCatAudio) { settingsWidgetStack->raiseWidget(pageAudio); } else if (index == idxCatRingtones) { settingsWidgetStack->raiseWidget(pageRingtones); } else if (index == idxCatAddressBook) { settingsWidgetStack->raiseWidget(pageAddressBook); } else if (index == idxCatNetwork) { settingsWidgetStack->raiseWidget(pageNetwork); } else if (index == idxCatLog) { settingsWidgetStack->raiseWidget(pageLog); } } string SysSettingsForm::comboItem2audio_dev(QString item, QLineEdit *qleOther, bool playback) { if (item == QString("ALSA: ") + DEV_OTHER) { if (qleOther->text().isEmpty()) return ""; return (QString(PFX_ALSA) + qleOther->text()).ascii(); } if (item == QString("OSS: ") + DEV_OTHER) { if (qleOther->text().isEmpty()) return ""; return (QString(PFX_OSS) + qleOther->text()).ascii(); } list &list_audio_dev = (playback ? list_audio_playback_dev : list_audio_capture_dev); for (list::iterator i = list_audio_dev.begin(); i != list_audio_dev.end(); i++) { if (i->get_description() == item.ascii()) { return i->get_settings_value(); } } return ""; } void SysSettingsForm::populateComboBox(QComboBox *cb, const QString &s) { for (int i = 0; i < cb->count(); i++) { if (cb->text(i) == s) { cb->setCurrentItem(i); return; } } } void SysSettingsForm::populate() { QString msg; int idx; // Select the Audio category categoryListBox->setSelected(idxCatGeneral, true); settingsWidgetStack->raiseWidget(pageGeneral); // Set focus on first field categoryListBox->setFocus(); // Audio settings list_audio_playback_dev = sys_config->get_audio_devices(true); list_audio_capture_dev = sys_config->get_audio_devices(false); ringtoneComboBox->clear(); speakerComboBox->clear(); micComboBox->clear(); bool devRingtoneFound = false; bool devSpeakerFound = false; bool devMicFound = false; // Playback devices idx = 0; for (list::iterator i = list_audio_playback_dev.begin(); i != list_audio_playback_dev.end(); i++, idx++) { string item = i->get_description(); ringtoneComboBox->insertItem(QString(item.c_str())); speakerComboBox->insertItem(QString(item.c_str())); // Select audio device if (sys_config->get_dev_ringtone().device == i->device) { ringtoneComboBox->setCurrentItem(idx); otherRingtoneLineEdit->clear(); devRingtoneFound = true; } if (sys_config->get_dev_speaker().device == i->device) { speakerComboBox->setCurrentItem(idx); otherSpeakerLineEdit->clear(); devSpeakerFound = true; } // Determine index for other non-standard device if (i->device == DEV_OTHER) { if (i->type == t_audio_device::ALSA) { idxOtherPlaybackDevAlsa = idx; } else { idxOtherPlaybackDevOss = idx; } } } // Check for non-standard audio devices if (!devRingtoneFound) { t_audio_device dev = sys_config->get_dev_ringtone(); otherRingtoneLineEdit->setText(dev.device.c_str()); ringtoneComboBox->setCurrentItem( (dev.type == t_audio_device::ALSA ? idxOtherPlaybackDevAlsa : idxOtherPlaybackDevOss)); } if (!devSpeakerFound) { t_audio_device dev = sys_config->get_dev_speaker(); otherSpeakerLineEdit->setText(dev.device.c_str()); speakerComboBox->setCurrentItem( (dev.type == t_audio_device::ALSA ? idxOtherPlaybackDevAlsa : idxOtherPlaybackDevOss)); } // Capture device idx = 0; for (list::iterator i = list_audio_capture_dev.begin(); i != list_audio_capture_dev.end(); i++, idx++) { string item = i->get_description(); micComboBox->insertItem(QString(item.c_str())); // Select audio device if (sys_config->get_dev_mic().device == i->device) { micComboBox->setCurrentItem(idx); otherMicLineEdit->clear(); devMicFound = true; } // Determine index for other non-standard device if (i->device == DEV_OTHER) { if (i->type == t_audio_device::ALSA) { idxOtherCaptureDevAlsa = idx; } else { idxOtherCaptureDevOss = idx; } } } // Check for non-standard audio devices if (!devMicFound) { t_audio_device dev = sys_config->get_dev_mic(); otherMicLineEdit->setText(dev.device.c_str()); micComboBox->setCurrentItem( (dev.type == t_audio_device::ALSA ? idxOtherCaptureDevAlsa : idxOtherCaptureDevOss)); } // Enable/disable line edit for non-standard device devRingtoneSelected(ringtoneComboBox->currentItem()); devSpeakerSelected(speakerComboBox->currentItem()); devMicSelected(micComboBox->currentItem()); validateAudioCheckBox->setChecked(sys_config->get_validate_audio_dev()); populateComboBox(ossFragmentComboBox, QString::number(sys_config->get_oss_fragment_size())); populateComboBox(alsaPlayPeriodComboBox, QString::number(sys_config->get_alsa_play_period_size())); populateComboBox(alsaCapturePeriodComboBox, QString::number(sys_config->get_alsa_capture_period_size())); // Log settings logMaxSizeSpinBox->setValue(sys_config->get_log_max_size()); logDebugCheckBox->setChecked(sys_config->get_log_show_debug()); logSipCheckBox->setChecked(sys_config->get_log_show_sip()); logStunCheckBox->setChecked(sys_config->get_log_show_stun()); logMemoryCheckBox->setChecked(sys_config->get_log_show_memory()); // General settings guiUseSystrayCheckBox->setChecked(sys_config->get_gui_use_systray()); guiHideCheckBox->setChecked(sys_config->get_gui_hide_on_close()); guiHideCheckBox->setEnabled(sys_config->get_gui_use_systray()); // Call history histSizeSpinBox->setValue(sys_config->get_ch_max_size()); // Auto show on incoming call autoShowCheckBox->setChecked(sys_config->get_gui_auto_show_incoming()); autoShowTimeoutSpinBox->setValue(sys_config->get_gui_auto_show_timeout()); // Services callWaitingCheckBox->setChecked(sys_config->get_call_waiting()); hangupBothCheckBox->setChecked(sys_config->get_hangup_both_3way()); // Startup settings startHiddenCheckBox->setChecked(sys_config->get_start_hidden()); QStringList profiles; if (!SelectProfileForm::getUserProfiles(profiles, msg)) { ((t_gui *)ui)->cb_show_msg(this, msg.ascii(), MSG_CRITICAL); } profileListView->clear(); for (QStringList::Iterator i = profiles.begin(); i != profiles.end(); i++) { // Strip off the .cfg suffix QString profile = *i; profile.truncate(profile.length() - 4); QCheckListItem *item = new QCheckListItem(profileListView, profile, QCheckListItem::CheckBox); item->setPixmap(0, QPixmap::fromMimeSource("penguin-small.png")); list l = sys_config->get_start_user_profiles(); if (std::find(l.begin(), l.end(), profile.ascii()) != l.end()) { item->setOn(true); } } // Web browser command browserLineEdit->setText(sys_config->get_gui_browser_cmd().c_str()); // Network settings sipUdpPortSpinBox->setValue(sys_config->get_config_sip_port()); rtpPortSpinBox->setValue(sys_config->get_rtp_port()); maxUdpSizeLineEdit->setText(QString::number(sys_config->get_sip_max_udp_size())); maxTcpSizeLineEdit->setText(QString::number(sys_config->get_sip_max_tcp_size())); // Ring tone settings playRingtoneCheckBox->setChecked(sys_config->get_play_ringtone()); defaultRingtoneRadioButton->setChecked(sys_config->get_ringtone_file().empty()); customRingtoneRadioButton->setChecked(!sys_config->get_ringtone_file().empty()); ringtoneLineEdit->setText(sys_config->get_ringtone_file().c_str()); defaultRingtoneRadioButton->setEnabled(sys_config->get_play_ringtone()); customRingtoneRadioButton->setEnabled(sys_config->get_play_ringtone()); ringtoneLineEdit->setEnabled(!sys_config->get_ringtone_file().empty()); openRingtoneToolButton->setEnabled(!sys_config->get_ringtone_file().empty()); playRingbackCheckBox->setChecked(sys_config->get_play_ringback()); defaultRingbackRadioButton->setChecked(sys_config->get_ringback_file().empty()); customRingbackRadioButton->setChecked(!sys_config->get_ringback_file().empty()); ringbackLineEdit->setText(sys_config->get_ringback_file().c_str()); defaultRingbackRadioButton->setEnabled(sys_config->get_play_ringback()); customRingbackRadioButton->setEnabled(sys_config->get_play_ringback()); ringbackLineEdit->setEnabled(!sys_config->get_ringback_file().empty()); openRingbackToolButton->setEnabled(!sys_config->get_ringback_file().empty()); // Address book settings abLookupNameCheckBox->setChecked(sys_config->get_ab_lookup_name()); abOverrideDisplayCheckBox->setChecked(sys_config->get_ab_override_display()); abOverrideDisplayCheckBox->setEnabled(sys_config->get_ab_lookup_name()); abLookupPhotoCheckBox->setChecked(sys_config->get_ab_lookup_photo()); } void SysSettingsForm::validate() { bool conversion_ok = false; unsigned short sip_max_udp_size = maxUdpSizeLineEdit->text().toUShort(&conversion_ok); if (!conversion_ok) sip_max_udp_size = sys_config->get_sip_max_udp_size(); unsigned long sip_max_tcp_size = maxTcpSizeLineEdit->text().toULong(&conversion_ok); if (!conversion_ok) sip_max_tcp_size = sys_config->get_sip_max_tcp_size(); // Audio string dev; dev = comboItem2audio_dev(ringtoneComboBox->currentText(), otherRingtoneLineEdit, true); if (dev != "") sys_config->set_dev_ringtone(sys_config->audio_device(dev)); dev = comboItem2audio_dev(speakerComboBox->currentText(), otherSpeakerLineEdit, true); if (dev != "") sys_config->set_dev_speaker(sys_config->audio_device(dev)); dev = comboItem2audio_dev(micComboBox->currentText(), otherMicLineEdit, false); if (dev != "") sys_config->set_dev_mic(sys_config->audio_device(dev)); sys_config->set_validate_audio_dev(validateAudioCheckBox->isChecked()); sys_config->set_oss_fragment_size( ossFragmentComboBox->currentText().toInt()); sys_config->set_alsa_play_period_size( alsaPlayPeriodComboBox->currentText().toInt()); sys_config->set_alsa_capture_period_size( alsaCapturePeriodComboBox->currentText().toInt()); // Log sys_config->set_log_max_size(logMaxSizeSpinBox->value()); sys_config->set_log_show_debug(logDebugCheckBox->isChecked()); sys_config->set_log_show_sip(logSipCheckBox->isChecked()); sys_config->set_log_show_stun(logStunCheckBox->isChecked()); sys_config->set_log_show_memory(logMemoryCheckBox->isChecked()); // General sys_config->set_gui_use_systray(guiUseSystrayCheckBox->isChecked()); sys_config->set_gui_hide_on_close(guiHideCheckBox->isChecked()); // Auto show on incoming call sys_config->set_gui_auto_show_incoming(autoShowCheckBox->isChecked()); sys_config->set_gui_auto_show_timeout(autoShowTimeoutSpinBox->value()); // Call history sys_config->set_ch_max_size(histSizeSpinBox->value()); // Services sys_config->set_call_waiting(callWaitingCheckBox->isChecked()); sys_config->set_hangup_both_3way(hangupBothCheckBox->isChecked()); // Startup sys_config->set_start_hidden(startHiddenCheckBox->isChecked() && guiUseSystrayCheckBox->isChecked()); list start_user_profiles; QListViewItemIterator i(profileListView, QListViewItemIterator::Checked); while (i.current()) { QCheckListItem *item = (QCheckListItem *)i.current(); start_user_profiles.push_back(item->text().ascii()); i++; } sys_config->set_start_user_profiles(start_user_profiles); // Web browser command sys_config->set_gui_browser_cmd(browserLineEdit->text().stripWhiteSpace().ascii()); // Network if (sys_config->get_config_sip_port() != sipUdpPortSpinBox->value()) { sys_config->set_config_sip_port(sipUdpPortSpinBox->value()); emit sipUdpPortChanged(); } if (sys_config->get_rtp_port() != rtpPortSpinBox->value()) { sys_config->set_rtp_port(rtpPortSpinBox->value()); emit rtpPortChanged(); } sys_config->set_sip_max_udp_size(sip_max_udp_size); sys_config->set_sip_max_tcp_size(sip_max_tcp_size); // Ring tones sys_config->set_play_ringtone(playRingtoneCheckBox->isChecked()); if (sys_config->get_play_ringtone()) { if (defaultRingtoneRadioButton->isOn()) { sys_config->set_ringtone_file(""); } else { sys_config->set_ringtone_file(ringtoneLineEdit-> text().stripWhiteSpace().ascii()); } } else { sys_config->set_ringtone_file(""); } sys_config->set_play_ringback(playRingbackCheckBox->isChecked()); if (sys_config->get_play_ringback()) { if (defaultRingbackRadioButton->isOn()) { sys_config->set_ringback_file(""); } else { sys_config->set_ringback_file(ringbackLineEdit-> text().stripWhiteSpace().ascii()); } } else { sys_config->set_ringback_file(""); } // Address book settings sys_config->set_ab_lookup_name(abLookupNameCheckBox->isChecked()); sys_config->set_ab_override_display(abOverrideDisplayCheckBox->isChecked()); sys_config->set_ab_lookup_photo(abLookupPhotoCheckBox->isChecked()); // Save user config string error_msg; if (!sys_config->write_config(error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); return; } accept(); } void SysSettingsForm::show() { populate(); QDialog::show(); } int SysSettingsForm::exec() { populate(); return QDialog::exec(); } void SysSettingsForm::chooseRingtone() { QString file = QFileDialog::getOpenFileName( ((t_gui *)ui)->get_last_file_browse_path(), tr("Ring tones", "Description of .wav files in file dialog").append(" (*.wav)"), this, "ring tone file dialog", tr("Choose ring tone")); if (!file.isEmpty()) { ringtoneLineEdit->setText(file); ((t_gui *)ui)->set_last_file_browse_path(QFileInfo(file).dirPath(true)); } } void SysSettingsForm::chooseRingback() { QString file = QFileDialog::getOpenFileName( ((t_gui *)ui)->get_last_file_browse_path(), tr("Ring back tones", "Description of .wav files in file dialog").append(" (*.wav)"), this, "ring back file dialog", tr("Choose ring back tone")); if (!file.isEmpty()) { ringbackLineEdit->setText(file); ((t_gui *)ui)->set_last_file_browse_path(QFileInfo(file).dirPath(true)); } } void SysSettingsForm::devRingtoneSelected(int idx) { bool b = (idx == idxOtherPlaybackDevAlsa || idx == idxOtherPlaybackDevOss); otherRingtoneTextLabel->setEnabled(b); otherRingtoneLineEdit->setEnabled(b); } void SysSettingsForm::devSpeakerSelected(int idx) { bool b = (idx == idxOtherPlaybackDevAlsa || idx == idxOtherPlaybackDevOss); otherSpeakerTextLabel->setEnabled(b); otherSpeakerLineEdit->setEnabled(b); } void SysSettingsForm::devMicSelected(int idx) { bool b = (idx == idxOtherCaptureDevAlsa || idx == idxOtherCaptureDevOss); otherMicTextLabel->setEnabled(b); otherMicLineEdit->setEnabled(b); } void SysSettingsForm::playRingToneCheckBoxToggles(bool on) { if (on) { ringtoneLineEdit->setEnabled(customRingtoneRadioButton->isChecked()); } else { ringtoneLineEdit->setEnabled(false); } } void SysSettingsForm::playRingBackToneCheckBoxToggles(bool on) { if (on) { ringbackLineEdit->setEnabled(customRingbackRadioButton->isChecked()); } else { ringbackLineEdit->setEnabled(false); } } twinkle-1.4.2/src/gui/numberconversionform.ui.h0000644000175000001440000000514111127714044016534 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void NumberConversionForm::init() { QRegExp rxNoAtSign("[^@]*"); exprLineEdit->setValidator(new QRegExpValidator(rxNoAtSign, this)); replaceLineEdit->setValidator(new QRegExpValidator(rxNoAtSign, this)); } int NumberConversionForm::exec(QString &expr, QString &replace) { exprLineEdit->setText(expr); replaceLineEdit->setText(replace); int retval = QDialog::exec(); if (retval == QDialog::Accepted) { expr = exprLineEdit->text(); replace = replaceLineEdit->text(); } return retval; } void NumberConversionForm::validate() { QString expr = exprLineEdit->text(); QString replace = replaceLineEdit->text(); if (expr.isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("Match expression may not be empty.").ascii(), MSG_CRITICAL); exprLineEdit->setFocus(); exprLineEdit->selectAll(); return; } if (replace.isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("Replace value may not be empty.").ascii(), MSG_CRITICAL); replaceLineEdit->setFocus(); replaceLineEdit->selectAll(); return; } try { boost::regex re(expr.ascii()); } catch (boost::bad_expression) { ((t_gui *)ui)->cb_show_msg(this, tr("Invalid regular expression.").ascii(), MSG_CRITICAL); exprLineEdit->setFocus(); return; } accept(); } twinkle-1.4.2/src/gui/selectuserform.ui.h0000644000175000001440000000771311134650164015323 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void SelectUserForm::init() { // Disable sorting userListView->setSorting(-1); } void SelectUserForm::show(t_select_purpose purpose) { QString title, msg_purpose; // Set dialog caption and purpose title = PRODUCT_NAME; title += " - "; switch (purpose) { case SELECT_REGISTER: title.append(tr("Register")); msg_purpose = tr("Select users that you want to register."); break; case SELECT_DEREGISTER: title.append(tr("Deregister")); msg_purpose = tr("Select users that you want to deregister."); break; case SELECT_DEREGISTER_ALL: title.append(tr("Deregister all devices")); msg_purpose = tr("Select users for which you want to deregister all devices."); break; case SELECT_DND: title.append(tr("Do not disturb")); msg_purpose = tr("Select users for which you want to enable 'do not disturb'."); break; case SELECT_AUTO_ANSWER: title.append(tr("Auto answer")); msg_purpose = tr("Select users for which you want to enable 'auto answer'."); break; default: assert(false); } setCaption(title); purposeTextLabel->setText(msg_purpose); // Fill list view list user_list = phone->ref_users(); for (list::reverse_iterator i = user_list.rbegin(); i != user_list.rend(); i++) { QCheckListItem *item = new QCheckListItem(userListView, (*i)->get_profile_name().c_str(), QCheckListItem::CheckBox); switch (purpose) { case SELECT_DND: item->setOn(phone->ref_service(*i)->is_dnd_active()); break; case SELECT_AUTO_ANSWER: item->setOn(phone->ref_service(*i)->is_auto_answer_active()); break; default: break; } } QDialog::show(); } void SelectUserForm::validate() { list selected_list, not_selected_list; QListViewItemIterator i(userListView); while (i.current()) { QCheckListItem *item = (QCheckListItem *)(i.current()); if (item->isOn()) { selected_list.push_back(phone-> ref_user_profile(item->text().ascii())); } else { not_selected_list.push_back(phone-> ref_user_profile(item->text().ascii())); } i++; } emit (selection(selected_list)); emit (not_selected(not_selected_list)); accept(); } void SelectUserForm::selectAll() { QListViewItemIterator i(userListView); while (i.current()) { QCheckListItem *item = (QCheckListItem *)(i.current()); item->setOn(true); i++; } } void SelectUserForm::clearAll() { QListViewItemIterator i(userListView); while (i.current()) { QCheckListItem *item = (QCheckListItem *)(i.current()); item->setOn(false); i++; } } void SelectUserForm::toggle(QListViewItem *item) { QCheckListItem *checkItem = (QCheckListItem *)item; checkItem->setOn(!checkItem->isOn()); } twinkle-1.4.2/src/gui/historylistview.h0000644000175000001440000000314611127714044015131 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _HISTORYLISTVIEW_H #define _HISTORYLISTVIEW_H #include #include "qlistview.h" #include "qpainter.h" #include "call_history.h" #include "user.h" // Columns of the history list view #define HISTCOL_TIMESTAMP 0 #define HISTCOL_DIRECTION 1 #define HISTCOL_FROMTO 2 #define HISTCOL_SUBJECT 3 #define HISTCOL_STATUS 4 class HistoryListViewItem : public QListViewItem { private: t_call_record call_record; time_t last_viewed; public: HistoryListViewItem( QListView * parent, const t_call_record &cr, t_user *user_config, time_t _last_viewed); void paintCell(QPainter *painter, const QColorGroup &cg, int column, int width, int align); int compare ( QListViewItem * i, int col, bool ascending ) const; time_t get_time_start(void) const; t_call_record get_call_record(void) const; }; #endif twinkle-1.4.2/src/gui/termcapform.ui0000644000175000001440000002173211131206176014344 00000000000000 TermCapForm TermCapForm 0 0 581 168 5 5 0 0 Twinkle - Terminal Capabilities unnamed layout53 unnamed fromTextLabel &From: fromComboBox fromComboBox 7 0 0 0 termCapGroupBox Get terminal capabilities of unnamed partyTextLabel &To: partyLineEdit partyLineEdit The address that you want to query for capabilities (OPTION request). This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. addressToolButton TabFocus F10 kontact_contacts.png Address book Select an address from the address book. spacer13 Vertical Expanding 20 16 layout15 unnamed spacer12 Horizontal Expanding 131 20 okPushButton &OK true cancelPushButton &Cancel cancelPushButton clicked() TermCapForm reject() okPushButton clicked() TermCapForm validate() addressToolButton clicked() TermCapForm showAddressBook() partyLineEdit addressToolButton okPushButton cancelPushButton fromComboBox gui.h audits/memman.h sockets/url.h getaddressform.h user.h phone.h termcapform.ui.h extern t_phone *phone; GetAddressForm *getAddressForm; destination(t_user *, const t_url &) show( t_user * user_config, const QString & dest ) validate() showAddressBook() selectedAddress( const QString & address ) init() destroy() twinkle-1.4.2/src/gui/addresslistviewitem.cpp0000644000175000001440000000271511127714053016270 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "addresslistviewitem.h" // Columns #define COL_ADDR_NAME 0 #define COL_ADDR_PHONE 1 #define COL_ADDR_REMARK 2 AddressListViewItem::AddressListViewItem(QListView *parent, const t_address_card &card) : QListViewItem(parent, card.get_display_name().c_str(), card.sip_address.c_str(), card.remark.c_str()), address_card(card) {} t_address_card AddressListViewItem::getAddressCard(void) const { return address_card; } void AddressListViewItem::update(const t_address_card &card) { address_card = card; setText(COL_ADDR_NAME, card.get_display_name().c_str()); setText(COL_ADDR_PHONE, card.sip_address.c_str()); setText(COL_ADDR_REMARK, card.remark.c_str()); } twinkle-1.4.2/src/gui/historyform.ui.h0000644000175000001440000002430011150240000014613 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void HistoryForm::init() { historyListView->setSorting(HISTCOL_TIMESTAMP, false); historyListView->setColumnWidthMode(HISTCOL_FROMTO, QListView::Manual); historyListView->setColumnWidth(HISTCOL_FROMTO, 200); historyListView->setColumnWidthMode(HISTCOL_SUBJECT, QListView::Manual); historyListView->setColumnWidth(HISTCOL_SUBJECT, 200); inCheckBox->setChecked(true); outCheckBox->setChecked(true); successCheckBox->setChecked(true); missedCheckBox->setChecked(true); profileCheckBox->setChecked(true); timeLastViewed = phone->get_startup_time(); QIconSet inviteIcon(QPixmap::fromMimeSource("invite.png")); QIconSet deleteIcon(QPixmap::fromMimeSource("editdelete.png")); histPopupMenu = new QPopupMenu(this); MEMMAN_NEW(histPopupMenu); itemCall = histPopupMenu->insertItem(inviteIcon, tr("Call..."), this, SLOT(call())); histPopupMenu->insertItem(deleteIcon, tr("Delete"), this, SLOT(deleteEntry())); } void HistoryForm::destroy() { MEMMAN_DELETE(histPopupMenu); delete histPopupMenu; } void HistoryForm::loadHistory() { // Create list of all active profile names QStringList profile_name_list; listuser_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { profile_name_list.append((*i)->get_profile_name().c_str()); } // Fill the history table unsigned long numberOfCalls = 0; unsigned long totalCallDuration = 0; unsigned long totalConversationDuration = 0; historyListView->clear(); list history; call_history->get_history(history); for (list::iterator i = history.begin(); i != history.end(); i++) { if (i->direction == t_call_record::DIR_IN && !inCheckBox->isChecked()) { continue; } if (i->direction == t_call_record::DIR_OUT && !outCheckBox->isChecked()) { continue; } if (i->invite_resp_code < 300 && !successCheckBox->isChecked()) { continue; } if (i->invite_resp_code >= 300 && !missedCheckBox->isChecked()) { continue; } if (!profile_name_list.contains(i->user_profile.c_str()) && profileCheckBox->isChecked()) { continue; } numberOfCalls++; // Calculate total duration totalCallDuration += i->time_end - i->time_start; if (i->time_answer != 0) { totalConversationDuration += i->time_end - i->time_answer; } t_user *user_config = phone->ref_user_profile(i->user_profile); // If the user profile is not active, then use the // first user profile for formatting if (!user_config) { user_config = phone->ref_users().front(); } new HistoryListViewItem(historyListView, *i, user_config, timeLastViewed); } numberCallsValueTextLabel->setText(QString().setNum(numberOfCalls)); // Total call duration formatting QString durationText = duration2str(totalCallDuration).c_str(); durationText += " ("; durationText += tr("conversation"); durationText += ": "; durationText += duration2str(totalConversationDuration).c_str(); durationText += ")"; totalDurationValueTextLabel->setText(durationText); // Make the first entry the selected entry. QListViewItem *first = historyListView->firstChild(); if (first) { historyListView->setSelected(first, true); showCallDetails(first); } else { cdrTextEdit->clear(); } } // Update history when triggered by a call back function on the user // interface. void HistoryForm::update() { // There is no need to update the history when the window is // hidden. if (isShown()) loadHistory(); } void HistoryForm::show() { if (isShown()) { raise(); setActiveWindow(); return; } loadHistory(); QDialog::show(); raise(); } void HistoryForm::closeEvent( QCloseEvent *e ) { struct timeval t; gettimeofday(&t, NULL); timeLastViewed = t.tv_sec; // If Twinkle is terminated while the history window is // shown, then the call_history object is destroyed, before this // window is closed. if (call_history) { call_history->clear_num_missed_calls(); } QDialog::closeEvent(e); } void HistoryForm::showCallDetails(QListViewItem *item) { QString s; t_call_record cr = ((HistoryListViewItem *)item)->get_call_record(); cdrTextEdit->clear(); t_user *user_config = phone->ref_user_profile(cr.user_profile); // If the user profile is not active, then use the // first user profile for formatting if (!user_config) { user_config = phone->ref_users().front(); } s = ""; // Left column: header names s += ""; // Right column: values s += ""; s += "
"; s += tr("Call start:") + "
"; s += tr("Call answer:") + "
"; s += tr("Call end:") + "
"; s += tr("Call duration:") + "
"; s += tr("Direction:") + "
"; s += tr("From:") + "
"; s += tr("To:") + "
"; if (cr.reply_to_uri.is_valid()) s += tr("Reply to:") + "
"; if (cr.referred_by_uri.is_valid()) s += tr("Referred by:") + "
"; s += tr("Subject:") + "
"; s += tr("Released by:") + "
"; s += tr("Status:") + "
"; if (!cr.far_end_device.empty()) s += tr("Far end device:") + "
"; s += tr("User profile:"); s += "
"; s += time2str(cr.time_start, "%d %b %Y %H:%M:%S").c_str(); s += "
"; if (cr.time_answer != 0) { s += time2str(cr.time_answer, "%d %b %Y %H:%M:%S").c_str(); } s += "
"; s += time2str(cr.time_end, "%d %b %Y %H:%M:%S").c_str(); s += "
"; s += duration2str((unsigned long)(cr.time_end - cr.time_start)).c_str(); if (cr.time_answer != 0) { s += " ("; s += tr("conversation"); s += ": "; s += duration2str((unsigned long)(cr.time_end - cr.time_answer)).c_str(); s += ")"; } s += "
"; s += cr.get_direction().c_str(); s += "
"; s += str2html(ui->format_sip_address(user_config, cr.from_display, cr.from_uri).c_str()); if (cr.from_organization != "") { s += ", "; s += str2html(cr.from_organization.c_str()); } s += "
"; s += str2html(ui->format_sip_address(user_config, cr.to_display, cr.to_uri).c_str()); if (cr.to_organization != "") { s += ", "; s += str2html(cr.to_organization.c_str()); } s += "
"; if (cr.reply_to_uri.is_valid()) { s += str2html(ui->format_sip_address(user_config, cr.reply_to_display, cr.reply_to_uri).c_str()); s += "
"; } if (cr.referred_by_uri.is_valid()) { s += str2html(ui->format_sip_address(user_config, cr.referred_by_display, cr.referred_by_uri).c_str()); s += "
"; } s += str2html(cr.subject.c_str()); s += "
"; s += cr.get_rel_cause().c_str(); s += "
"; s += int2str(cr.invite_resp_code).c_str(); s += ' '; s += str2html(cr.invite_resp_reason.c_str()); s += "
"; if (!cr.far_end_device.empty()) { s += str2html(cr.far_end_device.c_str()); s += "
"; } s += str2html(cr.user_profile.c_str()); s += "
"; cdrTextEdit->setText(s); } void HistoryForm::popupMenu(QListViewItem *item, const QPoint &pos) { if (!item) return; HistoryListViewItem *histItem = dynamic_cast(item); if (!histItem) return; t_call_record cr = histItem->get_call_record(); // An anonymous caller cannot be called bool canCall = !(cr.direction == t_call_record::DIR_IN && cr.from_uri.encode() == ANONYMOUS_URI); histPopupMenu->setItemEnabled(itemCall, canCall); histPopupMenu->popup(pos); } void HistoryForm::call(QListViewItem *item) { if (!item) return; HistoryListViewItem *histItem = (HistoryListViewItem *)item; t_call_record cr = histItem->get_call_record(); t_user *user_config = phone->ref_user_profile(cr.user_profile); // If the user profile is not active, then use the first profile if (!user_config) { user_config = phone->ref_users().front(); } // Determine subject QString subject; if (cr.direction == t_call_record::DIR_IN) { if (!cr.subject.empty()) { if (cr.subject.substr(0, tr("Re:").length()) != tr("Re:").ascii()) { subject = tr("Re:").append(" "); subject += cr.subject.c_str(); } else { subject = cr.subject.c_str(); } } } else { subject = cr.subject.c_str(); } // Send call signal if (cr.direction == t_call_record::DIR_IN && cr.reply_to_uri.is_valid()) { // Call to the Reply-To contact emit call(user_config, ui->format_sip_address(user_config, cr.reply_to_display, cr.reply_to_uri).c_str(), subject, false); } else { // For incoming calls, call to the From contact // For outgoing calls, call to the To contact bool hide_user = false; if (cr.direction == t_call_record::DIR_OUT && cr.from_uri.encode() == ANONYMOUS_URI) { hide_user = true; } emit call(user_config, item->text(HISTCOL_FROMTO), subject, hide_user); } } void HistoryForm::call(void) { QListViewItem *item = historyListView->currentItem(); if (item) call(item); } void HistoryForm::deleteEntry(void) { QListViewItem *item = historyListView->currentItem(); HistoryListViewItem *histItem = dynamic_cast(item); if (!histItem) return; call_history->delete_call_record(histItem->get_call_record().get_id()); } void HistoryForm::clearHistory() { call_history->clear(); } twinkle-1.4.2/src/gui/inviteform.ui.h0000644000175000001440000001032611127714045014436 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void InviteForm::init() { getAddressForm = 0; // Set toolbutton icons for disabled options. setDisabledIcon(addressToolButton, "kontact_contacts-disabled.png"); // A QComboBox accepts a new line through copy/paste. QRegExp rxNoNewLine("[^\\n\\r]*"); inviteComboBox->setValidator(new QRegExpValidator(rxNoNewLine, this)); } void InviteForm::destroy() { if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } } void InviteForm::clear() { inviteComboBox->clearEdit(); subjectLineEdit->clear(); hideUserCheckBox->setChecked(false); inviteComboBox->setFocus(); } void InviteForm::show(t_user *user_config, const QString &dest, const QString &subject, bool anonymous) { ((t_gui *)ui)->fill_user_combo(fromComboBox); // Select from user if (user_config) { for (int i = 0; i < fromComboBox->count(); i++) { if (fromComboBox->text(i) == user_config->get_profile_name().c_str()) { fromComboBox->setCurrentItem(i); break; } } } inviteComboBox->setEditText(dest); subjectLineEdit->setText(subject); hideUserCheckBox->setChecked(anonymous); QDialog::show(); } void InviteForm::validate() { string display, dest_str; t_user *from_user = phone->ref_user_profile( fromComboBox->currentText().ascii()); ui->expand_destination(from_user, inviteComboBox->currentText().stripWhiteSpace().ascii(), display, dest_str); t_url dest(dest_str); if (dest.is_valid()) { addToInviteComboBox(inviteComboBox->currentText()); emit raw_destination(inviteComboBox->currentText()); emit destination(from_user, display.c_str(), dest, subjectLineEdit->text(), hideUserCheckBox->isChecked()); accept(); } else { inviteComboBox->setFocus(); inviteComboBox->lineEdit()->selectAll(); } } // Add a destination to the history list of inviteComboBox void InviteForm::addToInviteComboBox(const QString &destination) { inviteComboBox->insertItem(destination, 0); if (inviteComboBox->count() > SIZE_REDIAL_LIST) { inviteComboBox->removeItem(inviteComboBox->count() - 1); } } void InviteForm::reject() { // Unseize the line ((t_gui *)ui)->action_unseize(); QDialog::reject(); } void InviteForm::closeEvent(QCloseEvent *) { reject(); } void InviteForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); getAddressForm->show(); } void InviteForm::selectedAddress(const QString &address) { inviteComboBox->setEditText(address); } void InviteForm::warnHideUser(void) { // Warn only once if (!sys_config->get_warn_hide_user()) return; QString msg = tr("Not all SIP providers support identity hiding. Make sure your SIP provider " "supports it if you really need it."); ((t_gui *)ui)->cb_show_msg(this, msg.ascii(), MSG_WARNING); // Do not warn again sys_config->set_warn_hide_user(false); } twinkle-1.4.2/src/gui/buddylistview.h0000644000175000001440000000501711134646162014541 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef BUDDYLISTVIEW_H #define BUDDYLISTVIEW_H #include "qlistview.h" #include "qpainter.h" #include "qtooltip.h" #include "presence/buddy.h" #include "presence/presence_epa.h" #include "patterns/observer.h" class AbstractBLVItem : public QListViewItem { protected: // Text to show as a tool tip. QString tip; // Set the presence icon to reflect the presence state virtual void set_icon(t_presence_state::t_basic_state state); public: AbstractBLVItem(QListViewItem *parent, const QString &text); AbstractBLVItem(QListView *parent, const QString &text); virtual ~AbstractBLVItem(); virtual QString get_tip(void); }; // List view item representing a buddy. class BuddyListViewItem : public AbstractBLVItem, public patterns::t_observer { private: t_buddy *buddy; // Set the presence icon to reflect the buddy's presence void set_icon(void); public: BuddyListViewItem(QListViewItem *parent, t_buddy *_buddy); virtual ~BuddyListViewItem(); virtual void update(void); virtual void subject_destroyed(void); t_buddy *get_buddy(void); }; // List view item representing a user class BLViewUserItem : public AbstractBLVItem, public patterns::t_observer { private: t_presence_epa *presence_epa; void set_icon(void); public: BLViewUserItem(QListView *parent, t_presence_epa *_presence_epa); virtual ~BLViewUserItem(); void paintCell(QPainter *painter, const QColorGroup &cg, int column, int width, int align); virtual void update(void); virtual void subject_destroyed(void); t_presence_epa *get_presence_epa(void); }; class BuddyListViewTip : public QToolTip { private: QListView *parentListView; public: BuddyListViewTip(QListView *parent); virtual ~BuddyListViewTip() {}; void maybeTip ( const QPoint & p ); }; #endif twinkle-1.4.2/src/gui/twinkleapplication.cpp0000644000175000001440000000313611127714053016074 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinkleapplication.h" #include "phone.h" #include "sys_settings.h" #include "user.h" #include "gui.h" extern t_phone *phone; #ifdef HAVE_KDE t_twinkle_application::t_twinkle_application() : KApplication() {} #else t_twinkle_application::t_twinkle_application(int &argc, char **argv) : QApplication(argc,argv) {} #endif void t_twinkle_application::commitData (QSessionManager &sm) { sys_config->set_ui_session_id(sessionId().ascii()); // Create list of active profile file names list user_list = phone->ref_users(); list profile_filenames; for (list::const_iterator it = user_list.begin(); it != user_list.end(); ++it) { profile_filenames.push_back((*it)->get_filename()); } sys_config->set_ui_session_active_profiles(profile_filenames); ((t_gui*)ui)->save_session_state(); } twinkle-1.4.2/src/gui/gui.cpp0000644000175000001440000022725411151323277012771 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinkle_config.h" #include #include #include #ifdef HAVE_KDE #include #include #include #include #endif // This include is needed to avoid build error when building Twinkle // without Qt. One of the other includes below seems to include qdir.h // indirectly. But by that time it probably conflicts with a macro causing // compilation errors reported in qdir.h Include qdir.h here avoids the // conflict. #include "qdir.h" #include "gui.h" #include "line.h" #include "log.h" #include "sys_settings.h" #include "user.h" #include "cmd_socket.h" #include "audio/rtp_telephone_event.h" #include "sockets/interfaces.h" #include "threads/thread.h" #include "audits/memman.h" #include "authenticationform.h" #include "mphoneform.h" #include "selectnicform.h" #include "selectprofileform.h" #include "messageformview.h" #include "twinklesystray.h" #include "util.h" #include "address_finder.h" #include "yesnodialog.h" #include "command_args.h" #include "im/msg_session.h" #include "qcombobox.h" #include "qhbox.h" #include "qlabel.h" #include "qlayout.h" #include "qlistbox.h" #include "qmessagebox.h" #include "qpixmap.h" #include "qprocess.h" #include "qpushbutton.h" #include "qsize.h" #include "qsizepolicy.h" #include "qstring.h" #include "qtextcodec.h" #include "qtextedit.h" #include "qtoolbar.h" #include "qtooltip.h" #include "qvbox.h" extern string user_host; extern pthread_t thread_id_main; // External command arguments extern t_command_args g_cmd_args; QString str2html(const QString &s) { QString result(s); result.replace('&', "&"); result.replace('<', "<"); result.replace('>', ">"); return result; } void setDisabledIcon(QAction *action, const QString &icon) { QIconSet i = action->iconSet(); i.setPixmap(QPixmap::fromMimeSource(icon), QIconSet::Automatic, QIconSet::Disabled); action->setIconSet(i); } void setDisabledIcon(QToolButton *toolButton, const QString &icon) { QIconSet i = toolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource(icon), QIconSet::Automatic, QIconSet::Disabled); toolButton->setIconSet(i); } ///////////////////////////////////////////////// // PRIVATE ///////////////////////////////////////////////// void t_gui::setLineFields(int line) { if (line == 0) { fromLabel = mainWindow->from1Label; toLabel = mainWindow->to1Label; subjectLabel = mainWindow->subject1Label; codecLabel = mainWindow->codec1TextLabel; photoLabel = mainWindow->photo1Label; } else { fromLabel = mainWindow->from2Label; toLabel = mainWindow->to2Label; subjectLabel = mainWindow->subject2Label; codecLabel = mainWindow->codec2TextLabel; photoLabel = mainWindow->photo2Label; } } void t_gui::clearLineFields(int line) { if (line >= NUM_USER_LINES) return; setLineFields(line); fromLabel->clear(); QToolTip::remove(fromLabel); toLabel->clear(); QToolTip::remove(toLabel); subjectLabel->clear(); QToolTip::remove(subjectLabel); codecLabel->clear(); photoLabel->clear(); photoLabel->hide(); } void t_gui::displayTo(const QString &s) { toLabel->setText(s); toLabel->setCursorPosition(0); QToolTip::add(toLabel, s); } void t_gui::displayFrom(const QString &s) { fromLabel->setText(s); fromLabel->setCursorPosition(0); QToolTip::add(fromLabel, s); } void t_gui::displaySubject(const QString &s) { subjectLabel->setText(s); subjectLabel->setCursorPosition(0); QToolTip::add(subjectLabel, s); } void t_gui::displayCodecInfo(int line) { if (line > NUM_USER_LINES) return; setLineFields(line); codecLabel->clear(); t_call_info call_info = phone->get_call_info(line); if (call_info.send_codec == CODEC_NULL && call_info.recv_codec == CODEC_NULL) { return; } if (call_info.send_codec == CODEC_NULL) { codecLabel->setText(format_codec(call_info.recv_codec).c_str()); return; } if (call_info.recv_codec == CODEC_NULL) { codecLabel->setText(format_codec(call_info.send_codec).c_str()); return; } if (call_info.send_codec == call_info.recv_codec) { codecLabel->setText(format_codec(call_info.send_codec).c_str()); return; } QString s = format_codec(call_info.send_codec).c_str(); s.append('/').append(format_codec(call_info.recv_codec).c_str()); codecLabel->setText(s); } void t_gui::displayPhoto(const QImage &photo) { if (mainWindow->getViewCompactLineStatus()) { // In compact line status mode, no photo can be shown return; } if (photo.isNull()) { photoLabel->hide(); } else { QPixmap pm; pm.convertFromImage(photo.smoothScale( photoLabel->width(), photoLabel->height(), QImage::ScaleMin)); photoLabel->setPixmap(pm); photoLabel->show(); } } ///////////////////////////////////////////////// // PROTECTED ///////////////////////////////////////////////// bool t_gui::do_invite(const string &destination, const string &display, const string &subject, bool immediate, bool anonymous) { lock(); if (mainWindow->callInvite->isEnabled()) { if (immediate) { t_user *user = phone->ref_user_profile( mainWindow->userComboBox->currentText().ascii()); t_url dst_url(expand_destination(user, destination)); if (dst_url.is_valid()) { mainWindow->do_phoneInvite(user, display.c_str(), dst_url, subject.c_str(), anonymous); } } else { t_url dest_url(destination); t_display_url du(dest_url, display); mainWindow->phoneInvite(du.encode().c_str(), subject.c_str(), anonymous); } } unlock(); return true; } void t_gui::do_redial(void) { lock(); if (mainWindow->callRedial->isEnabled()) { mainWindow->phoneRedial(); } unlock(); } void t_gui::do_answer(void) { lock(); if (mainWindow->callAnswer->isEnabled()) { mainWindow->phoneAnswer(); } unlock(); } void t_gui::do_answerbye(void) { lock(); if (mainWindow->callAnswer->isEnabled()) { mainWindow->phoneAnswer(); } else if (mainWindow->callBye->isEnabled()) { mainWindow->phoneBye(); } unlock(); } void t_gui::do_reject(void) { lock(); if (mainWindow->callReject->isEnabled()) { mainWindow->phoneReject(); } unlock(); } void t_gui::do_redirect(bool show_status, bool type_present, t_cf_type cf_type, bool action_present, bool enable, int num_redirections, const list &dest_strlist, bool immediate) { if (show_status) { // Show status not supported in GUI return; } t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); list dest_list; for (list::const_iterator i = dest_strlist.begin(); i != dest_strlist.end(); i++) { t_display_url du; du.url = expand_destination(user, *i); du.display.clear(); if (!du.is_valid()) return; dest_list.push_back(du); } // Enable/disable permanent redirections if (type_present) { lock(); if (enable) { phone->ref_service(user)->enable_cf(cf_type, dest_list); } else { phone->ref_service(user)->disable_cf(cf_type); } mainWindow->updateServicesStatus(); unlock(); return; } else { if (action_present) { if (!enable) { lock(); phone->ref_service(user)->disable_cf(CF_ALWAYS); phone->ref_service(user)->disable_cf(CF_BUSY); phone->ref_service(user)->disable_cf(CF_NOANSWER); mainWindow->updateServicesStatus(); unlock(); } return; } } lock(); if (mainWindow->callRedirect->isEnabled()) { if (immediate) { mainWindow->do_phoneRedirect(dest_list); } else { mainWindow->phoneRedirect(dest_strlist); } } unlock(); return; } void t_gui::do_dnd(bool show_status, bool toggle, bool enable) { if (show_status) { // Show status not supported in GUI return; } lock(); if (phone->ref_users().size() == 1) { if (toggle) { enable = !mainWindow->serviceDnd->isOn(); } mainWindow->srvDnd(enable); mainWindow->serviceDnd->setOn(enable); } else { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); list l; l.push_back(user); if (toggle) { enable = !phone->ref_service(user)->is_dnd_active(); } if (enable) { mainWindow->do_srvDnd_enable(l); } else { mainWindow->do_srvDnd_disable(l); } } unlock(); } void t_gui::do_auto_answer(bool show_status, bool toggle, bool enable) { if (show_status) { // Show status not supported in GUI return; } lock(); if (phone->ref_users().size() == 1) { if (toggle) { enable = !mainWindow->serviceAutoAnswer->isOn(); } mainWindow->srvAutoAnswer(enable); mainWindow->serviceAutoAnswer->setOn(enable); } else { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); list l; l.push_back(user); if (toggle) { enable = !phone->ref_service(user)-> is_auto_answer_active(); } if (enable) { mainWindow->do_srvAutoAnswer_enable(l); } else { mainWindow->do_srvAutoAnswer_disable(l); } } unlock(); } void t_gui::do_bye(void) { lock(); if (mainWindow->callBye->isEnabled()) { mainWindow->phoneBye(); } unlock(); } void t_gui::do_hold(void) { lock(); if (mainWindow->callHold->isEnabled() && !mainWindow->callHold->isOn()) { mainWindow->phoneHold(true); } unlock(); } void t_gui::do_retrieve(void) { lock(); if (mainWindow->callHold->isEnabled() && mainWindow->callHold->isOn()) { mainWindow->phoneHold(false); } unlock(); } bool t_gui::do_refer(const string &destination, t_transfer_type transfer_type, bool immediate) { lock(); if (mainWindow->callTransfer->isEnabled() && !mainWindow->callTransfer->isOn()) { if (immediate) { t_display_url du; t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); du.url = expand_destination(user, destination); if (du.is_valid() || transfer_type == TRANSFER_OTHER_LINE) { mainWindow->do_phoneTransfer(du, transfer_type); } } else { mainWindow->phoneTransfer(destination, transfer_type); } } else if(mainWindow->callTransfer->isEnabled() && mainWindow->callTransfer->isOn()) { if (transfer_type != TRANSFER_CONSULT) { mainWindow->do_phoneTransferLine(); } } unlock(); return true; } void t_gui::do_conference(void) { lock(); if (mainWindow->callConference->isEnabled()) { mainWindow->phoneConference(); } unlock(); } void t_gui::do_mute(bool show_status, bool toggle, bool enable) { if (show_status) { // Show status not supported in GUI return; } lock(); if (mainWindow->callMute->isEnabled()) { if (toggle) enable = !phone->is_line_muted(phone->get_active_line()); mainWindow->phoneMute(enable); } unlock(); } void t_gui::do_dtmf(const string &digits) { lock(); if (mainWindow->callDTMF->isEnabled()) { mainWindow->sendDTMF(digits.c_str()); } unlock(); } void t_gui::do_register(bool reg_all_profiles) { lock(); list l; if (reg_all_profiles) { l = phone->ref_users(); } else { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); l.push_back(user); } mainWindow->do_phoneRegister(l); unlock(); } void t_gui::do_deregister(bool dereg_all_profiles, bool dereg_all_devices) { lock(); list l; if (dereg_all_profiles) { l = phone->ref_users(); } else { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); l.push_back(user); } if (dereg_all_devices) { mainWindow->do_phoneDeregisterAll(l); } else { mainWindow->do_phoneDeregister(l); } unlock(); } void t_gui::do_fetch_registrations(void) { lock(); mainWindow->phoneShowRegistrations(); unlock(); } bool t_gui::do_options(bool dest_set, const string &destination, bool immediate) { lock(); // In-dialog OPTIONS request int line = phone->get_active_line(); if (phone->get_line_substate(line) == LSSUB_ESTABLISHED) { ((t_gui *)ui)->action_options(); return true; } if (immediate) { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); t_url dst_url(expand_destination(user, destination)); if (dst_url.is_valid()) { mainWindow->do_phoneTermCap(user, dst_url); } } else { mainWindow->phoneTermCap(destination.c_str()); } unlock(); return true; } void t_gui::do_line(int line) { // Cannot get current line number via CLI interface on GUI. // So return in this case. if (line == 0) return; phone->pub_activate_line(line - 1); } void t_gui::do_user(const string &profile_name) { lock(); for (int i = 0; i < mainWindow->userComboBox->count(); i++) { if (mainWindow->userComboBox->text(i) == profile_name.c_str()) { mainWindow->userComboBox->setCurrentItem(i); } } unlock(); } bool t_gui::do_message(const string &destination, const string &display, const im::t_msg &msg) { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); t_url dest_url(expand_destination(user, destination)); if (dest_url.is_valid()) { phone->pub_send_message(user, dest_url, display, msg); } return true; } void t_gui::do_presence(t_presence_state::t_basic_state basic_state) { t_user *user = phone->ref_user_profile(mainWindow-> userComboBox->currentText().ascii()); phone->pub_publish_presence(user, basic_state); } void t_gui::do_zrtp(t_zrtp_cmd zrtp_cmd) { lock(); switch (zrtp_cmd) { case ZRTP_ENCRYPT: mainWindow->phoneEnableZrtp(true); break; case ZRTP_GO_CLEAR: mainWindow->phoneEnableZrtp(false); break; case ZRTP_CONFIRM_SAS: mainWindow->phoneConfirmZrtpSas(); break; case ZRTP_RESET_SAS: mainWindow->phoneResetZrtpSasConfirmation(); break; default: assert(false); } unlock(); } void t_gui::do_quit(void) { lock(); mainWindow->fileExit(); unlock(); } void t_gui::do_help(const list &al) { // Nothing to do in GUI mode return; } ///////////////////////////////////////////////// // PUBLIC ///////////////////////////////////////////////// t_gui::t_gui(t_phone *_phone) : t_userintf(_phone), timerUpdateMessageSessions(NULL) { use_stdout = false; lastFileBrowsePath = DIR_HOME; mainWindow = new MphoneForm(0, 0, Qt::WType_TopLevel | Qt::WStyle_ContextHelp); #ifdef HAVE_KDE sys_tray_popup = NULL; #endif for (int i = 0; i < NUM_USER_LINES; i++) { QObject::connect(&autoShowTimer[i], SIGNAL(timeout()), mainWindow, SLOT(show())); } MEMMAN_NEW(mainWindow); qApp->setMainWidget(mainWindow); } t_gui::~t_gui() { destroyAllMessageSessions(); MEMMAN_DELETE(mainWindow); delete mainWindow; } void t_gui::run(void) { // Start asynchronous event processor thr_process_events = new t_thread(process_events_main, NULL); MEMMAN_NEW(thr_process_events); QString s; list user_list = phone->ref_users(); // The Qt event loop is not running yet. Explicitly take the Qt lock // to avoid race conditions with other threads that may call GUI call // backs. // NOTE: the t_gui::lock() method cannot be used as this method // will not lock from the main thread and we are running in the // main thread (a bit of a kludge). qApp->lock(); // Set configuration file name in titlebar s = PRODUCT_NAME; mainWindow->setCaption(s); // Set user combo box mainWindow->updateUserComboBox(); // Display product information s = PRODUCT_NAME; s.append(' ').append(PRODUCT_VERSION).append(", "); s.append(sys_config->get_product_date().c_str()); mainWindow->display(s); s = "Copyright (C) 2005-2009 "; s.append(PRODUCT_AUTHOR); mainWindow->display(s); // Restore user interface state from previous session restore_state(); // Initialize phone functions phone->init(); // Set controls in correct status mainWindow->updateState(); mainWindow->updateRegStatus(); mainWindow->updateMwi(); mainWindow->updateServicesStatus(); mainWindow->updateMissedCallStatus(0); mainWindow->updateMenuStatus(); // Clear line field info fields clearLineFields(0); clearLineFields(1); // Populate buddy list mainWindow->populateBuddyList(); // Set width of window to width of tool bar int widthToolBar = mainWindow->callToolbar->width(); QSize sizeMainWin = mainWindow->size(); sizeMainWin.setWidth(widthToolBar); mainWindow->resize(sizeMainWin); // Start QApplication/KApplication if (qApp->isSessionRestored() && sys_config->get_ui_session_id() == qApp->sessionId().ascii()) { // Restore previous session restore_session_state(); } else { if ((sys_config->get_start_hidden() && !g_cmd_args.cmd_show) || g_cmd_args.cmd_hide) { mainWindow->hide(); } else { mainWindow->show(); } } // Activate a profile if the --set-profile option was given on the command // line. if (!g_cmd_args.cmd_set_profile.isEmpty()) { cmdsocket::cmd_cli(string("user ") + g_cmd_args.cmd_set_profile.ascii(), true); } // Execute the call command if a callto destination was specified on the // command line if (!g_cmd_args.callto_destination.isEmpty()) { cmdsocket::cmd_call(g_cmd_args.callto_destination.ascii(), g_cmd_args.cmd_immediate_mode); } // Execute a CLI command if one was given on the command line if (!g_cmd_args.cli_command.isEmpty()) { cmdsocket::cmd_cli(g_cmd_args.cli_command.ascii(), g_cmd_args.cmd_immediate_mode); } qApp->unlock(); // Start Qt application qApp->exec(); // Terminate phone functions phone->terminate(); // Make user interface state persistent save_state(); } void t_gui::save_state(void) { lock(); sys_config->set_last_used_profile( mainWindow->userComboBox->currentText().ascii()); list history; for (int i = 0; i < mainWindow->callComboBox->count(); i++) { history.push_back(mainWindow->callComboBox->text(i).ascii()); } sys_config->set_dial_history(history); sys_config->set_show_display(mainWindow->getViewDisplay()); sys_config->set_compact_line_status(mainWindow->getViewCompactLineStatus()); sys_config->set_show_buddy_list(mainWindow->getViewBuddyList()); t_userintf::save_state(); unlock(); } void t_gui::restore_state(void) { lock(); // The last used profile is selected when the userComboBox is // filled by MphoneForm::updateUserComboBox mainWindow->callComboBox->clear(); list dial_history = sys_config->get_dial_history(); for (list::reverse_iterator i = dial_history.rbegin(); i != dial_history.rend(); i++) { mainWindow->addToCallComboBox(i->c_str()); } mainWindow->showDisplay(sys_config->get_show_display()); mainWindow->showCompactLineStatus(sys_config->get_compact_line_status()); mainWindow->showBuddyList(sys_config->get_show_buddy_list()); t_userintf::restore_state(); unlock(); } void t_gui::save_session_state(void) { lock(); t_win_geometry geometry(mainWindow->x(), mainWindow->y(), mainWindow->width(), mainWindow->height()); sys_config->set_ui_session_main_geometry(geometry); sys_config->set_ui_session_main_state(mainWindow->windowState()); sys_config->set_ui_session_main_hidden(mainWindow->isHidden()); unlock(); } void t_gui::restore_session_state(void) { lock(); t_win_geometry geometry = sys_config->get_ui_session_main_geometry(); mainWindow->setGeometry(geometry.x, geometry.y, geometry.width, geometry.height); mainWindow->setWindowState(sys_config->get_ui_session_main_state()); mainWindow->setHidden(sys_config->get_ui_session_main_hidden()); unlock(); } void t_gui::lock(void) { // To synchronize actions on the Qt widget the application lock // is used. The main thread running the Qt event loop takes the // application lock itself already. So take the lock if this is not the // main thread. // If the Qt event loop has not been started yet, then the lock // should also be taken from the main thread. t_userintf::lock(); if (!t_thread::is_self(thread_id_main)) { qApp->lock(); } } void t_gui::unlock(void) { t_userintf::lock(); if (!t_thread::is_self(thread_id_main)) { qApp->unlock(); } } string t_gui::select_network_intf(void) { string ip; list *l = get_interfaces(); // The socket routines are not under control of MEMMAN so report // the allocation here. MEMMAN_NEW(l); if (l->size() == 0) { cb_show_msg(qApp->translate("GUI", "Cannot find a network interface. Twinkle will use " "127.0.0.1 as the local IP address. When you connect to " "the network you have to restart Twinkle to use the correct " "IP address.").ascii(), MSG_WARNING); MEMMAN_DELETE(l); delete l; return "127.0.0.1"; } if (l->size() == 1) { // There is only 1 interface ip = l->front().get_ip_addr(); } else { // There are multiple interfaces SelectNicForm *sf = new SelectNicForm(NULL, "nic", true); MEMMAN_NEW(sf); QString item; for (list::iterator i = l->begin(); i != l->end(); i++) { item = i->name.c_str(); item.append(':').append(i->get_ip_addr().c_str()); sf->nicListBox->insertItem( QPixmap::fromMimeSource("kcmpci16.png"), item); } sf->nicListBox->setCurrentItem(0); sf->exec(); int selection = sf->nicListBox->currentItem(); int num = 0; for (list::iterator i = l->begin(); i != l->end(); i++) { if (num == selection) { ip = i->get_ip_addr(); break; } num++; } MEMMAN_DELETE(sf); delete sf; } MEMMAN_DELETE(l); delete l; return ip; } bool t_gui::select_user_config(list &config_files) { SelectProfileForm f(0, "select user profile", true); if (f.execForm()) { config_files = f.selectedProfiles; return true; } return false; } // GUI call back functions void t_gui::cb_incoming_call(t_user *user_config, int line, const t_request *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; setLineFields(line); // Incoming call for to-header mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: incoming call for %2").arg(line + 1).arg( format_sip_address(user_config, r->hdr_to.display, r->hdr_to.uri).c_str()); mainWindow->display(s); // Is this a transferred call? QString referredByParty; if (r->hdr_referred_by.is_populated()) { referredByParty = format_sip_address(user_config, r->hdr_referred_by.display, r->hdr_referred_by.uri).c_str(); s = "Call transferred by "; s = qApp->translate("GUI", "Call transferred by %1").arg(referredByParty); mainWindow->display(s); } // From QString fromParty = format_sip_address(user_config, r->hdr_from.get_display_presentation(), r->hdr_from.uri).c_str(); s = fromParty; QString organization(""); if (r->hdr_organization.is_populated()) { organization = r->hdr_organization.name.c_str(); s.append(", ").append(organization); } displayFrom(s); // Display photo QImage fromPhoto; if (sys_config->get_ab_lookup_photo()) { t_address_finder *af = t_address_finder::get_instance(); fromPhoto = af->find_photo(user_config, r->hdr_from.uri); } displayPhoto(fromPhoto); // To s = ""; s.append(format_sip_address(user_config, r->hdr_to.display, r->hdr_to.uri).c_str()); displayTo(s); // Subject QString subject(""); if (r->hdr_subject.is_populated()) { subject = r->hdr_subject.subject.c_str(); } displaySubject(subject); cb_notify_call(line, fromParty, organization, fromPhoto, subject, referredByParty); unlock(); } void t_gui::cb_call_cancelled(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: far end cancelled call.").arg(line + 1); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_far_end_hung_up(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: far end released call.").arg(line + 1); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_answer_timeout(int line) { if (line >= NUM_USER_LINES) return; lock(); cb_stop_call_notification(line); unlock(); } void t_gui::cb_sdp_answer_not_supported(int line, const string &reason) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: SDP answer from far end not supported.").arg(line + 1); mainWindow->display(s); s = reason.c_str(); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_sdp_answer_missing(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: SDP answer from far end missing.").arg(line + 1); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_unsupported_content_type(int line, const t_sip_message *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: Unsupported content type in answer from far end.").arg(line + 1); mainWindow->display(s); s = r->hdr_content_type.media.type.c_str(); s.append("/").append(r->hdr_content_type.media.subtype.c_str()); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_ack_timeout(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: no ACK received, call will be terminated.").arg(line + 1); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_100rel_timeout(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: no PRACK received, call will be terminated.").arg(line + 1); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_prack_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: PRACK failed.").arg(line + 1); mainWindow->display(s); s = QString().setNum(r->code); s.append(' ').append(r->reason.c_str()); mainWindow->display(s); cb_stop_call_notification(line); unlock(); } void t_gui::cb_provisional_resp_invite(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); mainWindow->updateState(); unlock(); } void t_gui::cb_cancel_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: failed to cancel call.").arg(line + 1); mainWindow->display(s); s = QString().setNum(r->code); s.append(' ').append(r->reason.c_str()); mainWindow->display(s); unlock(); } void t_gui::cb_call_answered(t_user *user_config, int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; setLineFields(line); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: far end answered call.").arg(line + 1); mainWindow->display(s); // Put far-end party in line to-field s = ""; s.append(format_sip_address(user_config, r->hdr_to.display, r->hdr_to.uri).c_str()); if (r->hdr_organization.is_populated()) { s.append(", ").append(r->hdr_organization.name.c_str()); } displayTo(s); unlock(); } void t_gui::cb_call_failed(t_user *user_config, int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call failed.").arg(line + 1); mainWindow->display(s); s = QString().setNum(r->code); s.append(' ').append(r->reason.c_str()); mainWindow->display(s); // Warnings if (r->hdr_warning.is_populated()) { list l = format_warnings(r->hdr_warning); for (list::iterator i = l.begin(); i != l.end(); i++) { mainWindow->display(i->c_str()); } } // Redirect response if (r->get_class() == R_3XX && r->hdr_contact.is_populated()) { list l = r->hdr_contact.contact_list; l.sort(); mainWindow->display(qApp->translate("GUI", "The call can be redirected to:")); for (list::iterator i = l.begin(); i != l.end(); i++) { s = format_sip_address(user_config, i->display, i->uri).c_str(); mainWindow->display(s); } } // Unsupported extensions if (r->code == R_420_BAD_EXTENSION) { mainWindow->display(r->hdr_unsupported.encode().c_str()); } unlock(); } void t_gui::cb_stun_failed_call_ended(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call failed.").arg(line + 1); mainWindow->display(s); unlock(); } void t_gui::cb_call_ended(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call released.").arg(line + 1); mainWindow->display(s); unlock(); } void t_gui::cb_call_established(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call established.").arg(line + 1); mainWindow->display(s); unlock(); } void t_gui::cb_options_response(const t_response *r) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Response on terminal capability request: %1 %2") .arg(r->code).arg(r->reason.c_str()); mainWindow->display(s); if (r->code == R_408_REQUEST_TIMEOUT) { // The request timed out, so no capabilities are known. unlock(); return; } s = qApp->translate("GUI", "Terminal capabilities of %1").arg(r->hdr_to.uri.encode().c_str()); mainWindow->display(s); s = qApp->translate("GUI", "Accepted body types:").append(" "); if (r->hdr_accept.is_populated()) { s.append(r->hdr_accept.get_value().c_str()); } else { s.append(qApp->translate("GUI", "unknown")); } mainWindow->display(s); s = qApp->translate("GUI", "Accepted encodings:").append(" "); if (r->hdr_accept_encoding.is_populated()) { s.append(r->hdr_accept_encoding.get_value().c_str()); } else { s.append(qApp->translate("GUI", "unknown")); } mainWindow->display(s); s = qApp->translate("GUI", "Accepted languages:").append(" "); if (r->hdr_accept_language.is_populated()) { s.append(r->hdr_accept_language.get_value().c_str()); } else { s.append(qApp->translate("GUI", "unknown")); } mainWindow->display(s); s = qApp->translate("GUI", "Allowed requests:").append(" "); if (r->hdr_allow.is_populated()) { s.append(r->hdr_allow.get_value().c_str()); } else { s.append(qApp->translate("GUI", "unknown")); } mainWindow->display(s); s = qApp->translate("GUI", "Supported extensions:").append(" "); if (r->hdr_supported.is_populated()) { if (r->hdr_supported.features.empty()) { s.append(qApp->translate("GUI", "none")); } else { s.append(r->hdr_supported.get_value().c_str()); } } else { s.append(qApp->translate("GUI", "unknown")); } mainWindow->display(s); s = qApp->translate("GUI", "End point type:").append(" "); if (r->hdr_server.is_populated()) { s.append(r->hdr_server.get_value().c_str()); } else if (r->hdr_user_agent.is_populated()) { // Some end-points put a User-Agent header in the response // instead of a Server header. s.append(r->hdr_user_agent.get_value().c_str()); } else { s.append(qApp->translate("GUI", "unknown")); } mainWindow->display(s); unlock(); } void t_gui::cb_reinvite_success(int line, const t_response *r) { // Do not bother GUI user. return; } void t_gui::cb_reinvite_failed(int line, const t_response *r) { // Do not bother GUI user. return; } void t_gui::cb_retrieve_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call retrieve failed.").arg(line + 1); mainWindow->display(s); s = QString().setNum(r->code); s.append(' ').append(r->reason.c_str()); mainWindow->display(s); unlock(); } void t_gui::cb_invalid_reg_resp(t_user *user_config, const t_response *r, const string &reason) { lock(); QString s; mainWindow->displayHeader(); qApp->translate("GUI", "%1, registration failed: %2 %3") .arg(user_config->get_profile_name().c_str()) .arg(r->code) .arg(r->reason.c_str()); mainWindow->display(s); mainWindow->display(reason.c_str()); mainWindow->updateRegStatus(); unlock(); } void t_gui::cb_register_success(t_user *user_config, const t_response *r, unsigned long expires, bool first_success) { lock(); QString s; if (first_success) { mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, registration succeeded (expires = %2 seconds)") .arg(user_config->get_profile_name().c_str()) .arg(expires); mainWindow->display(s); } mainWindow->updateRegStatus(); unlock(); } void t_gui::cb_register_failed(t_user *user_config, const t_response *r, bool first_failure) { lock(); QString s; if (first_failure) { mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, registration failed: %2 %3") .arg(user_config->get_profile_name().c_str()) .arg(r->code) .arg(r->reason.c_str()); mainWindow->display(s); } mainWindow->updateRegStatus(); unlock(); } void t_gui::cb_register_stun_failed(t_user *user_config, bool first_failure) { lock(); QString s; if (first_failure) { mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, registration failed: STUN failure") .arg(user_config->get_profile_name().c_str()); mainWindow->display(s); } mainWindow->updateRegStatus(); unlock(); } void t_gui::cb_deregister_success(t_user *user_config, const t_response *r) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, de-registration succeeded: %2 %3") .arg(user_config->get_profile_name().c_str()) .arg(r->code) .arg(r->reason.c_str()); mainWindow->display(s); mainWindow->updateRegStatus(); unlock(); } void t_gui::cb_deregister_failed(t_user *user_config, const t_response *r) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, de-registration failed: %2 %3") .arg(user_config->get_profile_name().c_str()) .arg(r->code) .arg(r->reason.c_str()); mainWindow->display(s); mainWindow->updateRegStatus(); unlock(); } void t_gui::cb_fetch_reg_failed(t_user *user_config, const t_response *r) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, fetching registrations failed: %2 %3") .arg(user_config->get_profile_name().c_str()) .arg(r->code) .arg(r->reason.c_str()); mainWindow->display(s); unlock(); } void t_gui::cb_fetch_reg_result(t_user *user_config, const t_response *r) { lock(); QString s; mainWindow->displayHeader(); s = user_config->get_profile_name().c_str(); const list &l = r->hdr_contact.contact_list; if (l.size() == 0) { s += qApp->translate("GUI", ": you are not registered"); mainWindow->display(s); } else { s += qApp->translate("GUI", ": you have the following registrations"); mainWindow->display(s); for (list::const_iterator i = l.begin(); i != l.end(); i++) { mainWindow->display(i->encode().c_str()); } } unlock(); } void t_gui::cb_register_inprog(t_user *user_config, t_register_type register_type) { QString s; lock(); switch(register_type) { case REG_REGISTER: // Do not report registration refreshments if (phone->get_is_registered(user_config)) break; mainWindow->statRegLabel->setPixmap( QPixmap::fromMimeSource("gear.png")); break; case REG_DEREGISTER: case REG_DEREGISTER_ALL: mainWindow->statRegLabel->setPixmap( QPixmap::fromMimeSource("gear.png")); break; case REG_QUERY: mainWindow->displayHeader(); s = user_config->get_profile_name().c_str(); s += qApp->translate("GUI", ": fetching registrations..."); mainWindow->display(s); break; } unlock(); } void t_gui::cb_redirecting_request(t_user *user_config, int line, const t_contact_param &contact) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: redirecting request to").arg(line + 1); mainWindow->display(s); s = format_sip_address(user_config, contact.display, contact.uri).c_str(); mainWindow->display(s); unlock(); } void t_gui::cb_redirecting_request(t_user *user_config, const t_contact_param &contact) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Redirecting request to: %1").arg( format_sip_address(user_config, contact.display, contact.uri).c_str()); mainWindow->display(s); unlock(); } void t_gui::cb_notify_call(int line, const QString &from_party, const QString &organization, const QImage &photo, const QString &subject, QString &referred_by_party) { if (line >= NUM_USER_LINES) return; lock(); // Play ringtone if the call is received on the active line. if (line == phone->get_active_line() && !phone->is_line_auto_answered(line)) { cb_play_ringtone(line); } // Pop up sys tray balloon #ifdef HAVE_KDE t_twinkle_sys_tray *tray = mainWindow->getSysTray(); if (tray && !sys_tray_popup && !phone->is_line_auto_answered(line)) { QString presFromParty(""); if (!from_party.isEmpty()) { presFromParty = dotted_truncate(from_party.ascii(), 50).c_str(); } QString presOrganization(""); if (!organization.isEmpty()) { presOrganization = dotted_truncate(organization.ascii(), 50).c_str(); } QString presSubject(""); if (!subject.isEmpty()) { presSubject = dotted_truncate(subject.ascii(), 50).c_str(); } QString presReferredByParty(""); if (!referred_by_party.isEmpty()) { presReferredByParty = qApp->translate("GUI", "Transferred by: %1").arg( dotted_truncate(referred_by_party.ascii(), 40).c_str()); } // Create photo pixmap. If no photo is available, then use // the Twinkle icon. QPixmap pm; QFrame::Shape photoFrameShape = QFrame::NoFrame; if (photo.isNull()) { pm = QPixmap::fromMimeSource("twinkle32.png"); } else { pm.convertFromImage(photo); photoFrameShape = QFrame::Box; } // Create the popup view. sys_tray_popup = new KPassivePopup(tray); MEMMAN_NEW(sys_tray_popup); sys_tray_popup->setAutoDelete(false); sys_tray_popup->setTimeout(0); QVBox *popup_view = new QVBox(sys_tray_popup); QHBox *hb = new QHBox(popup_view); hb->setSpacing(5); QLabel *lblPhoto = new QLabel(hb); lblPhoto->setPixmap(pm); lblPhoto->setFrameShape(photoFrameShape); QVBox *vb = new QVBox(hb); QString captionText("

"); captionText += qApp->translate("SysTrayPopup", "Incoming Call"); captionText += "

"; QLabel *lblCaption = new QLabel(captionText, vb); lblCaption->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblCaption->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QLabel *lblFrom = new QLabel(presFromParty, vb); lblFrom->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblFrom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QLabel *lastLabel = lblFrom; if (!presOrganization.isEmpty()) { QLabel *lblOrganization = new QLabel(presOrganization, vb); lblOrganization->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblOrganization->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); lastLabel = lblOrganization; } if (!presReferredByParty.isEmpty()) { QLabel *lblReferredBy = new QLabel(presReferredByParty, vb); lblReferredBy->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblReferredBy->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); lastLabel = lblReferredBy; } if (!presSubject.isEmpty()) { QLabel *lblSubject = new QLabel(presSubject, vb); lblSubject->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblSubject->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); lastLabel = lblSubject; } lastLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // Answer and reject buttons QHBox *buttonBox = new QHBox(vb); QIconSet iconAnswer(QPixmap::fromMimeSource("answer.png")); QPushButton *pbAnswer = new QPushButton(iconAnswer, qApp->translate("SysTrayPopup", "Answer"), buttonBox); QObject::connect(pbAnswer, SIGNAL(clicked()), mainWindow, SLOT(phoneAnswerFromSystrayPopup())); QIconSet iconReject(QPixmap::fromMimeSource("reject.png")); QPushButton *pbReject = new QPushButton(iconReject, qApp->translate("SysTrayPopup", "Reject"), buttonBox); QObject::connect(pbReject, SIGNAL(clicked()), mainWindow, SLOT(phoneRejectFromSystrayPopup())); sys_tray_popup->setView(popup_view); // Show the popup line_sys_tray_popup = line; sys_tray_popup->show(); QObject::connect(sys_tray_popup, SIGNAL(clicked()), sys_tray_popup, SLOT(hide())); } #endif // Show main window after a few seconds if (sys_config->get_gui_auto_show_incoming()) { autoShowTimer[line].start( sys_config->get_gui_auto_show_timeout() * 1000, true); } unlock(); } void t_gui::cb_stop_call_notification(int line) { if (line >= NUM_USER_LINES) return; lock(); cb_stop_tone(line); autoShowTimer[line].stop(); #ifdef HAVE_KDE if (sys_tray_popup && line_sys_tray_popup == line) { sys_tray_popup->hide(); MEMMAN_DELETE(sys_tray_popup); delete sys_tray_popup; sys_tray_popup = NULL; } #endif unlock(); } void t_gui::cb_dtmf_detected(int line, char dtmf_event) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: DTMF detected:").arg(line + 1).append(" "); if (VALID_DTMF_EV(dtmf_event)) { s.append(dtmf_ev2char(dtmf_event)); } else { s.append(qApp->translate("GUI", "invalid DTMF telephone event (%1)").arg( (int)dtmf_event)); } mainWindow->display(s); unlock(); } void t_gui::cb_send_dtmf(int line, char dtmf_event) { if (line >= NUM_USER_LINES) return; lock(); QString s; if (!VALID_DTMF_EV(dtmf_event)) return; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: send DTMF %2").arg(line + 1).arg( dtmf_ev2char(dtmf_event)); mainWindow->display(s); unlock(); } void t_gui::cb_dtmf_not_supported(int line) { if (line >= NUM_USER_LINES) return; QString s; if (throttle_dtmf_not_supported) return; lock(); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: far end does not support DTMF telephone events.").arg(line + 1); mainWindow->display(s); // Throttle subsequent call backs throttle_dtmf_not_supported = true; unlock(); } void t_gui::cb_dtmf_supported(int line) { if (line >= NUM_USER_LINES) return; lock(); mainWindow->updateState(); unlock(); } void t_gui::cb_line_state_changed(void) { lock(); mainWindow->updateState(); unlock(); } void t_gui::cb_send_codec_changed(int line, t_audio_codec codec) { if (line >= NUM_USER_LINES) return; lock(); displayCodecInfo(line); unlock(); } void t_gui::cb_recv_codec_changed(int line, t_audio_codec codec) { if (line >= NUM_USER_LINES) return; lock(); displayCodecInfo(line); unlock(); } void t_gui::cb_notify_recvd(int line, const t_request *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: received notification.").arg(line+1); mainWindow->display(s); s = qApp->translate("GUI", "Event: %1").arg(r->hdr_event.event_type.c_str()); mainWindow->display(s); s = qApp->translate("GUI", "State: %1").arg(r->hdr_subscription_state.substate.c_str()); mainWindow->display(s); if (r->hdr_subscription_state.substate == SUBSTATE_TERMINATED) { s = qApp->translate("GUI", "Reason: %1").arg(r->hdr_subscription_state.reason.c_str()); mainWindow->display(s); } t_response *sipfrag = (t_response *)((t_sip_body_sipfrag *)r->body)->sipfrag; s = qApp->translate("GUI", "Progress: %1 %2").arg(sipfrag->code).arg(sipfrag->reason.c_str()); mainWindow->display(s); unlock(); } void t_gui::cb_refer_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call transfer failed.").arg(line + 1); mainWindow->display(s); s = QString().setNum(r->code); s.append(' ').append(r->reason.c_str()); mainWindow->display(s); // The refer state has changed, so update the main window. mainWindow->updateState(); unlock(); } void t_gui::cb_refer_result_success(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call succesfully transferred.").arg(line + 1); mainWindow->display(s); // The refer state has changed, so update the main window. mainWindow->updateState(); unlock(); } void t_gui::cb_refer_result_failed(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call transfer failed.").arg(line + 1); mainWindow->display(s); // The refer state has changed, so update the main window. mainWindow->updateState(); unlock(); } void t_gui::cb_refer_result_inprog(int line) { if (line >= NUM_USER_LINES) return; lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call transfer still in progress.").arg(line + 1); mainWindow->display(s); s = qApp->translate("GUI", "No further notifications will be received."); mainWindow->display(s); // The refer state has changed, so update the main window. mainWindow->updateState(); unlock(); } void t_gui::cb_call_referred(t_user *user_config, int line, t_request *r) { if (line >= NUM_USER_LINES) return; QString s; lock(); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: transferring call to %2").arg(line +1).arg( format_sip_address(user_config, r->hdr_refer_to.display, r->hdr_refer_to.uri).c_str()); mainWindow->display(s); if (r->hdr_referred_by.is_populated()) { s = qApp->translate("GUI", "Transfer requested by %1").arg( format_sip_address(user_config, r->hdr_referred_by.display, r->hdr_referred_by.uri).c_str()); mainWindow->display(s); } setLineFields(line); s = format_sip_address(user_config, user_config->get_display(false), user_config->create_user_uri(false)).c_str(); displayFrom(s); photoLabel->hide(); s = format_sip_address(user_config, r->hdr_refer_to.display, r->hdr_refer_to.uri).c_str(); displayTo(s); subjectLabel->clear(); codecLabel->clear(); unlock(); } void t_gui::cb_retrieve_referrer(t_user *user_config, int line) { if (line >= NUM_USER_LINES) return; QString s; lock(); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: Call transfer failed. Retrieving original call.").arg(line + 1); mainWindow->display(s); setLineFields(line); const t_call_info call_info = phone->get_call_info(line); s = format_sip_address(user_config, call_info.get_from_display_presentation(), call_info.from_uri).c_str(); if (!call_info.from_organization.empty()) { s += ", "; s += call_info.from_organization.c_str(); } displayFrom(s); // Display photo QImage fromPhoto; if (sys_config->get_ab_lookup_photo()) { t_address_finder *af = t_address_finder::get_instance(); fromPhoto = af->find_photo(user_config, call_info.from_uri); } displayPhoto(fromPhoto); s = format_sip_address(user_config, call_info.to_display, call_info.to_uri).c_str(); if (!call_info.to_organization.empty()) { s += ", "; s += call_info.to_organization.c_str(); } displayTo(s); displaySubject(call_info.subject.c_str()); codecLabel->clear(); unlock(); } void t_gui::cb_consultation_call_setup(t_user *user_config, int line) { if (line >= NUM_USER_LINES) return; QString s; lock(); setLineFields(line); const t_call_info call_info = phone->get_call_info(line); s = format_sip_address(user_config, call_info.get_from_display_presentation(), call_info.from_uri).c_str(); if (!call_info.from_organization.empty()) { s += ", "; s += call_info.from_organization.c_str(); } displayFrom(s); photoLabel->hide(); s = format_sip_address(user_config, call_info.to_display, call_info.to_uri).c_str(); if (!call_info.to_organization.empty()) { s += ", "; s += call_info.to_organization.c_str(); } displayTo(s); displaySubject(call_info.subject.c_str()); codecLabel->clear(); unlock(); } void t_gui::cb_stun_failed(t_user *user_config, int err_code, const string &err_reason) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, STUN request failed: %2 %3") .arg(user_config->get_profile_name().c_str()) .arg(err_code).arg(err_reason.c_str()); mainWindow->display(s); unlock(); } void t_gui::cb_stun_failed(t_user *user_config) { lock(); QString s; mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, STUN request failed.") .arg(user_config->get_profile_name().c_str()); mainWindow->display(s); unlock(); } bool t_gui::cb_ask_user_to_redirect_invite(t_user *user_config, const t_url &destination, const string &display) { QString s; QString title; lock(); title = PRODUCT_NAME; title.append(" - ").append(qApp->translate("GUI", "Redirecting call")); s = qApp->translate("GUI", "User profile:").append(" "); s.append(user_config->get_profile_name().c_str()); s.append("
").append(qApp->translate("GUI", "User:")).append(" "); s.append(str2html(user_config->get_display_uri().c_str())); s.append("

"); s.append(qApp->translate("GUI", "Do you allow the call to be redirected to the following destination?")); s.append("

"); s.append(str2html(ui->format_sip_address(user_config, display, destination).c_str())); s.append("

"); s.append(qApp->translate("GUI", "If you don't want to be asked this anymore, then you must change " "the settings in the SIP protocol section of the user profile.")); QMessageBox *mb = new QMessageBox(title, s, QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton, mainWindow); MEMMAN_NEW(mb); bool permission = (mb->exec() == QMessageBox::Yes); MEMMAN_DELETE(mb); delete mb; unlock(); return permission; } bool t_gui::cb_ask_user_to_redirect_request(t_user *user_config, const t_url &destination, const string &display, t_method method) { QString s; QString title; lock(); title = PRODUCT_NAME; title.append(" - ").append(qApp->translate("GUI", "Redirecting request")); s = qApp->translate("GUI", "User profile:").append(" "); s.append(user_config->get_profile_name().c_str()); s.append("
").append(qApp->translate("GUI", "User:")).append(" "); s.append(str2html(user_config->get_display_uri().c_str())); s.append("

"); s.append(qApp->translate("GUI", "Do you allow the %1 request to be redirected to the following destination?").arg( method2str(method).c_str())); s.append("

"); s.append(str2html(ui->format_sip_address(user_config, display, destination).c_str())); s.append("

"); s.append(qApp->translate("GUI", "If you don't want to be asked this anymore, then you must change " "the settings in the SIP protocol section of the user profile.")); QMessageBox *mb = new QMessageBox(title, s, QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton, mainWindow); MEMMAN_NEW(mb); bool permission = (mb->exec() == QMessageBox::Yes); MEMMAN_DELETE(mb); delete mb; unlock(); return permission; } bool t_gui::cb_ask_credentials(t_user *user_config, const string &realm, string &username, string &password) { QString user(username.c_str()); QString passwd(password.c_str()); lock(); AuthenticationForm *af = new AuthenticationForm(mainWindow, "authentication", true); MEMMAN_NEW(af); if (!af->exec(user_config, QString(realm.c_str()), user, passwd)) { MEMMAN_DELETE(af); delete af; unlock(); return false; } username = user.ascii(); password = passwd.ascii(); MEMMAN_DELETE(af); delete af; unlock(); return true; } void t_gui::cb_ask_user_to_refer(t_user *user_config, const t_url &refer_to_uri, const string &refer_to_display, const t_url &referred_by_uri, const string &referred_by_display) { QString s; QString title; lock(); title = PRODUCT_NAME; title.append(" - ").append(qApp->translate("GUI", "Transferring call")); s = qApp->translate("GUI", "User profile:").append(" "); s.append(user_config->get_profile_name().c_str()); s.append("
").append(qApp->translate("GUI", "User:")).append(" "); s.append(str2html(user_config->get_display_uri().c_str())); s.append("

"); if (referred_by_uri.is_valid()) { s.append(qApp->translate("GUI","Request to transfer call received from:")); s.append("
"); s.append(str2html(format_sip_address(user_config, referred_by_display, referred_by_uri).c_str())); s.append("
"); } else { s.append(qApp->translate("GUI", "Request to transfer call received.")); s.append("
"); } s.append("
"); s.append(qApp->translate("GUI", "Do you allow the call to be transferred to the following destination?")); s.append("

"); s.append(str2html(ui->format_sip_address(user_config, refer_to_display, refer_to_uri).c_str())); s.append("

"); s.append(qApp->translate("GUI", "If you don't want to be asked this anymore, then you must change " "the settings in the SIP protocol section of the user profile.")); ReferPermissionDialog *dialog = new ReferPermissionDialog(mainWindow, title, s); // Do not report to MEMMAN as Qt will auto destruct this dialog on close. dialog->show(); unlock(); } void t_gui::cb_show_msg(const string &msg, t_msg_priority prio) { cb_show_msg(NULL, msg, prio); } void t_gui::cb_show_msg(QWidget *parent, const string &msg, t_msg_priority prio) { lock(); switch (prio) { case MSG_INFO: QMessageBox::information(parent, PRODUCT_NAME, msg.c_str()); break; case MSG_WARNING: QMessageBox::warning(parent, PRODUCT_NAME, msg.c_str()); break; case MSG_CRITICAL: default: QMessageBox::critical(parent, PRODUCT_NAME, msg.c_str()); break; } unlock(); } bool t_gui::cb_ask_msg(const string &msg, t_msg_priority prio) { return cb_ask_msg(NULL, msg, prio); } bool t_gui::cb_ask_msg(QWidget *parent, const string &msg, t_msg_priority prio) { lock(); int button = QMessageBox::No; switch (prio) { case MSG_INFO: button = QMessageBox::information(parent, PRODUCT_NAME, msg.c_str(), QMessageBox::Yes, QMessageBox::No | QMessageBox::Escape | QMessageBox::Default); break; case MSG_WARNING: button = QMessageBox::warning(parent, PRODUCT_NAME, msg.c_str(), QMessageBox::Yes, QMessageBox::No | QMessageBox::Escape | QMessageBox::Default); break; case MSG_CRITICAL: default: button = QMessageBox::critical(parent, PRODUCT_NAME, msg.c_str(), QMessageBox::Yes, QMessageBox::No | QMessageBox::Escape | QMessageBox::Default); break; } unlock(); return (button == QMessageBox::Yes); } void t_gui::cb_display_msg(const string &msg, t_msg_priority prio) { // If this thread may not lock the UI, then push the display message on // the UI event queue. The message will be display asynchronously. if (is_prohibited_thread()) { cb_async_display_msg(msg, prio); return; } QString s; lock(); switch (prio) { case MSG_NO_PRIO: break; case MSG_INFO: s = qApp->translate("GUI", "Info:"); break; case MSG_WARNING: s = qApp->translate("GUI", "Warning:"); break; case MSG_CRITICAL: default: s = qApp->translate("GUI", "Critical:"); break; } if (prio == MSG_NO_PRIO) { s = msg.c_str(); } else { s.append(" ").append(msg.c_str()); } mainWindow->displayHeader(); mainWindow->display(s); unlock(); } void t_gui::cb_log_updated(bool log_zapped) { lock(); mainWindow->updateLog(log_zapped); unlock(); } void t_gui::cb_call_history_updated(void) { lock(); mainWindow->updateCallHistory(); unlock(); } void t_gui::cb_missed_call(int num_missed_calls) { lock(); mainWindow->updateMissedCallStatus(num_missed_calls); unlock(); } void t_gui::cb_nat_discovery_progress_start(int num_steps) { natDiscoveryProgressDialog = new QProgressDialog( qApp->translate("GUI", "Firewall / NAT discovery..."), qApp->translate("GUI", "Abort"), num_steps, NULL, "nat discovery progress", true); MEMMAN_NEW(natDiscoveryProgressDialog); natDiscoveryProgressDialog->setCaption(PRODUCT_NAME); natDiscoveryProgressDialog->setMinimumDuration(200); } void t_gui::cb_nat_discovery_progress_step(int step) { natDiscoveryProgressDialog->setProgress(step); qApp->processEvents(); } void t_gui::cb_nat_discovery_finished(void) { MEMMAN_DELETE(natDiscoveryProgressDialog); delete natDiscoveryProgressDialog; } bool t_gui::cb_nat_discovery_cancelled(void) { return natDiscoveryProgressDialog->wasCancelled(); } void t_gui::cb_line_encrypted(int line, bool encrypted, const string &cipher_mode) { // Nothing todo in GUI // Encryption state is shown by the line state updata methods on // MphoneForm } void t_gui::cb_show_zrtp_sas(int line, const string &sas) { if (line >= NUM_USER_LINES) return; lock(); QString s; setLineFields(line); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1").arg(line + 1); s.append(": SAS = ").append(sas.c_str()); mainWindow->display(s); s = qApp->translate("GUI", "Click the padlock to confirm a correct SAS."); mainWindow->display(s); unlock(); } void t_gui::cb_zrtp_confirm_go_clear(int line) { t_user *user_config = phone->get_line_user(line); if (!user_config) return; QString msg(qApp->translate("GUI", "The remote user on line %1 disabled the encryption.") .arg(line + 1)); if (user_config->get_zrtp_goclear_warning()) { cb_show_msg(msg.ascii(), MSG_WARNING); } else { cb_display_msg(msg.ascii(), MSG_WARNING); } action_zrtp_go_clear_ok(line); } void t_gui::cb_zrtp_sas_confirmed(int line) { lock(); QString s; setLineFields(line); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: SAS confirmed.").arg(line + 1); mainWindow->display(s); unlock(); } void t_gui::cb_zrtp_sas_confirmation_reset(int line) { lock(); QString s; setLineFields(line); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: SAS confirmation reset.").arg(line + 1); mainWindow->display(s); unlock(); } void t_gui::cb_update_mwi(void) { lock(); mainWindow->updateMwi(); unlock(); } void t_gui::cb_mwi_subscribe_failed(t_user *user_config, t_response *r, bool first_failure) { lock(); QString s; if (first_failure) { mainWindow->displayHeader(); s = qApp->translate("GUI", "%1, voice mail status failure.") .arg(user_config->get_profile_name().c_str()); mainWindow->display(s); } unlock(); } void t_gui::cb_mwi_terminated(t_user *user_config, const string &reason) { lock(); QString s; if (reason == "EV_REASON_REJECTED") { s = qApp->translate("GUI", "%1, voice mail status rejected."); } else if (reason == "EV_REASON_NORESOURCE") { s = qApp->translate("GUI", "%1, voice mailbox does not exist."); } else { s = qApp->translate("GUI", "%1, voice mail status terminated."); } mainWindow->displayHeader(); mainWindow->display(s.arg(user_config->get_profile_name().c_str())); unlock(); } bool t_gui::cb_message_request(t_user *user_config, t_request *r) { string text; im::t_text_format text_format = im::TXT_PLAIN; bool attachment = false; bool failed_to_save_attachment = false; string attachment_error_msg; string attachment_saved_name; string attachment_save_as_name; if (!r->body) { log_file->write_report("Missing body.", "t_gui::cb_message_request", LOG_NORMAL, LOG_DEBUG); return true; } // Determine if message should be shown inline or as an attachment if ((r->hdr_content_disp.is_populated() && r->hdr_content_disp.type == "attachment") || (r->body->get_type() == BODY_OPAQUE) || (r->hdr_content_length.is_populated() && r->hdr_content_length.length > im::MAX_INLINE_TEXT_LEN) || (r->body->encode().size() > im::MAX_INLINE_TEXT_LEN)) { attachment = true; string suggested_file_extension = mime2file_extension(r->hdr_content_type.media); if (!sys_config->save_sip_body(*r, suggested_file_extension, attachment_saved_name, attachment_save_as_name, attachment_error_msg)) { failed_to_save_attachment = true; } } else if (r->body->get_type() == BODY_PLAIN_TEXT) { t_sip_body_plain_text *sb = dynamic_cast(r->body); text = sb->text; text_format = im::TXT_PLAIN; } else if (r->body->get_type() == BODY_HTML_TEXT) { t_sip_body_html_text *sb = dynamic_cast(r->body); text = sb->text; text_format = im::TXT_HTML; } else { log_file->write_header("t_gui::cb_message_request", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw("Unsupported content type: "); log_file->write_raw(r->body->get_type()); log_file->write_endl(); log_file->write_footer(); return true; } if (!text.empty()) { string charset = r->hdr_content_type.media.charset; if (!charset.empty() && cmp_nocase(charset, "utf-8") != 0) { // Try to decode the text QTextCodec *c = QTextCodec::codecForName(charset.c_str()); if (c) { text = c->toUnicode(text.c_str()); } else { log_file->write_header( "t_gui::cb_message_request", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Cannot decode charset: "); log_file->write_raw(charset); log_file->write_endl(); log_file->write_footer(); } } } lock(); // Find an existing session im::t_msg_session *session = getMessageSession(user_config, r->hdr_from.uri, r->hdr_from.get_display_presentation()); if (!session) { // There is no session yet. if (messageSessions.size() >= user_config->get_im_max_sessions()) { log_file->write_report( "Maximum number of message sessions reached. Reject message", "t_gui::cb_message_request"); unlock(); return false; } // Create a new session. session = new im::t_msg_session(user_config, t_display_url(r->hdr_from.uri, r->hdr_from.get_display_presentation())); MEMMAN_NEW(session); addMessageSession(session); MessageFormView *view = new MessageFormView(NULL, session); MEMMAN_NEW(view); view->show(); view->raise(); } // Construct message im::t_msg msg; msg.direction = im::MSG_DIR_IN; if (r->hdr_subject.is_populated()) { msg.subject = r->hdr_subject.subject; } if (!text.empty()) { msg.message = text; msg.format = text_format; } if (attachment && !failed_to_save_attachment) { msg.has_attachment = true; msg.attachment_filename = attachment_saved_name; msg.attachment_save_as_name = attachment_save_as_name; msg.attachment_media = r->hdr_content_type.media; } session->recv_msg(msg); // Set error message if attachment could not be saved if (failed_to_save_attachment) { QString s = qApp->translate("GUI", "Failed to save message attachment: %1"); s.arg(attachment_error_msg.c_str()); session->set_error(s.ascii()); } unlock(); return true; } void t_gui::cb_message_response(t_user *user_config, t_response *r, t_request *req) { lock(); // Find session associated with the response im::t_msg_session *session = getMessageSession(user_config, r->hdr_to.uri, r->hdr_to.display); if (session) { if (!r->is_success()) { string s = int2str(r->code); s += ' '; s += r->reason; session->set_error(s); } else { if (r->code == R_202_ACCEPTED) { string s; if (r->reason == REASON_202) { s = qApp->translate("GUI", "Accepted by network").ascii(); } else { s = r->reason; } session->set_delivery_notification(s); } } session->set_msg_in_flight(false); } // If there is no session anymore, then discard the response unlock(); } void t_gui::cb_im_iscomposing_request(t_user *user_config, t_request *r, im::t_composing_state state, time_t refresh) { lock(); // Find an existing session im::t_msg_session *session = getMessageSession(user_config, r->hdr_from.uri, r->hdr_from.get_display_presentation()); if (!session) { // A composing indication does not initiate a new message session. log_file->write_report( "Received composing indication for unknown session.", "t_gui::cb_im_iscomposing_request"); } else { session->set_remote_composing_state(state, refresh); } unlock(); } void t_gui::cb_im_iscomposing_not_supported(t_user *user_config, t_response *r) { lock(); // Find an existing session im::t_msg_session *session = getMessageSession(user_config, r->hdr_to.uri, r->hdr_to.display); if (session) session->set_send_composing_state(false); unlock(); } void t_gui::cmd_call(const string &destination, bool immediate) { string subject; string dst_no_headers; t_display_url du; t_user *user = phone->ref_user_profile( mainWindow->userComboBox->currentText().ascii()); expand_destination(user, destination, du, subject, dst_no_headers); if (!du.is_valid()) return; lock(); if (immediate) { mainWindow->do_phoneInvite(user, du.display.c_str(), du.url, subject.c_str(), false); } else { mainWindow->phoneInvite(dst_no_headers.c_str(), subject.c_str(), false); } unlock(); } void t_gui::cmd_quit(void) { lock(); mainWindow->fileExit(); unlock(); } void t_gui::cmd_show(void) { lock(); if (mainWindow->isMinimized()) { mainWindow->setWindowState(mainWindow->windowState() & ~Qt::WindowMinimized | Qt::WindowActive); mainWindow->raise(); } else { mainWindow->show(); mainWindow->raise(); mainWindow->setActiveWindow(); } unlock(); } void t_gui::cmd_hide(void) { lock(); if (sys_config->get_gui_use_systray()) { mainWindow->hide(); } else { mainWindow->setWindowState(mainWindow->windowState() | Qt::WindowMinimized); } unlock(); } string t_gui::get_name_from_abook(t_user *user_config, const t_url &u) { string name; lock(); // Search local address book first name = t_userintf::get_name_from_abook(user_config, u); // Search KAddressBook if (name.empty()) { t_address_finder *af = t_address_finder::get_instance(); name = af->find_name(user_config, u); } unlock(); return name; } // User invoked actions on the phone object void t_gui::action_register(list user_list) { for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { phone->pub_registration(*i, REG_REGISTER, DUR_REGISTRATION(*i)); } } void t_gui::action_deregister(list user_list, bool dereg_all) { for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if (dereg_all) { phone->pub_registration(*i, REG_DEREGISTER_ALL); } else { phone->pub_registration(*i, REG_DEREGISTER); } } } void t_gui::action_show_registrations(list user_list) { for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { phone->pub_registration(*i, REG_QUERY); } } void t_gui::action_invite(t_user *user_config, const t_url &destination, const string &display, const string &subject, bool anonymous) { QString s; // Call can only be made if line is idle int line = phone->get_active_line(); if (phone->get_line_state(line) == LS_BUSY) return; t_url vm_url(expand_destination(user_config, user_config->get_mwi_vm_address())); if (destination != vm_url) { // Store call info for redial last_called_url = destination; last_called_display = display; last_called_subject = subject; last_called_profile = user_config->get_profile_name(); last_called_hide_user = anonymous; } setLineFields(line); // Set party and subject line fields s = ""; s.append(format_sip_address(user_config, display, destination).c_str()); displayTo(s); s = ""; s.append(format_sip_address(user_config, user_config->get_display(false), user_config->create_user_uri(false)).c_str()); displayFrom(s); displaySubject(subject.c_str()); phone->pub_invite(user_config, destination, display, subject.c_str(), anonymous); } void t_gui::action_answer(void) { cb_stop_call_notification(phone->get_active_line()); phone->pub_answer(); } void t_gui::action_bye(void) { phone->pub_end_call(); } void t_gui::action_reject(void) { QString s; cb_stop_call_notification(phone->get_active_line()); phone->pub_reject(); int line = phone->get_active_line(); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call rejected.").arg(line + 1); mainWindow->display(s); } void t_gui::action_reject(unsigned short line) { QString s; cb_stop_call_notification(line); phone->pub_reject(line); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call rejected.").arg(line + 1); mainWindow->display(s); } void t_gui::action_redirect(const list &contacts) { QString s; cb_stop_call_notification(phone->get_active_line()); phone->pub_redirect(contacts, 302); int line = phone->get_active_line(); mainWindow->displayHeader(); s = qApp->translate("GUI", "Line %1: call redirected.").arg(line + 1); mainWindow->display(s); } void t_gui::action_refer(const t_url &destination, const string &display) { phone->pub_refer(destination, display); } void t_gui::action_refer(unsigned short line_from, unsigned short line_to) { phone->pub_refer(line_from, line_to); } void t_gui::action_setup_consultation_call(const t_url &destination, const string &display) { phone->pub_setup_consultation_call(destination, display); } void t_gui::action_hold(void) { phone->pub_hold(); } void t_gui::action_retrieve(void) { phone->pub_retrieve(); } void t_gui::action_conference(void) { if (!phone->join_3way(0, 1)) { mainWindow->display(qApp->translate("GUI", "Failed to start conference.")); } } void t_gui::action_mute(bool on) { phone->mute(on); } void t_gui::action_options(void) { phone->pub_options(); } void t_gui::action_options(t_user *user_config, const t_url &contact) { phone->pub_options(user_config, contact); } void t_gui::action_dtmf(const string &digits) { const t_call_info call_info = phone->get_call_info(phone->get_active_line()); throttle_dtmf_not_supported = false; if (!call_info.dtmf_supported) return; for (string::const_iterator i = digits.begin(); i != digits.end(); i++) { if (VALID_DTMF_SYM(*i)) { phone->pub_send_dtmf(*i, call_info.dtmf_inband, call_info.dtmf_info); } } } void t_gui::action_activate_line(unsigned short line) { phone->pub_activate_line(line); } bool t_gui::action_seize(void) { return phone->pub_seize(); } void t_gui::action_unseize(void) { phone->pub_unseize(); } void t_gui::action_confirm_zrtp_sas(int line) { phone->pub_confirm_zrtp_sas(line); } void t_gui::action_confirm_zrtp_sas() { phone->pub_confirm_zrtp_sas(); } void t_gui::action_reset_zrtp_sas_confirmation(int line) { phone->pub_reset_zrtp_sas_confirmation(line); } void t_gui::action_reset_zrtp_sas_confirmation() { phone->pub_reset_zrtp_sas_confirmation(); } void t_gui::action_enable_zrtp(void) { phone->pub_enable_zrtp(); } void t_gui::action_zrtp_request_go_clear(void) { phone->pub_zrtp_request_go_clear(); } void t_gui::action_zrtp_go_clear_ok(unsigned short line) { phone->pub_zrtp_go_clear_ok(line); } void t_gui::srv_dnd(list user_list, bool on) { for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if (on) { phone->ref_service(*i)->enable_dnd(); } else { phone->ref_service(*i)->disable_dnd(); } } } void t_gui::srv_enable_cf(t_user *user_config, t_cf_type cf_type, const list &cf_dest) { phone->ref_service(user_config)->enable_cf(cf_type, cf_dest); } void t_gui::srv_disable_cf(t_user *user_config, t_cf_type cf_type) { phone->ref_service(user_config)->disable_cf(cf_type); } void t_gui::srv_auto_answer(list user_list, bool on) { for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { phone->ref_service(*i)->enable_auto_answer(on); } } void t_gui::fill_user_combo(QComboBox *cb) { cb->clear(); list user_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { // OLD code: used display uri // cb->insertItem((*i)->get_display_uri().c_str()); cb->insertItem((*i)->get_profile_name().c_str()); } cb->setCurrentItem(0); } QString t_gui::get_last_file_browse_path(void) const { return lastFileBrowsePath; } void t_gui::set_last_file_browse_path(QString path) { lock(); lastFileBrowsePath = path; unlock(); } #ifdef HAVE_KDE unsigned short t_gui::get_line_sys_tray_popup(void) const { return line_sys_tray_popup; } #endif im::t_msg_session *t_gui::getMessageSession(t_user *user_config, const t_url &remote_url, const string &display) const { for (list::const_iterator it = messageSessions.begin(); it != messageSessions.end(); ++it) { if ((*it)->match(user_config, remote_url)) { (*it)->set_display_if_empty(display); return *it; } } return NULL; } void t_gui::addMessageSession(im::t_msg_session *s) { messageSessions.push_back(s); if (!timerUpdateMessageSessions) { timerUpdateMessageSessions = new QTimer(); MEMMAN_NEW(timerUpdateMessageSessions); connect(timerUpdateMessageSessions, SIGNAL(timeout()), this, SLOT(updateTimersMessageSessions())); timerUpdateMessageSessions->start(1000); } } void t_gui::removeMessageSession(im::t_msg_session *s) { messageSessions.remove(s); if (messageSessions.empty()) { timerUpdateMessageSessions->stop(); MEMMAN_DELETE(timerUpdateMessageSessions); delete timerUpdateMessageSessions; timerUpdateMessageSessions = NULL; } } void t_gui::destroyAllMessageSessions(void) { if (timerUpdateMessageSessions) { MEMMAN_DELETE(timerUpdateMessageSessions); delete timerUpdateMessageSessions; timerUpdateMessageSessions = NULL; } for (list::iterator it = messageSessions.begin(); it != messageSessions.end(); ++it) { MEMMAN_DELETE(*it); delete *it; } messageSessions.clear(); } void t_gui::updateTimersMessageSessions() { for (list::iterator it = messageSessions.begin(); it != messageSessions.end(); ++it) { (*it)->dec_local_composing_timeout(); (*it)->dec_remote_composing_timeout(); } } string t_gui::mime2file_extension(t_media media) { string extension; #ifdef HAVE_KDE // If KDE is available then use KDE to retrieve the proper file // extension so we nicely integrate with the desktop settings. string mime = media.type + "/" + media.subtype; KMimeType::Ptr pMime = KMimeType::mimeType(mime.c_str()); const QStringList &patterns = pMime->patterns(); if (!patterns.empty()) { extension = patterns.front().ascii(); } else { log_file->write_header("t_gui::mime2file_extension", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Cannot find file extension for mime type "); log_file->write_raw(mime); log_file->write_footer(); } #endif return extension; } void t_gui::open_url_in_browser(const QString &url) { string sys_browser = sys_config->get_gui_browser_cmd(); #ifdef HAVE_KDE if (sys_browser.empty()) { KTrader::OfferList offers = KTrader::self()->query("text/html", "Type == 'Application'"); if (!offers.empty()) { KService::Ptr ptr = offers.first(); KURL::List lst; lst.append(url); KRun::run(*ptr, lst); return; } } #endif QProcess process; bool process_started = false; QStringList browsers; if (sys_browser.empty()) { browsers << "firefox" << "mozilla" << "netscape" << "opera"; browsers << "galeon" << "epiphany" << "konqueror"; } else { browsers << sys_browser.c_str(); } for (QStringList::Iterator it = browsers.begin(); it != browsers.end(); ++it) { process.setArguments(QStringList() << *it << url); process_started = process.start(); if (process_started) break; } if (!process_started) { QString msg = qApp->translate("GUI", "Cannot open web browser: %1").arg(url); msg += "\n\n"; msg += qApp->translate("GUI", "Configure your web browser in the system settings."); cb_show_msg(msg.ascii(), MSG_CRITICAL); } } twinkle-1.4.2/src/gui/qt_translator.h0000644000175000001440000000253511134645315014541 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _QT_TRANSLATOR_H #define _QT_TRANSLATOR_H #include #include "translator.h" // This class provides the translation service from Qt to the // core of Twinkle. class t_qt_translator : public t_translator { public: t_qt_translator(QApplication *qa) : _qa(qa) {}; virtual string translate(const string &s) { return _qa->translate("TwinkleCore", s.c_str()).ascii(); }; virtual string translate2(const string &context, const string &s) { return _qa->translate(context.c_str(), s.c_str()).ascii(); }; private: QApplication *_qa; }; #endif twinkle-1.4.2/src/gui/mphoneform.ui0000644000175000001440000045746211150577512014222 00000000000000 MphoneForm MphoneForm true 0 0 739 693 5 5 0 0 714 693 Twinkle twinkle16.png false false true unnamed splitter2 Horizontal Buddy list false false buddyListView 7 7 150 0 0 0 true LastColumn You can create a separate buddy list for each user profile. You can only see availability of your buddies and publish your own availability if your provider offers a presence server. layout13 unnamed layout76 unnamed callTextLabel &Call: Label in front of combobox to enter address callComboBox layout71 unnamed callComboBox 3 0 0 0 true 10 NoInsertion true The address that you want to call. This can be a full SIP address like <b>sip:example@example.com</b> or just the user part or telephone number of the full address. When you do not specify a full address, then Twinkle will complete the address by using the domain value of your user profile. addressToolButton TabFocus F10 kontact_contacts.png Address book Select an address from the address book. callPushButton Dial true Dial the address. userLabel &User: userComboBox layout75 unnamed userComboBox 3 0 0 0 The user that will make the call. layout74 unnamed statAaLabel 0 0 0 0 13 Plain auto_answer.png Auto answer indication. statCfLabel 0 0 0 0 13 cf.png Call redirect indication. statDndLabel 0 0 0 0 13 cancel.png Do not disturb indication. statMWILabel 0 0 0 0 13 Plain mwi_none16.png Message waiting indication. statMissedLabel 0 0 0 0 13 missed.png Missed call indication. statRegLabel 0 0 0 0 13 twinkle16.png Registration status. displayGroupBox 5 5 0 0 Display unnamed displayTextEdit 7 3 0 0 AlwaysOn PlainText NoWrap true AutoAll lineButtonGroup 5 5 0 0 Line status true unnamed layout20 unnamed layout27 unnamed line1RadioButton 0 0 0 0 Line &1: Alt+1 true Click to switch to line 1. fromhead1Label 0 5 0 0 From: 21 tohead1Label 0 5 0 0 To: 21 subjecthead1Label 0 5 0 0 Subject: 21 layout19 unnamed layout17 unnamed line1StatLabel 0 5 0 0 0 NoFrame Plain 1 stat_ringing.png Visual indication of line state. status1TextLabel 5 5 0 0 85 0 255 idle No need to translate RichText line1HoldLabel 0 5 0 0 0 NoFrame Plain 1 hold.png Call is on hold line1MuteLabel 0 5 0 0 0 NoFrame Plain 1 stat_mute.png Voice is muted line1ConfLabel 0 5 0 0 0 NoFrame Plain 1 stat_conference.png Conference call line1ReferLabel 0 5 0 0 0 NoFrame Plain 1 cf.png Transferring call crypt1Label 0 5 0 0 13 Panel Raised 1 encrypted.png <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> line1SasLabel 0 5 0 0 sas No need to translate Short authentication string codec1TextLabel 0 5 0 0 0 170 127 g711a/g711a No need to translate AlignVCenter|AlignRight Audio codec timer1TextLabel 0 5 0 0 Courier New 0:00:00 Call duration from1Label 85 0 255 238 234 238 NoFocus NoFrame sip:from No need to translate AlignAuto true to1Label 85 0 255 238 234 238 NoFocus NoFrame sip:to No need to translate true subject1Label 85 0 255 238 234 238 NoFocus NoFrame subject No need to translate true photo1Label 0 0 0 0 70 98 70 98 Box photo No need to translate layout22 unnamed layout31 unnamed line2RadioButton 0 0 0 0 Line &2: Alt+2 Click to switch to line 2. fromhead2Label 0 5 0 0 From: 21 tohead2Label 0 5 0 0 To: 21 subjecthead2Label 0 5 0 0 Subject: 21 layout21 unnamed layout18 unnamed line2StatLabel 0 5 0 0 0 NoFrame Plain 1 stat_ringing.png Visual indication of line state. status2TextLabel 5 5 0 0 85 0 255 idle No need to translate RichText line2HoldLabel 0 5 0 0 0 NoFrame Plain 1 hold.png Call is on hold line2MuteLabel 0 5 0 0 0 NoFrame Plain 1 stat_mute.png Voice is muted line2ConfLabel 0 5 0 0 0 NoFrame Plain 1 stat_conference.png Conference call line2ReferLabel 0 5 0 0 0 NoFrame Plain 1 cf.png Transferring call crypt2Label 0 5 0 0 13 Panel Raised 1 encrypted.png <p> The padlock indicates that your voice is encrypted during transport over the network. </p> <h3>SAS - Short Authentication String</h3> <p> Both ends of an encrypted voice channel receive the same SAS on the first call. If the SAS is different at each end, your voice channel may be compromised by a man-in-the-middle attack (MitM). </p> <p> If the SAS is equal at both ends, then you should confirm it by clicking this padlock for stronger security of future calls to the same destination. For subsequent calls to the same destination, you don't have to confirm the SAS again. The padlock will show a check symbol when the SAS has been confirmed. </p> line2SasLabel 0 5 0 0 sas No need to translate Short authentication string codec2TextLabel 0 5 0 0 0 170 127 g711a/g711a No need to translate AlignVCenter|AlignRight Audio codec timer2TextLabel 0 5 0 0 Courier New 0:00:00 Call duration from2Label 85 0 255 238 234 238 NoFocus NoFrame sip:from No need to translate true to2Label 85 0 255 238 234 238 NoFocus NoFrame sip:to No need to translate true subject2Label 85 0 255 238 234 238 NoFocus NoFrame subject No need to translate true photo2Label 0 0 0 0 70 98 70 98 Box photo No need to translate menubar callToolbar false true true true Call Toolbar fileExitAction exit.png Quit &Quit Ctrl+Q helpAboutAction twinkle16.png About Twinkle &About Twinkle callInvite invite.png Call toolbar text &Call... call menu text Call someone F5 callAnswer answer.png Answer toolbar text &Answer menu text Answer incoming call F6 callBye bye.png Bye toolbar text &Bye menu text Release call Esc callReject reject.png Reject toolbar text &Reject menu text Reject incoming call F8 callHold true hold.png Hold toolbar text &Hold menu text Put a call on hold, or retrieve a held call callRedirect redirect.png Redirect toolbar text R&edirect... menu text Redirect incoming call without answering callDTMF dtmf.png Dtmf toolbar text &Dtmf... menu text Open keypad to enter digits for voice menu's regRegister twinkle16.png Register &Register regDeregister twinkle16-disabled.png Deregister &Deregister Deregister this device regShow reg-query.png Show registrations &Show registrations callTermCap Terminal capabilities &Terminal capabilities... menu text Request terminal capabilities from someone serviceDnd true cancel.png Do not disturb &Do not disturb serviceRedirection cf.png Call redirection Call &redirection... callRedial redial.png Redial toolbar text &Redial menu text Repeat last call F12 helpAboutQtAction qt-logo.png About Qt About &Qt editUserProfileAction penguin-small.png User profile &User profile... callConference conf.png Conf toolbar text &Conference menu text Join two calls in a 3-way conference callMute true mute.png Mute toolbar text &Mute menu text Mute a call callTransfer true transfer.png Xfer toolbar text Trans&fer... menu text Transfer call editSysSettingsAction settings.png System settings &System settings... registrationAction regDeregisterAll twinkle16-disabled.png Deregister all Deregister &all Deregister all your registered devices serviceAutoAnswer true auto_answer.png Auto answer &Auto answer viewLogAction log_small.png Log &Log... viewCall_HistoryAction missed.png Call history Call &history... F9 fileChangeUserAction penguin-small.png Change user ... &Change user ... Activate or de-activate users helpWhats_ThisAction contexthelp.png What's This? What's &This? Shift+F1 actgrActivateLine false Activate line false actionLine1 true true Line 1 actionLine2 true Line 2 callActivate_LineAction false Activate line Activate line viewDisplayAction true true Display &Display servicesVoice_mailAction mwi_none16.png Voice mail &Voice mail Access voice mail F11 actionSendMsg message.png Msg Instant &message... Instant message viewBuddyListAction true true Buddy list &Buddy list Buddy list helpManualAction Manual &Manual diamondcardSign_upAction Sign up &Sign up... Sign up helpWhats_ThisAction activated() MphoneForm whatsThis() addressToolButton clicked() MphoneForm showAddressBook() callPushButton clicked() MphoneForm quickCall() fileChangeUserAction activated() MphoneForm selectProfile() viewCall_HistoryAction activated() MphoneForm viewHistory() viewLogAction activated() MphoneForm viewLog() regDeregisterAll activated() MphoneForm phoneDeregisterAll() editSysSettingsAction activated() MphoneForm editSysSettings() callMute toggled(bool) MphoneForm phoneMute(bool) callConference activated() MphoneForm phoneConference() editUserProfileAction activated() MphoneForm editUserProfile() helpAboutQtAction activated() MphoneForm aboutQt() helpAboutAction activated() MphoneForm about() callRedial activated() MphoneForm phoneRedial() serviceRedirection activated() MphoneForm srvRedirect() regShow activated() MphoneForm phoneShowRegistrations() regDeregister activated() MphoneForm phoneDeregister() regRegister activated() MphoneForm phoneRegister() callHold toggled(bool) MphoneForm phoneHold(bool) callReject activated() MphoneForm phoneReject() callRedirect activated() MphoneForm phoneRedirect() callInvite activated() MphoneForm phoneInvite() callDTMF activated() MphoneForm phoneDTMF() callBye activated() MphoneForm phoneBye() callAnswer activated() MphoneForm phoneAnswer() callTermCap activated() MphoneForm phoneTermCap() line2RadioButton toggled(bool) MphoneForm line2rbChangedState(bool) line1RadioButton toggled(bool) MphoneForm line1rbChangedState(bool) fileExitAction activated() MphoneForm fileExit() actionLine1 toggled(bool) MphoneForm actionLine1Toggled(bool) actionLine2 toggled(bool) MphoneForm actionLine2Toggled(bool) viewDisplayAction toggled(bool) MphoneForm showDisplay(bool) callTransfer activated() MphoneForm phoneTransfer() servicesVoice_mailAction activated() MphoneForm popupMenuVoiceMail() actionSendMsg activated() MphoneForm startMessageSession() buddyListView rightButtonPressed(QListViewItem*,const QPoint&,int) MphoneForm showBuddyListPopupMenu(QListViewItem*,const QPoint&) buddyListView doubleClicked(QListViewItem*) MphoneForm doMessageBuddy(QListViewItem*) viewBuddyListAction toggled(bool) MphoneForm showBuddyList(bool) helpManualAction activated() MphoneForm manual() diamondcardSign_upAction activated() MphoneForm DiamondcardSignUp() callComboBox addressToolButton callPushButton displayTextEdit line1RadioButton line2RadioButton userComboBox from1Label subject1Label to1Label subject2Label from2Label to2Label phone.h dtmfform.h inviteform.h redirectform.h termcapform.h srvredirectform.h userprofileform.h transferform.h syssettingsform.h logviewform.h historyform.h selectuserform.h selectprofileform.h qevent.h twinklesystray.h im/msg_session.h messageformview.h buddylistview.h diamondcard.h user.h qtextedit.h qcheckbox.h qapplication.h gui.h qpixmap.h qiconset.h qmessagebox.h audits/memman.h line.h stun/stun_transaction.h log.h qprogressdialog.h util.h qtimer.h sys/time.h qframe.h qcursor.h qregexp.h qvalidator.h buddyform.h diamondcardprofileform.h mphoneform.ui.h extern t_phone *phone; QTimer tmrFlashMWI; GetAddressForm *getAddressForm; SelectProfileForm *selectProfileForm; SelectUserForm *selectUserForm; HistoryForm *historyForm; TransferForm *transferForm; UserProfileForm *userProfileForm; SrvRedirectForm *srvRedirectForm; TermCapForm *termCapForm; RedirectForm *redirectForm; InviteForm *inviteForm; DtmfForm *dtmfForm; SysSettingsForm *sysSettingsForm; QStringList displayContents; LogViewForm *logViewForm; t_twinkle_sys_tray *sysTray; QTimer *lineTimer1; QTimer *lineTimer2; QTimer *hideLineTimer1; QTimer *hideLineTimer2; bool viewDisplay; bool viewCompactLineStatus; bool mwiFlashStatus; QPopupMenu *buddyPopupMenu; QPopupMenu *buddyListPopupMenu; QPopupMenu *changeAvailabilityPopupMenu; QToolTip *buddyToolTip; bool viewBuddyList; closeEvent( QCloseEvent * e ) fileExit() display( const QString & s ) displayHeader() showLineTimer( int line ) showLineTimer1() showLineTimer2() updateLineTimer( int line ) updateLineEncryptionState( int line ) updateLineStatus( int line ) updateState() updateRegStatus() flashMWI() updateMwi() updateServicesStatus() updateMissedCallStatus( int num_missed_calls ) updateSysTrayStatus() updateMenuStatus() updateDiamondcardMenu() removeDiamondcardAction( int & id ) removeDiamondcardMenu( QPopupMenu * & menu ) phoneRegister() do_phoneRegister( list<t_user *> user_list ) phoneDeregister() do_phoneDeregister( list<t_user *> user_list ) phoneDeregisterAll() do_phoneDeregisterAll( list<t_user *> user_list ) phoneShowRegistrations() phoneInvite( t_user * user_config, const QString & dest, const QString & subject, bool anonymous ) phoneInvite( const QString & dest, const QString & subject, bool anonymous ) phoneInvite() do_phoneInvite( t_user * user_config, const QString & display, const t_url & destination, const QString & subject, bool anonymous ) phoneRedial( void ) phoneAnswer() phoneAnswerFromSystrayPopup() phoneBye() phoneReject() phoneRejectFromSystrayPopup() phoneRedirect( const list<string> & contacts ) phoneRedirect() do_phoneRedirect( const list<t_display_url> & destinations ) phoneTransfer( const string & dest, t_transfer_type transfer_type ) phoneTransfer() do_phoneTransfer( const t_display_url & destination, t_transfer_type transfer_type ) do_phoneTransferLine() phoneHold( bool on ) phoneConference() phoneMute( bool on ) phoneTermCap( const QString & dest ) phoneTermCap() do_phoneTermCap( t_user * user_config, const t_url & destination ) phoneDTMF() sendDTMF( const QString & digits ) startMessageSession( void ) startMessageSession( t_buddy * buddy ) phoneConfirmZrtpSas( int line ) phoneConfirmZrtpSas() phoneResetZrtpSasConfirmation( int line ) phoneResetZrtpSasConfirmation() phoneEnableZrtp( bool on ) phoneZrtpGoClearOk( unsigned short line ) line1rbChangedState( bool on ) line2rbChangedState( bool on ) actionLine1Toggled( bool on ) actionLine2Toggled( bool on ) srvDnd( bool on ) srvDnd() do_srvDnd_enable( list<t_user *> user_list ) do_srvDnd_disable( list<t_user *> user_list ) srvAutoAnswer( bool on ) srvAutoAnswer() do_srvAutoAnswer_enable( list<t_user *> user_list ) do_srvAutoAnswer_disable( list<t_user *> user_list ) srvRedirect() do_srvRedirect( t_user * user_config, const list<t_display_url> & always, const list<t_display_url> & busy, const list<t_display_url> & noanswer ) about() aboutQt() manual() editUserProfile() editSysSettings() selectProfile() newUsers( const list<string> & profiles ) updateUserComboBox() updateSipUdpPort() updateRtpPorts() updateStunSettings( t_user * user_config ) updateAuthCache( t_user * user_config, const string & realm ) unsubscribeMWI( t_user * user_config ) subscribeMWI( t_user * user_config ) viewLog() updateLog( bool log_zapped ) viewHistory() updateCallHistory() quickCall() addToCallComboBox( const QString & destination ) showAddressBook() selectedAddress( const QString & address ) enableCallOptions( bool enable ) keyPressEvent( QKeyEvent * e ) mouseReleaseEvent( QMouseEvent * e ) processLeftMouseButtonRelease( QMouseEvent * e ) processRightMouseButtonRelease( QMouseEvent * e ) processCryptLabelClick( int line ) popupMenuVoiceMail( const QPoint & pos ) popupMenuVoiceMail( void ) showDisplay( bool on ) showBuddyList( bool on ) showCompactLineStatus( bool on ) populateBuddyList() showBuddyListPopupMenu( QListViewItem * item, const QPoint & pos ) doCallBuddy() doMessageBuddy( QListViewItem * qitem ) doMessageBuddy() doEditBuddy() doDeleteBuddy() doAddBuddy() doAvailabilityOffline() doAvailabilityOnline() DiamondcardSignUp() newDiamondcardUser( const QString & filename ) DiamondcardAction( t_dc_action action, int userIdx ) DiamondcardRecharge( int userIdx ) DiamondcardBalanceHistory( int userIdx ) DiamondcardCallHistory( int userIdx ) DiamondcardAdminCenter( int userIdx ) init() destroy() lineSubstate2str( int line ) getMWIStatus( const t_mwi & mwi, bool & msg_waiting ) const getSysTray() getViewDisplay() getViewBuddyList() getViewCompactLineStatus() twinkle-1.4.2/src/gui/getaddressform.ui.h0000644000175000001440000001526111127714045015270 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define TAB_KABC 0 #define TAB_LOCAL 1 #ifdef HAVE_KDE #include #include #include #include #include #define ABOOK ((KABC::AddressBook *)addrBook) // Column numbers #define AB_COL_NAME 0 #define AB_COL_PHONE 2 #endif void GetAddressForm::init() { #ifdef HAVE_KDE addrBook = (void *)KABC::StdAddressBook::self(false); loadAddresses(); connect(ABOOK, SIGNAL(addressBookChanged(AddressBook *)), this, SLOT(loadAddresses())); sipOnlyCheckBox->setChecked(sys_config->get_ab_show_sip_only()); #else addressTabWidget->setTabEnabled(tabKABC, false); addressTabWidget->setCurrentPage(TAB_LOCAL); #endif loadLocalAddresses(); } void GetAddressForm::reload() { #ifdef HAVE_KDE ABOOK->disconnect(); KABC::StdAddressBook::close(); addrBook = (void *)KABC::StdAddressBook::self(false); loadAddresses(); connect(ABOOK, SIGNAL(addressBookChanged(AddressBook *)), this, SLOT(loadAddresses())); #endif } void GetAddressForm::show() { QDialog::show(); #ifdef HAVE_KDE if (addressListView->childCount() == 0) { if (localListView->childCount() == 0) { QMessageBox::information(this, PRODUCT_NAME, tr( "

" "You seem not to have any contacts with a phone number " "in KAddressBook, KDE's address book application. " "Twinkle retrieves all contacts with a phone number from " "KAddressBook. To manage your contacts you have to " "use KAddressBook." "

" "As an alternative you may use Twinkle's local address book." "

")); } else { addressTabWidget->setCurrentPage(TAB_LOCAL); } } #endif } void GetAddressForm::loadAddresses() { #ifdef HAVE_KDE // Explicit loading of address book is not needed as it is // automatically loaded. // if (!ABOOK->load()) return; addressListView->clear(); for (KABC::AddressBook::Iterator i = ABOOK->begin(); i != ABOOK->end(); i++) { KABC::PhoneNumber::List phoneNrs = i->phoneNumbers(); for (KABC::PhoneNumber::List::iterator j = phoneNrs.begin(); j != phoneNrs.end(); j++) { QString phone = (*j).number(); if (!sys_config->get_ab_show_sip_only() || phone.startsWith("sip:")) { new QListViewItem(addressListView, i->realName(), (*j).typeLabel(), phone); } } } QListViewItem *first = addressListView->firstChild(); if (first) addressListView->setSelected(first, true); #endif } void GetAddressForm::loadLocalAddresses() { localListView->clear(); const list &address_list = ab_local->get_address_list(); for(list::const_iterator i = address_list.begin(); i != address_list.end(); i++) { new AddressListViewItem(localListView, *i); } QListViewItem *first = localListView->firstChild(); if (first) localListView->setSelected(first, true); } void GetAddressForm::selectAddress() { if (addressTabWidget->currentPageIndex() == TAB_KABC) { selectKABCAddress(); } else { selectLocalAddress(); } } void GetAddressForm::selectKABCAddress() { #ifdef HAVE_KDE QListViewItem *item = addressListView->selectedItem(); if (item) { QString name(item->text(AB_COL_NAME)); QString phone(item->text(AB_COL_PHONE)); phone = phone.stripWhiteSpace(); emit address(name, phone); // Signal display name and url combined. t_display_url du(t_url(phone.ascii()), name.ascii()); emit address(du.encode().c_str()); } accept(); #endif } void GetAddressForm::selectLocalAddress() { AddressListViewItem *item = dynamic_cast( localListView->selectedItem()); if (item) { t_address_card card = item->getAddressCard(); emit(card.get_display_name().c_str(), card.sip_address.c_str()); // Signal display name and url combined. t_display_url du(t_url(card.sip_address), card.get_display_name()); emit address(du.encode().c_str()); } accept(); } void GetAddressForm::toggleSipOnly(bool on) { #ifdef HAVE_KDE string msg; sys_config->set_ab_show_sip_only(on); // Ignore write failures. If for some reason the system config // could not be written, then this settings is lost after exiting Twinkle. // No need to bother the user at this point. (void)sys_config->write_config(msg); loadAddresses(); #endif } void GetAddressForm::addLocalAddress() { t_address_card card; AddressCardForm f; if (f.exec(card)) { ab_local->add_address(card); new AddressListViewItem(localListView, card); string error_msg; if (!ab_local->save(error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); } } } void GetAddressForm::deleteLocalAddress() { AddressListViewItem *item = dynamic_cast( localListView->selectedItem()); if (item) { t_address_card card = item->getAddressCard(); if (ab_local->del_address(card)) { delete item; string error_msg; if (!ab_local->save(error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); } } } } void GetAddressForm::editLocalAddress() { AddressListViewItem *item = dynamic_cast( localListView->selectedItem()); if (!item) return; t_address_card oldCard = item->getAddressCard(); t_address_card newCard = oldCard; AddressCardForm f; if (f.exec(newCard)) { if (ab_local->update_address(oldCard, newCard)) { item->update(newCard); string error_msg; if (!ab_local->save(error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); } } } } twinkle-1.4.2/src/gui/logviewform.ui.h0000644000175000001440000000467211127714045014623 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void LogViewForm::show() { if (isShown()) { raise(); return; } QString fname = log_file->get_filename().c_str(); logfile = new QFile(fname); MEMMAN_NEW(logfile); logstream = NULL; if (logfile->open(IO_ReadOnly)) { logstream = new QTextStream(logfile); MEMMAN_NEW(logstream); logTextEdit->setText(logstream->read()); // Set cursor position at the end of text logTextEdit->scrollToBottom(); } log_file->enable_inform_user(true); QDialog::show(); raise(); } void LogViewForm::closeEvent( QCloseEvent *ev ) { log_file->enable_inform_user(false); logTextEdit->clear(); if (logstream) { MEMMAN_DELETE(logstream); delete logstream; logstream = NULL; } logfile->close(); MEMMAN_DELETE(logfile); delete logfile; logfile = NULL; QDialog::closeEvent(ev); } void LogViewForm::update(bool log_zapped) { if (!isShown()) return; if (log_zapped) { close(); show(); return; } if (logstream) { QString s = logstream->read(); if (!s.isNull() && !s.isEmpty()) { logTextEdit->append(s); } } } void LogViewForm::clear() { logTextEdit->clear(); } twinkle-1.4.2/src/gui/messageformview.cpp0000644000175000001440000001041111127714053015370 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "messageformview.h" #include "gui.h" #include "audits/memman.h" MessageFormView::MessageFormView(QWidget *parent, im::t_msg_session *s) : MessageForm(parent), t_observer() { _msgSession = s; _msgSession->attach(this); _destructing = false; } MessageFormView::~MessageFormView() { _destructing = true; if (_msgSession) { ((t_gui *)ui)->removeMessageSession(_msgSession); MEMMAN_DELETE(_msgSession); delete _msgSession; } } void MessageFormView::updatePartyInfo(void) { t_user *user_config = _msgSession->get_user(); selectUserConfig(user_config); t_display_url to_url = _msgSession->get_remote_party(); if (to_url.is_valid()) { toLineEdit->setText(ui->format_sip_address(user_config, to_url.display, to_url.url).c_str()); } else { toLineEdit->clear(); } } void MessageFormView::update(void) { // Called directly from core, so lock GUI ui->lock(); updatePartyInfo(); setRemotePartyCaption(); t_user *user_config = _msgSession->get_user(); t_display_url to_url = _msgSession->get_remote_party(); // Update msgLineEdit field based on msg-in-flight indication if (!_msgSession->is_msg_in_flight() && !msgLineEdit->isEnabled()) { msgLineEdit->clear(); // When the user edits the message, the composition indication // will be set to active. connect(msgLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(setLocalComposingIndicationActive())); // Enable msgLineEdit first, otherwise the setFocus does not work msgLineEdit->setEnabled(true); msgLineEdit->setFocus(); } else if (_msgSession->is_msg_in_flight() && msgLineEdit->isEnabled()) { // Disable the triggering of the composition indication while a message // is being sent. disconnect(msgLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(setLocalComposingIndicationActive())); msgLineEdit->setText(tr("sending message")); } // Enable/disable msgLineEdit here to be robust, such that msgLineEdit // does not stay disabled forever. msgLineEdit->setEnabled(!_msgSession->is_msg_in_flight()); sendFileAction->setEnabled(!_msgSession->is_msg_in_flight()); // Display error if (_msgSession->error_received()) { string error_msg = _msgSession->take_error(); displayError(error_msg.c_str()); } // Display delivery notification if (_msgSession->delivery_notification_received()) { string notification = _msgSession->take_delivery_notification(); displayDeliveryNotification(notification.c_str()); } // Display message composing indication if (_msgSession->get_remote_composing_state() == im::COMPOSING_STATE_ACTIVE) { QString name = to_url.display.c_str(); if (name.isEmpty()) { name = to_url.url.get_user().c_str(); } setComposingIndication(name); } else { clearComposingIndication(); } // Display message if (_msgSession->is_new_message_added()) { im::t_msg m; try { m = _msgSession->get_last_message(); } catch (empty_list_exception) { ui->unlock(); return; } QString name; if (m.direction == im::MSG_DIR_IN) { name = to_url.display.c_str(); if (name.isEmpty()) { name = to_url.url.get_user().c_str(); } } else { name = user_config->get_display(false).c_str(); if (name.isEmpty()) { name = user_config->get_name().c_str(); } } addMessage(m, name); } ui->unlock(); } void MessageFormView::subject_destroyed() { _msgSession = NULL; if (!_destructing) close(); } void MessageFormView::show() { ((t_gui *)ui)->fill_user_combo(fromComboBox); updatePartyInfo(); MessageForm::show(); } twinkle-1.4.2/src/gui/dtmfform.ui0000644000175000001440000004524410503576707013663 00000000000000 DtmfForm DtmfForm 0 0 350 302 5 5 0 0 Twinkle - DTMF unnamed keypadGroupBox Keypad unnamed twoPushButton 10 dtmf-2.png 2 threePushButton 10 dtmf-3.png 3 aPushButton 194 202 210 dtmf-a.png Over decadic A. Normally not needed. fourPushButton dtmf-4.png 4 fivePushButton dtmf-5.png 5 sixPushButton dtmf-6.png 6 bPushButton 194 202 210 dtmf-b.png Over decadic B. Normally not needed. sevenPushButton dtmf-7.png 7 eightPushButton dtmf-8.png 8 ninePushButton dtmf-9.png 9 cPushButton 194 202 210 dtmf-c.png Over decadic C. Normally not needed. starPushButton dtmf-star.png Star (*) zeroPushButton dtmf-0.png 0 poundPushButton dtmf-pound.png Pound (#) dPushButton 194 202 210 dtmf-d.png Over decadic D. Normally not needed. onePushButton 10 dtmf-1.png true 1 layout24 unnamed spacer20 Horizontal Expanding 291 20 closePushButton &Close Alt+C true closePushButton clicked() DtmfForm accept() onePushButton clicked() DtmfForm dtmf1() twoPushButton clicked() DtmfForm dtmf2() threePushButton clicked() DtmfForm dtmf3() fourPushButton clicked() DtmfForm dtmf4() fivePushButton clicked() DtmfForm dtmf5() sixPushButton clicked() DtmfForm dtmf6() sevenPushButton clicked() DtmfForm dtmf7() eightPushButton clicked() DtmfForm dtmf8() ninePushButton clicked() DtmfForm dtmf9() zeroPushButton clicked() DtmfForm dtmf0() starPushButton clicked() DtmfForm dtmfStar() poundPushButton clicked() DtmfForm dtmfPound() aPushButton clicked() DtmfForm dtmfA() bPushButton clicked() DtmfForm dtmfB() cPushButton clicked() DtmfForm dtmfC() dPushButton clicked() DtmfForm dtmfD() onePushButton twoPushButton threePushButton aPushButton fourPushButton fivePushButton sixPushButton bPushButton sevenPushButton eightPushButton ninePushButton cPushButton starPushButton zeroPushButton poundPushButton dPushButton closePushButton qregexp.h qvalidator.h qlineedit.h dtmfform.ui.h digits(const QString &) dtmf1() dtmf2() dtmf3() dtmf4() dtmf5() dtmf6() dtmf7() dtmf8() dtmf9() dtmf0() dtmfStar() dtmfPound() dtmfA() dtmfB() dtmfC() dtmfD() keyPressEvent( QKeyEvent * e ) twinkle-1.4.2/src/gui/yesnodialog.cpp0000644000175000001440000000465011127714053014512 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "yesnodialog.h" #include "qlabel.h" #include "qlayout.h" #include "userintf.h" // class YesNoDialog void YesNoDialog::actionYes() { QDialog::accept(); } void YesNoDialog::actionNo() { QDialog::reject(); } YesNoDialog::YesNoDialog() { new QDialog(NULL, NULL, true, Qt::WDestructiveClose); } YesNoDialog::YesNoDialog(QWidget *parent, const QString &caption, const QString &text) : QDialog(parent, NULL, true, Qt::WDestructiveClose) { setCaption(caption); QBoxLayout *vb = new QVBoxLayout(this, 11, 6); QLabel *lblQuestion = new QLabel(text, this); vb->addWidget(lblQuestion); QHBoxLayout *hb = new QHBoxLayout(NULL, 0, 6); QSpacerItem *spacer1 = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum ); hb->addItem(spacer1); pbYes = new QPushButton(tr("&Yes"), this); hb->addWidget(pbYes); pbNo = new QPushButton(tr("&No"), this); hb->addWidget(pbNo); QSpacerItem *spacer2 = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum ); hb->addItem(spacer2); vb->addLayout(hb); connect(pbYes, SIGNAL(clicked()), this, SLOT(actionYes())); connect(pbNo, SIGNAL(clicked()), this, SLOT(actionNo())); } YesNoDialog::~YesNoDialog() {} void YesNoDialog::reject() { pbNo->animateClick(); } // class ReferPermissionDialog void ReferPermissionDialog::actionYes() { ui->send_refer_permission(true); YesNoDialog::actionYes(); } void ReferPermissionDialog::actionNo() { ui->send_refer_permission(false); YesNoDialog::actionNo(); } ReferPermissionDialog::ReferPermissionDialog(QWidget *parent, const QString &caption, const QString &text) : YesNoDialog(parent, caption, text) {} twinkle-1.4.2/src/gui/twinkleapplication.h0000644000175000001440000000237311127714045015544 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TWINKLEAPPLICATION_H #define _TWINKLEAPPLICATION_H #include "twinkle_config.h" #ifdef HAVE_KDE #include #else #include #endif #ifdef HAVE_KDE class t_twinkle_application : public KApplication { #else class t_twinkle_application : public QApplication { #endif public: #ifdef HAVE_KDE t_twinkle_application(); #else t_twinkle_application(int &argc, char **argv); #endif virtual void commitData ( QSessionManager &sm ); }; #endif twinkle-1.4.2/src/gui/messageformview.h0000644000175000001440000000256311127714045015047 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MESSAGEFORMVIEW_H #define _MESSAGEFORMVIEW_H #include "messageform.h" #include "im/msg_session.h" #include "patterns/observer.h" class MessageFormView : public MessageForm, patterns::t_observer { private: bool _destructing; /**< Indicates if object is being destructed. */ public: MessageFormView(QWidget *parent, im::t_msg_session *s); virtual ~MessageFormView(); virtual void updatePartyInfo(void); /** Update the message form with the latest message session state. */ virtual void update(void); virtual void subject_destroyed(void); virtual void show(void); }; #endif twinkle-1.4.2/src/gui/yesnodialog.h0000644000175000001440000000270611127714045014160 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _YESNODIALOG_H #define _YESNODIALOG_H #include "qdialog.h" #include "qpushbutton.h" #include "qstring.h" class YesNoDialog : public QDialog { private: Q_OBJECT QPushButton *pbYes; QPushButton *pbNo; protected slots: virtual void actionYes(); virtual void actionNo(); public: YesNoDialog(); YesNoDialog(QWidget *parent, const QString &caption, const QString &text); virtual ~YesNoDialog(); void reject(); }; class ReferPermissionDialog : public YesNoDialog { private: Q_OBJECT protected slots: virtual void actionYes(); virtual void actionNo(); public: ReferPermissionDialog(QWidget *parent, const QString &caption, const QString &text); }; #endif twinkle-1.4.2/src/gui/authenticationform.ui.h0000644000175000001440000000346211127714045016162 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ int AuthenticationForm::exec(t_user *user_config, const QString &realm, QString &username, QString &password) { int retval; profileValueTextLabel->setText(user_config->get_profile_name().c_str()); userValueTextLabel->setText(user_config->get_display_uri().c_str()); realmTextLabel->setText(realm); usernameLineEdit->setText(username); passwordLineEdit->setText(password); if (!username.isEmpty()) passwordLineEdit->setFocus(); retval = QDialog::exec(); username = usernameLineEdit->text(); password = passwordLineEdit->text(); return retval; } twinkle-1.4.2/src/gui/messageform.ui.h0000644000175000001440000003710411150243276014566 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_KDE #include #include #include #include #include #else #include "utils/mime_database.h" #endif using namespace utils; /** Maximum width for an inline image */ #define MAX_WIDTH_IMG_INLINE 400 /** Maximum height for an inline image */ #define MAX_HEIGHT_IMG_INLINE 400 #define IMG_SCALE_FACTOR(width, height) (std::min( float(MAX_WIDTH_IMG_INLINE) / (width), float(MAX_HEIGHT_IMG_INLINE) / (height) ) ) void MessageForm::init() { setWFlags(getWFlags() | Qt::WDestructiveClose); _getAddressForm = 0; _remotePartyComplete = false; // Add label to display size of typed message _msgSizeLabel = new QLabel(this); statusBar()->addWidget(_msgSizeLabel); showMessageSize(); // Set toolbutton icons for disabled options. setDisabledIcon(addressToolButton, "kontact_contacts-disabled.png"); attachmentPopupMenu = new QPopupMenu(this); MEMMAN_NEW(attachmentPopupMenu); connect(attachmentPopupMenu, SIGNAL(activated(int)), this, SLOT(attachmentPopupActivated(int))); _serviceMap = NULL; _saveAsDialog = NULL; _isComposingLabel = NULL; // When the user edits the message, the composition indication // will be set to active. connect(msgLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(setLocalComposingIndicationActive())); } void MessageForm::destroy() { if (_getAddressForm) { MEMMAN_DELETE(_getAddressForm); delete _getAddressForm; } MEMMAN_DELETE(attachmentPopupMenu); delete attachmentPopupMenu; #ifdef HAVE_KDE vector *serviceMap = (vector *)_serviceMap; if (serviceMap) { MEMMAN_DELETE(serviceMap); delete serviceMap; } #endif if (_saveAsDialog) { MEMMAN_DELETE(_saveAsDialog); delete _saveAsDialog; } if (_isComposingLabel) { MEMMAN_DELETE(_isComposingLabel); delete _isComposingLabel; } } void MessageForm::closeEvent(QCloseEvent *e) { MEMMAN_DELETE(this); // destructive close QMainWindow::closeEvent(e); } void MessageForm::show() { if (toLineEdit->text().isEmpty()) { sendFileAction->setEnabled(false); toLineEdit->setFocus(); } else { // Once a message session has been created, the // source and destination cannot be changed anymore. fromComboBox->setEnabled(false); toLineEdit->setEnabled(false); addressToolButton->setEnabled(false); sendFileAction->setEnabled(true); msgLineEdit->setFocus(); } QMainWindow::show(); } void MessageForm::selectUserConfig(t_user *user_config) { for (int i = 0; i < fromComboBox->count(); i++) { if (fromComboBox->text(i) == user_config->get_profile_name().c_str()) { fromComboBox->setCurrentItem(i); break; } } } void MessageForm::showAddressBook() { if (!_getAddressForm) { _getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(_getAddressForm); } connect(_getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); _getAddressForm->show(); } void MessageForm::selectedAddress(const QString &address) { toLineEdit->setText(address); } /** * Check if there is a valid sender and receiver. If so, then set the sender * and receiver addresses in the message session object. */ bool MessageForm::updateMessageSession() { string display, dest_str; t_user *from_user = phone->ref_user_profile( fromComboBox->currentText().ascii()); if (!from_user) { // The user profile is not active anymore fromComboBox->setFocus(); return false; } ui->expand_destination(from_user, toLineEdit->text().stripWhiteSpace().ascii(), display, dest_str); t_url dest(dest_str); if (!dest.is_valid()) { toLineEdit->setFocus(); toLineEdit->selectAll(); return false; } _msgSession->set_user(from_user); _msgSession->set_remote_party(t_display_url(dest, display)); setRemotePartyCaption(); return true; } /** * Determine if a message can be sent, i.e. there is a valid sender and * receiver. If a message can be sent, then lock the sender and receiver. * @return True if message can be sent, false otherwise. */ bool MessageForm::prepareSendMessage() { if (toLineEdit->text().isEmpty()) { // No recipient selected. return false; } if (toLineEdit->isEnabled()) { if (!updateMessageSession()) { // No valid sender and receiver. return false; } // Once a message session has been created, the // source and destination cannot be changed anymore. fromComboBox->setEnabled(false); toLineEdit->setEnabled(false); addressToolButton->setEnabled(false); } return true; } /** Send a text message */ void MessageForm::sendMessage() { if (msgLineEdit->text().isEmpty()) { // Nothing to send return; } if (!prepareSendMessage()) { return; } _msgSession->send_msg(msgLineEdit->text().ascii(), im::TXT_PLAIN); } /** * Send a file. * @param filename [in] Name of file to send. * @param subject [in] Subject to set in the message. */ void MessageForm::sendFile(const QString &filename, const QString &subject) { if (!prepareSendMessage()) { return; } t_media media("application/octet-stream"); #ifdef HAVE_KDE // Get mime type for the attachment KMimeType::Ptr pMime = KMimeType::findByURL(filename); media = t_media(pMime->name().ascii()); #else string mime_type = mime_database->get_mimetype(filename.ascii()); if (!mime_type.empty()) { media = t_media(mime_type); } #endif _msgSession->send_file(filename.ascii(), media, subject.ascii()); } /** * Add a message to the converstation broswer. * @param msg [in] The message to add. * @param name [in] The name of the sender of the message. */ void MessageForm::addMessage(const im::t_msg &msg, const QString &name) { QString s = ""; // Timestamp and name of sender if (msg.direction == im::MSG_DIR_IN) s += ""; s += time2str(msg.timestamp, "%H:%M:%S ").c_str(); s += QStyleSheet::escape(name); if (msg.direction == im::MSG_DIR_IN) s += ""; s += ""; // Subject if (!msg.subject.empty()) { s += "
"; s += ""; s += "Subject: "; s += ""; s += msg.subject.c_str(); } // Text message if (!msg.message.empty()) { s += "
"; if (msg.format == im::TXT_HTML) { s += msg.message.c_str(); } else { s += QStyleSheet::escape(msg.message.c_str()); } } // Attachment if (msg.has_attachment) { s += "
"; s += ""; bool show_attachment_inline = false; bool scale_image = false; int scaled_width = 0, scaled_height = 0; if (msg.attachment_media.type == "image") { // Show image inline if possible QPixmap image (msg.attachment_filename.c_str()); if (!image.isNull()) { show_attachment_inline = true; if (image.width() > MAX_WIDTH_IMG_INLINE && image.height() > MAX_HEIGHT_IMG_INLINE) { // Shrink image scaled_width = int(image.width() * IMG_SCALE_FACTOR(image.width(), image.height())); scaled_height = int(image.height() * IMG_SCALE_FACTOR(image.width(), image.height())); scale_image = true; } } } s += ""; s+= "
"; s += msg.attachment_save_as_name.c_str(); s += "
"; if (scale_image) { s += "
"; s += ""; s += tr("image size is scaled down in preview"); s += ""; } // Store the association between the tempory file name of the // save attachment and the suggested save-as file name. When // the user clicks on the attachment, only the temporary file name // is available. Through this association the suggested file name // can be retrieved. _filenameMap[msg.attachment_filename] = msg.attachment_save_as_name; } conversationBrowser->append(s); } void MessageForm::displayError(const QString &errorMsg) { QString s = ""; s += ""; s += tr("Delivery failure").ascii(); s += ": "; s += QStyleSheet::escape(errorMsg); s += ""; conversationBrowser->append(s); } void MessageForm::displayDeliveryNotification(const QString ¬ification) { QString s = ""; s += ""; s += tr("Delivery notification").ascii(); s += ": "; s += QStyleSheet::escape(notification); s += ""; conversationBrowser->append(s); } void MessageForm::setRemotePartyCaption(void) { if (!_msgSession) return; t_user *user = _msgSession->get_user(); t_display_url remote_party = _msgSession->get_remote_party(); setCaption(ui->format_sip_address(user, remote_party.display, remote_party.url).c_str()); } void MessageForm::showAttachmentPopupMenu(const QString &attachment) { #ifdef HAVE_KDE vector *serviceMap = (vector *)_serviceMap; if (serviceMap) { MEMMAN_DELETE(serviceMap); delete serviceMap; } serviceMap = new vector; MEMMAN_NEW(serviceMap); _serviceMap = (void *)serviceMap; #endif int id = 0; // Identity of popup menu item // Store attachment. When the user selects an attachment we still // know which attachment was clicked. clickedAttachment = attachment; attachmentPopupMenu->clear(); QIconSet saveIcon(QPixmap::fromMimeSource("save_as.png")); attachmentPopupMenu->insertItem(saveIcon, "Save as...", id++); #ifdef HAVE_KDE // Get mime type for the attachment KMimeType::Ptr pMime = KMimeType::findByURL(attachment); // Get applications that can open the mime type KServiceTypeProfile::OfferList services = KServiceTypeProfile::offers( pMime->name(), "Application"); KServiceTypeProfile::OfferList::ConstIterator it; for (it = services.begin(); it != services.end(); ++it) { KService::Ptr service = (*it).service(); serviceMap->push_back(service); QString menuText = tr("Open with %1...").arg(service->name()); QPixmap pixmap = service->pixmap(KIcon::Small); QIconSet iconSet; iconSet.setPixmap(pixmap, QIconSet::Small); attachmentPopupMenu->insertItem(iconSet, menuText, id++); } QIconSet openIcon(QPixmap::fromMimeSource("fileopen.png")); attachmentPopupMenu->insertItem(openIcon, tr("Open with..."), id++); #endif attachmentPopupMenu->popup(QCursor::pos()); } void MessageForm::attachmentPopupActivated(int id) { #ifdef HAVE_KDE vector *serviceMap = (vector *)_serviceMap; assert(serviceMap); #endif if (id == 0) { #ifdef HAVE_KDE KFileDialog *d = new KFileDialog(QString::null, QString::null, this, 0, true); MEMMAN_NEW(d); d->setOperationMode(KFileDialog::Saving); connect(d, SIGNAL(okClicked()), this, SLOT(saveAttachment())); #else QFileDialog *d = new QFileDialog(QString::null, QString::null, this, 0, true); MEMMAN_NEW(d); d->setMode(QFileDialog::AnyFile); connect(d, SIGNAL(fileSelected(const QString &)), this, SLOT(saveAttachment())); #endif d->setSelection(_filenameMap[clickedAttachment.ascii()].c_str()); d->setCaption(tr("Save attachment as...")); if (_saveAsDialog) { MEMMAN_DELETE(_saveAsDialog); delete _saveAsDialog; } _saveAsDialog = d; d->show(); #ifdef HAVE_KDE } else if (id > serviceMap->size()) { KURL::List urls; urls << clickedAttachment; KRun::displayOpenWithDialog(urls, false); } else { KURL::List urls; urls << clickedAttachment; KRun::run(*serviceMap->at(id-1), urls); #endif } } void MessageForm::saveAttachment() { #ifdef HAVE_KDE KFileDialog *d = dynamic_cast(_saveAsDialog); #else QFileDialog *d = dynamic_cast(_saveAsDialog); #endif QString filename = d->selectedFile(); if (QFile::exists(filename)) { bool overwrite = ((t_gui *)ui)->cb_ask_msg(this, tr("File already exists. Do you want to overwrite this file?").ascii(), MSG_WARNING); if (!overwrite) return; } if (!filecopy(clickedAttachment.ascii(), filename.ascii())) { ((t_gui *)ui)->cb_show_msg(this, tr("Failed to save attachment.").ascii(), MSG_CRITICAL); } } /** Choose a file to send */ void MessageForm::chooseFileToSend() { // Indicate that a message is being composed. setLocalComposingIndicationActive(); SendFileForm *form = new SendFileForm(); MEMMAN_NEW(form); // Form will auto destruct itself on close. connect(form, SIGNAL(selected(const QString &, const QString &)), this, SLOT(sendFile(const QString &, const QString &))); form->show(); } /** * Show an is-composing indication in the status bar. * @param name [in] The name of the sender of the message. */ void MessageForm::setComposingIndication(const QString &name) { if (!_isComposingLabel) { _isComposingLabel = new QLabel(NULL); MEMMAN_NEW(_isComposingLabel); _isComposingLabel->setText(tr("%1 is typing a message.").arg(name)); _isComposingLabel->setFrameStyle(QFrame::NoFrame | QFrame::Plain); statusBar()->addWidget(_isComposingLabel); } } /** Clear an is-composing indication from the status bar. */ void MessageForm::clearComposingIndication() { if (_isComposingLabel) { statusBar()->removeWidget(_isComposingLabel); statusBar()->clear(); MEMMAN_DELETE(_isComposingLabel); delete _isComposingLabel; _isComposingLabel = NULL; } } /** Set the local composition indication to active. */ void MessageForm::setLocalComposingIndicationActive() { _msgSession->set_local_composing_state(im::COMPOSING_STATE_ACTIVE); } void MessageForm::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Return: case Qt::Key_Enter: if (sendPushButton->isEnabled()) { sendPushButton->animateClick(); } break; default: e->ignore(); } } void MessageForm::toAddressChanged(const QString &address) { sendFileAction->setEnabled(!address.isEmpty()); } /** Show the size of the typed message */ void MessageForm::showMessageSize() { uint len = msgLineEdit->text().length(); QString s(tr("Size")); s += ": "; s += QString().setNum(len); _msgSizeLabel->setText(s); } twinkle-1.4.2/src/gui/authenticationform.ui0000644000175000001440000003232510514000305015716 00000000000000 AuthenticationForm AuthenticationForm 0 0 582 198 Twinkle - Authentication unnamed layout33 unnamed authIconTextLabel password.png spacer46 Vertical Expanding 20 51 layout9 unnamed userValueTextLabel 0 85 255 user No need to translate The user for which authentication is requested. profileValueTextLabel 7 0 0 0 0 85 255 profile No need to translate The user profile of the user for which authentication is requested. profileTextLabel User profile: userTextLabel User: layout10 unnamed passwordTextLabel &Password: passwordLineEdit passwordLineEdit 200 0 Password Your password for authentication. usernameLineEdit 200 0 Your SIP authentication name. Quite often this is the same as your SIP user name. It can be a different name though. usernameTextLabel &User name: usernameLineEdit spacer13 Vertical Expanding 20 16 layout22 unnamed spacer12 Horizontal Expanding 101 20 okPushButton &OK true cancelPushButton &Cancel layout13 unnamed authTextLabel 32767 32767 Login required for realm: realmTextLabel 7 0 0 0 0 85 255 realm No need to translate The realm for which you need to authenticate. okPushButton clicked() AuthenticationForm accept() cancelPushButton clicked() AuthenticationForm reject() usernameLineEdit passwordLineEdit okPushButton cancelPushButton user.h authenticationform.ui.h exec( t_user * user_config, const QString & realm, QString & username, QString & password ) twinkle-1.4.2/src/gui/transferform.ui.h0000644000175000001440000001170511127714045014766 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void TransferForm::init() { getAddressForm = 0; // Set toolbutton icons for disabled options. QIconSet i; i = addressToolButton->iconSet(); i.setPixmap(QPixmap::fromMimeSource("kontact_contacts-disabled.png"), QIconSet::Automatic, QIconSet::Disabled); addressToolButton->setIconSet(i); } void TransferForm::destroy() { if (getAddressForm) { MEMMAN_DELETE(getAddressForm); delete getAddressForm; } } void TransferForm::initTransferOptions() { // Show possible transfer type options // Basic transfer is always possible. // If a line is idle, then a transfer with consultation is possible. // The line will be seized, so an incoming call cannot occupy it. // If both lines are busy, then the active line can be transferred // to the other line. unsigned short idle_line; if (phone->get_idle_line(idle_line)) { consult_line = (int)idle_line; phone->pub_seize(consult_line); consultRadioButton->show(); consultRadioButton->setChecked(true); otherLineRadioButton->hide(); } else { consult_line = -1; consultRadioButton->hide(); otherLineRadioButton->show(); otherLineRadioButton->setChecked(true); } } void TransferForm::show(t_user *user) { user_config = user; initTransferOptions(); QDialog::show(); } void TransferForm::show(t_user *user, const string &dest, t_transfer_type transfer_type) { user_config = user; initTransferOptions(); toLineEdit->setText(dest.c_str()); switch (transfer_type) { case TRANSFER_CONSULT: consultRadioButton->setChecked(true); break; case TRANSFER_OTHER_LINE: otherLineRadioButton->setChecked(true); break; default: basicRadioButton->setChecked(true); break; } QDialog::show(); } void TransferForm::hide() { if (consult_line > -1) { phone->pub_unseize(consult_line); } QDialog::hide(); } void TransferForm::reject() { if (user_config->get_referrer_hold()) { ((t_gui *)ui)->action_retrieve(); } if (consult_line > -1) { phone->pub_unseize(consult_line); } QDialog::reject(); } void TransferForm::validate() { t_display_url dest; ui->expand_destination(user_config, toLineEdit->text().stripWhiteSpace().ascii(), dest); t_transfer_type transfer_type; if (consultRadioButton->isOn()) { transfer_type = TRANSFER_CONSULT; } else if (otherLineRadioButton->isOn()) { transfer_type = TRANSFER_OTHER_LINE; } else { transfer_type = TRANSFER_BASIC; } if (transfer_type == TRANSFER_OTHER_LINE || dest.is_valid()) { if (consult_line > -1) { phone->pub_unseize(consult_line); } emit destination(dest, transfer_type); accept(); } else { toLineEdit->selectAll(); } } void TransferForm::closeEvent(QCloseEvent *) { reject(); } void TransferForm::showAddressBook() { if (!getAddressForm) { getAddressForm = new GetAddressForm( this, "select address", true); MEMMAN_NEW(getAddressForm); } connect(getAddressForm, SIGNAL(address(const QString &)), this, SLOT(selectedAddress(const QString &))); getAddressForm->show(); } void TransferForm::selectedAddress(const QString &address) { toLineEdit->setText(address); } void TransferForm::setOtherLineAddress(bool on) { if (on) { previousAddress = toLineEdit->text(); unsigned short active_line = phone->get_active_line(); unsigned short other_line = (active_line == 0 ? 1 : 0); QString address = ui->format_sip_address(user_config, phone->get_remote_display(other_line), phone->get_remote_uri(other_line)).c_str(); toLineEdit->setText(address); toLineEdit->setEnabled(false); toLabel->setEnabled(false); #ifdef HAVE_KDE addressToolButton->setEnabled(false); #endif } else { toLineEdit->setText(previousAddress); toLineEdit->setEnabled(true); toLabel->setEnabled(true); #ifdef HAVE_KDE addressToolButton->setEnabled(true); #endif } } twinkle-1.4.2/src/gui/deregisterform.ui.h0000644000175000001440000000237211127714045015277 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ twinkle-1.4.2/src/gui/diamondcardprofileform.ui0000644000175000001440000002761411151057742016551 00000000000000 DiamondcardProfileForm DiamondcardProfileForm 0 0 541 433 0 Twinkle - Diamondcard User Profile unnamed explainTextLabel 5 5 0 0 <p>With a Diamondcard account you can make worldwide calls to regular and cell phones and send SMS messages. To sign up for a Diamondcard account click on the "sign up" link below. Once you have signed up you receive an account ID and PIN code. Enter the account ID and PIN code below to create a Twinkle user profile for your Diamondcard account.</p> <p>For call rates see the sign up web page that will be shown to you when you click on the "sign up" link.</p> RichText spacer35 Vertical Expanding 20 16 layout193 unnamed accountIdLineEdit Your Diamondcard account ID. nameLineEdit This is just your full name, e.g. John Doe. It is used as a display name. When you make a call, this display name might be shown to the called party. accountIdTextLabel &Account ID: accountIdLineEdit pinCodeTextLabel &PIN code: pinCodeLineEdit nameTextLabel &Your name: nameLineEdit pinCodeLineEdit Password Your Diamondcard PIN code. spacer27 Vertical Expanding 20 20 layout63 unnamed signUpTextLabel PaletteBackground 0 0 205 13 <p align="center"><u>Sign up for a Diamondcard account</u></p> AlignVCenter spacer28 Vertical Expanding 20 21 layout64 unnamed spacer21 Horizontal Expanding 61 20 okPushButton &OK Alt+O true cancelPushButton &Cancel Alt+C okPushButton clicked() DiamondcardProfileForm validate() cancelPushButton clicked() DiamondcardProfileForm reject() nameLineEdit accountIdLineEdit pinCodeLineEdit okPushButton cancelPushButton user.h qregexp.h qvalidator.h gui.h diamondcard.h getprofilenameform.h audits/memman.h diamondcardprofileform.ui.h t_user *user_config; bool destroy_user_config; success() newDiamondcardProfile(const QString&) destroyOldUserConfig() show( t_user * user ) validate() mouseReleaseEvent( QMouseEvent * e ) processLeftMouseButtonRelease( QMouseEvent * e ) init() destroy() exec( t_user * user ) twinkle-1.4.2/src/gui/diamondcardprofileform.ui.h0000644000175000001440000001044511151050762016764 00000000000000/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ void DiamondcardProfileForm::init() { user_config = NULL; destroy_user_config = false; QRegExp rxNoSpace("\\S*"); accountIdLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); pinCodeLineEdit->setValidator(new QRegExpValidator(rxNoSpace, this)); } void DiamondcardProfileForm::destroy() { destroyOldUserConfig(); } void DiamondcardProfileForm::destroyOldUserConfig() { if (user_config && destroy_user_config) { MEMMAN_DELETE(user_config); delete user_config; } user_config = NULL; } // Show the form void DiamondcardProfileForm::show(t_user *user) { destroyOldUserConfig(); if (user) { user_config = user; destroy_user_config = false; } else { user_config = new t_user(); MEMMAN_NEW(user_config); destroy_user_config = true; } QDialog::show(); } // Modal execution int DiamondcardProfileForm::exec(t_user *user) { destroyOldUserConfig(); user_config = user; destroy_user_config = false; return QDialog::exec(); } void DiamondcardProfileForm::validate() { if (accountIdLineEdit->text().isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("Fill in your account ID.").ascii(), MSG_CRITICAL); accountIdLineEdit->setFocus(); return; } if (pinCodeLineEdit->text().isEmpty()) { ((t_gui *)ui)->cb_show_msg(this, tr("Fill in your PIN code.").ascii(), MSG_CRITICAL); pinCodeLineEdit->setFocus(); return; } QString profileName("Diamondcard-"); profileName.append(accountIdLineEdit->text()); QString filename(profileName); filename.append(USER_FILE_EXT); // Create a new user config while (!user_config->set_config(filename.ascii())) { ((t_gui *)ui)->cb_show_msg(this, tr("A user profile with name %1 already exists.").arg(profileName).ascii(), MSG_WARNING); // Ask user for a profile name GetProfileNameForm getProfileNameForm(this, "get profile name", true); if (!getProfileNameForm.execNewName()) return; profileName = getProfileNameForm.getProfileName(); filename = profileName; filename.append(USER_FILE_EXT); } diamondcard_set_user_config(*user_config, nameLineEdit->text().ascii(), accountIdLineEdit->text().ascii(), pinCodeLineEdit->text().ascii()); string error_msg; if (!user_config->write_config(user_config->get_filename(), error_msg)) { // Failed to write config file ((t_gui *)ui)->cb_show_msg(this, error_msg, MSG_CRITICAL); return; } emit newDiamondcardProfile(user_config->get_filename().c_str()); emit success(); accept(); } // Handle mouse clicks on labels. void DiamondcardProfileForm::mouseReleaseEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton && e->type() == QEvent::MouseButtonRelease) { processLeftMouseButtonRelease(e); } else { e->ignore(); } } void DiamondcardProfileForm::processLeftMouseButtonRelease(QMouseEvent *e) { if (signUpTextLabel->hasMouse()) { string url = diamondcard_url(DC_ACT_SIGNUP, "", ""); ((t_gui *)ui)->open_url_in_browser(url.c_str()); } else { e->ignore(); } } twinkle-1.4.2/src/gui/twinklesystray.cpp0000644000175000001440000000222011127714053015300 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinklesystray.h" #include "audits/memman.h" t_twinkle_sys_tray::t_twinkle_sys_tray(QWidget *pParent, const char *pszName) : #ifdef HAVE_KDE KSystemTray(pParent, pszName) #else FreeDeskSysTray(pParent, pszName) #endif {} t_twinkle_sys_tray::~t_twinkle_sys_tray() {} void t_twinkle_sys_tray::dock() { #ifndef HAVE_KDE FreeDeskSysTray::dock(); #endif } twinkle-1.4.2/src/mwi/0000777000175000001440000000000011151327740011560 500000000000000twinkle-1.4.2/src/mwi/simple_msg_sum_body.cpp0000644000175000001440000001146011127714053016242 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "simple_msg_sum_body.h" #include #include #include #include "protocol.h" #include "util.h" #include "audits/memman.h" t_msg_summary::t_msg_summary() : newmsgs(0), newmsgs_urgent(0), oldmsgs(0), oldmsgs_urgent(0) {} bool t_msg_summary::parse(const string &s) { newmsgs = 0; oldmsgs = 0; newmsgs_urgent = 0; oldmsgs_urgent = 0; // RFC 3842 5.2 // msg-summary-line = message-context-class HCOLON newmsgs SLASH oldmsgs // [ LPAREN new-urgentmsgs SLASH old-urgentmsgs RPAREN ] // This regex matches the part after HCOLON boost::regex re("(\\d+)\\s*/\\s*(\\d+)(?:\\s*\\((\\d+)\\s*/\\s*(\\d+)\\s*\\))?"); boost::smatch m; if (!boost::regex_match(s, m, re)) return false; if (m.size() == 3) { newmsgs = strtoul(m.str(1).c_str(), NULL, 10); oldmsgs = strtoul(m.str(2).c_str(), NULL, 10); return true; } else if (m.size() == 5) { newmsgs = strtoul(m.str(1).c_str(), NULL, 10); oldmsgs = strtoul(m.str(2).c_str(), NULL, 10); newmsgs_urgent = strtoul(m.str(3).c_str(), NULL, 10); oldmsgs_urgent = strtoul(m.str(4).c_str(), NULL, 10); return true; } return false; } void t_msg_summary::clear(void) { newmsgs = 0; newmsgs_urgent = 0; oldmsgs = 0; oldmsgs_urgent = 0; } bool t_simple_msg_sum_body::is_context(const string &s) { return ( s == MSG_CONTEXT_VOICE || s == MSG_CONTEXT_FAX || s == MSG_CONTEXT_MULTIMEDIA || s == MSG_CONTEXT_TEXT || s == MSG_CONTEXT_NONE); } t_simple_msg_sum_body::t_simple_msg_sum_body() : t_sip_body() {} string t_simple_msg_sum_body::encode(void) const { string s = "Messages-Waiting: "; s += (msg_waiting ? "yes" : "no"); s += CRLF; if (msg_account.is_valid()) { s += "Message-Account: "; s += msg_account.encode(); s += CRLF; } for (t_msg_sum_const_iter i = msg_summary.begin(); i != msg_summary.end(); ++i) { const t_msg_summary &summary = i->second; s += i->first; s += ": "; s += ulong2str(summary.newmsgs); s += "/"; s += ulong2str(summary.oldmsgs); if (summary.newmsgs_urgent > 0 || summary.oldmsgs_urgent > 0) { s += " ("; s += ulong2str(summary.newmsgs_urgent); s += "/"; s += ulong2str(summary.oldmsgs_urgent); s += ")"; } s += CRLF; } return s; } t_sip_body *t_simple_msg_sum_body::copy(void) const { t_simple_msg_sum_body *body = new t_simple_msg_sum_body(*this); MEMMAN_NEW(body); return body; } t_body_type t_simple_msg_sum_body::get_type(void) const { return BODY_SIMPLE_MSG_SUM; } t_media t_simple_msg_sum_body::get_media(void) const { return t_media("application", "simple-message-summary"); } void t_simple_msg_sum_body::add_msg_summary(const string &context, const t_msg_summary summary) { msg_summary.insert(make_pair(context, summary)); } bool t_simple_msg_sum_body::get_msg_waiting(void) const { return msg_waiting; } t_url t_simple_msg_sum_body::get_msg_account(void) const { return msg_account; } bool t_simple_msg_sum_body::get_msg_summary(const string &context, t_msg_summary &summary) const { t_msg_sum_const_iter it = msg_summary.find(context); if (it == msg_summary.end()) return false; summary = it->second; return true; } bool t_simple_msg_sum_body::parse(const string &s) { bool valid = false; vector lines = split_linebreak(s); for (vector::iterator i = lines.begin(); i != lines.end(); ++i) { string line = trim(*i); if (line.empty()) continue; vector l = split_on_first(line, ':'); if (l.size() != 2) continue; string header = tolower(trim(l[0])); string value = tolower(trim(l[1])); if (value.empty()) continue; if (header == "messages-waiting") { if (value == "yes") { msg_waiting = true; valid = true; } else if (value == "no") { msg_waiting = false; valid = true; } } else if (header == "message-account") { msg_account.set_url(value); } else if (is_context(header)) { t_msg_summary summary; if (summary.parse(value)) { add_msg_summary(header, summary); } } } invalid = !valid; return valid; } twinkle-1.4.2/src/mwi/mwi.h0000644000175000001440000000344211127714045012445 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Message Waiting Indication information. */ #ifndef _MWI_HH #define _MWI_HH #include "simple_msg_sum_body.h" #include "threads/mutex.h" /** MWI information */ class t_mwi { public: /** Status of MWI information */ enum t_status { MWI_UNKNOWN, /**< The status is unknown */ MWI_KNOWN, /**< MWI properly received */ MWI_FAILED /**< MWI subscription failed */ }; private: /** Mutex for exclusive access to MWI information */ mutable t_mutex mtx_mwi; /** MWI status */ t_status status; /** Indication if messages are waiting */ bool msg_waiting; /** Summary of voice messages waiting */ t_msg_summary voice_msg_summary; public: t_mwi(); t_status get_status(void) const; bool get_msg_waiting(void) const; t_msg_summary get_voice_msg_summary(void) const; void set_status(t_status _status); void set_msg_waiting(bool _msg_waiting); void set_voice_msg_summary(const t_msg_summary &summary); /** Set all counters to zero */ void clear_voice_msg_summary(void); }; #endif twinkle-1.4.2/src/mwi/mwi_subscription.h0000644000175000001440000000247711127714045015260 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3842 // message-summary subscription #ifndef _MWI_SUBSCRIPTION_H #define _MWI_SUBSCRIPTION_H #include "mwi.h" #include "mwi_dialog.h" #include "subscription.h" class t_mwi_subscription : public t_subscription { private: t_mwi *mwi; protected: virtual t_request *create_subscribe(unsigned long expires) const; public: t_mwi_subscription(t_mwi_dialog *_dialog, t_mwi *_mwi); virtual bool recv_notify(t_request *r, t_tuid tuid, t_tid tid); virtual bool recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid); }; #endif twinkle-1.4.2/src/mwi/Makefile.am0000644000175000001440000000110011134651123013514 00000000000000AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ $(CCRTP_CFLAGS) \ $(XML2_CFLAGS) #noinst_PROGRAMS = mwitest #mwitest_SOURCES = mwitest.cpp #mwitest_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/mwi/libmwi.a\ # $(top_builddir)/src/sockets/libsocket.a\ # $(top_builddir)/src/parser/libsipparser.a\ # $(top_builddir)/src/sdp/libsdpparser.a\ # -lresolv\ # -lboost_regex noinst_LIBRARIES = libmwi.a libmwi_a_SOURCES =\ mwi.cpp\ mwi_dialog.cpp\ mwi_subscription.cpp\ simple_msg_sum_body.cpp\ mwi.h\ mwi_dialog.h\ mwi_subscription.h\ simple_msg_sum_body.h twinkle-1.4.2/src/mwi/Makefile.in0000644000175000001440000004041711151323406013542 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/mwi DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libmwi_a_AR = $(AR) $(ARFLAGS) libmwi_a_LIBADD = am_libmwi_a_OBJECTS = mwi.$(OBJEXT) mwi_dialog.$(OBJEXT) \ mwi_subscription.$(OBJEXT) simple_msg_sum_body.$(OBJEXT) libmwi_a_OBJECTS = $(am_libmwi_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libmwi_a_SOURCES) DIST_SOURCES = $(libmwi_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ $(CCRTP_CFLAGS) \ $(XML2_CFLAGS) #noinst_PROGRAMS = mwitest #mwitest_SOURCES = mwitest.cpp #mwitest_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/mwi/libmwi.a\ # $(top_builddir)/src/sockets/libsocket.a\ # $(top_builddir)/src/parser/libsipparser.a\ # $(top_builddir)/src/sdp/libsdpparser.a\ # -lresolv\ # -lboost_regex noinst_LIBRARIES = libmwi.a libmwi_a_SOURCES = \ mwi.cpp\ mwi_dialog.cpp\ mwi_subscription.cpp\ simple_msg_sum_body.cpp\ mwi.h\ mwi_dialog.h\ mwi_subscription.h\ simple_msg_sum_body.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/mwi/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/mwi/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libmwi.a: $(libmwi_a_OBJECTS) $(libmwi_a_DEPENDENCIES) -rm -f libmwi.a $(libmwi_a_AR) libmwi.a $(libmwi_a_OBJECTS) $(libmwi_a_LIBADD) $(RANLIB) libmwi.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mwi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mwi_dialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mwi_subscription.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_msg_sum_body.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/mwi/mwi.cpp0000644000175000001440000000334411127714053013000 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mwi.h" t_mwi::t_mwi() : status(MWI_UNKNOWN) {} t_mwi::t_status t_mwi::get_status(void) const { t_status result; mtx_mwi.lock(); result = status; mtx_mwi.unlock(); return result; } bool t_mwi::get_msg_waiting(void) const { bool result; mtx_mwi.lock(); result = msg_waiting; mtx_mwi.unlock(); return result; } t_msg_summary t_mwi::get_voice_msg_summary(void) const { t_msg_summary result; mtx_mwi.lock(); result = voice_msg_summary; mtx_mwi.unlock(); return result; } void t_mwi::set_status(t_status _status) { mtx_mwi.lock(); status = _status; mtx_mwi.unlock(); } void t_mwi::set_msg_waiting(bool _msg_waiting) { mtx_mwi.lock(); msg_waiting = _msg_waiting; mtx_mwi.unlock(); } void t_mwi::set_voice_msg_summary(const t_msg_summary &summary) { mtx_mwi.lock(); voice_msg_summary = summary; mtx_mwi.unlock(); } void t_mwi::clear_voice_msg_summary(void) { mtx_mwi.lock(); voice_msg_summary.clear(); mtx_mwi.unlock(); } twinkle-1.4.2/src/mwi/simple_msg_sum_body.h0000644000175000001440000000534411127714045015714 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * RFC 3842 simple-message-summary body */ #ifndef SIMPLE_MSG_SUM_BODY_HH #define SIMPLE_MSG_SUM_BODY_HH #include #include #include #include "parser/sip_body.h" #include "sockets/url.h" // RFC 3458 6.2 // Message contexts #define MSG_CONTEXT_VOICE "voice-message" #define MSG_CONTEXT_FAX "fax-message" #define MSG_CONTEXT_MULTIMEDIA "multimedia-message" #define MSG_CONTEXT_TEXT "text-message" #define MSG_CONTEXT_NONE "none" using namespace std; /** Message summary counters */ struct t_msg_summary { uint32 newmsgs; uint32 newmsgs_urgent; uint32 oldmsgs; uint32 oldmsgs_urgent; t_msg_summary(); /** * Parse a text representation of a message summary. * @param s [in] The text to parse. * @return false if parsing fails, true if it succeeds. */ bool parse(const string &s); /** Set all counters to zero */ void clear(void); }; typedef string t_msg_context; typedef map::const_iterator t_msg_sum_const_iter; class t_simple_msg_sum_body : public t_sip_body { private: bool msg_waiting; t_url msg_account; map msg_summary; // Returns true if string is a valid message context bool is_context(const string &s); public: t_simple_msg_sum_body(); // Return text encoded body virtual string encode(void) const; // Create a copy of the body virtual t_sip_body *copy(void) const; // Get type of body virtual t_body_type get_type(void) const; virtual t_media get_media(void) const; // Add a message summary void add_msg_summary(const string &context, const t_msg_summary summary); bool get_msg_waiting(void) const; t_url get_msg_account(void) const; // Get the message summary for a particular context // If the context is not present, then false is returned bool get_msg_summary(const string &context, t_msg_summary &summary) const; // Parse a text representation of the body. bool parse(const string &s); }; #endif twinkle-1.4.2/src/mwi/mwi_subscription.cpp0000644000175000001440000000642711127714053015611 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mwi_subscription.h" #include #include "userintf.h" #include "audits/memman.h" #include "parser/hdr_event.h" t_request *t_mwi_subscription::create_subscribe(unsigned long expires) const { t_request *r = t_subscription::create_subscribe(expires); SET_MWI_HDR_ACCEPT(r->hdr_accept); return r; } t_mwi_subscription::t_mwi_subscription(t_mwi_dialog *_dialog, t_mwi *_mwi) : t_subscription(_dialog, SR_SUBSCRIBER, SIP_EVENT_MSG_SUMMARY), mwi(_mwi) {} bool t_mwi_subscription::recv_notify(t_request *r, t_tuid tuid, t_tid tid) { if (t_subscription::recv_notify(r, tuid, tid)) return true; bool unsupported_body = false; // NOTE: if the subscription is still pending (RFC 3265 3.2.4), then the // information in the body has no meaning. if (r->body && r->body->get_type() == BODY_SIMPLE_MSG_SUM && !is_pending()) { t_simple_msg_sum_body *body = dynamic_cast(r->body); assert(body); mwi->set_msg_waiting(body->get_msg_waiting()); t_msg_summary summary; if (body->get_msg_summary(MSG_CONTEXT_VOICE, summary)) { mwi->set_voice_msg_summary(summary); } else { mwi->clear_voice_msg_summary(); } mwi->set_status(t_mwi::MWI_KNOWN); } // Verify if there is an usupported body. if (r->body && r->body->get_type() != BODY_SIMPLE_MSG_SUM) { unsupported_body = true; } if (state == SS_TERMINATED && !may_resubscribe) { // The MWI server ended the subscription and indicated // that resubscription is not possible. So no MWI status // can be retrieved anymore. This should not happen, so // present it as a failure to the user. mwi->set_status(t_mwi::MWI_FAILED); ui->cb_mwi_terminated(user_config, get_reason_termination()); } t_response *resp; if (unsupported_body) { resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE); SET_MWI_HDR_ACCEPT(r->hdr_accept); } else { resp = r->create_response(R_200_OK); } send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; ui->cb_update_mwi(); return true; } bool t_mwi_subscription::recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid) { // Parent handles the SUBSCRIBE response (void)t_subscription::recv_subscribe_response(r, tuid, tid); // If the subscription is terminated after the SUBSCRIBE response, it means // that subscription failed. if (state == SS_TERMINATED) { ui->cb_mwi_subscribe_failed(user_config, r, mwi->get_status() != t_mwi::MWI_FAILED); mwi->set_status(t_mwi::MWI_FAILED); } ui->cb_update_mwi(); return true; } twinkle-1.4.2/src/mwi/mwi_dialog.h0000644000175000001440000000210011127714045013752 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MWI_DIALOG_H #define _MWI_DIALOG_H #include "mwi.h" #include "subscription_dialog.h" // Forward declaration class t_phone_user; class t_mwi_dialog : public t_subscription_dialog { public: t_mwi_dialog(t_phone_user *_phone_user); virtual t_mwi_dialog *copy(void); }; #endif twinkle-1.4.2/src/mwi/mwi_dialog.cpp0000644000175000001440000000223211127714053014312 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mwi_dialog.h" #include "mwi_subscription.h" #include "phone_user.h" #include "audits/memman.h" t_mwi_dialog::t_mwi_dialog(t_phone_user *_phone_user) : t_subscription_dialog(_phone_user) { subscription = new t_mwi_subscription(this, &(phone_user->mwi)); MEMMAN_NEW(subscription); } t_mwi_dialog *t_mwi_dialog::copy(void) { // Copy is not needed. assert(false); } twinkle-1.4.2/src/sdp/0000777000175000001440000000000011151327747011561 500000000000000twinkle-1.4.2/src/sdp/sdp.h0000644000175000001440000002052511127714045012432 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Session description #ifndef _H_SDP #define _H_SDP #include #include #include #include "audio/audio_codecs.h" #include "parser/sip_body.h" /** User name to be put in o= line of SDP */ #define SDP_O_USER "twinkle" // Audio codec formats #define SDP_FORMAT_G711_ULAW 0 #define SDP_FORMAT_GSM 3 #define SDP_FORMAT_G711_ALAW 8 // rtpmap values #define SDP_RTPMAP_G711_ULAW "PCMU/8000" #define SDP_RTPMAP_GSM "GSM/8000" #define SDP_RTPMAP_G711_ALAW "PCMA/8000" #define SDP_RTPMAP_SPEEX_NB "speex/8000" #define SDP_RTPMAP_SPEEX_WB "speex/16000" #define SDP_RTPMAP_SPEEX_UWB "speex/32000" #define SDP_RTPMAP_ILBC "iLBC/8000" #define SDP_RTPMAP_G726_16 "G726-16/8000" #define SDP_RTPMAP_G726_24 "G726-24/8000" #define SDP_RTPMAP_G726_32 "G726-32/8000" #define SDP_RTPMAP_G726_40 "G726-40/8000" #define SDP_RTPMAP_TELEPHONE_EV "telephone-event/8000" // Audio codec names #define SDP_AC_NAME_G711_ULAW "PCMU" #define SDP_AC_NAME_G711_ALAW "PCMA" #define SDP_AC_NAME_GSM "GSM" #define SDP_AC_NAME_SPEEX "speex" #define SDP_AC_NAME_ILBC "iLBC" #define SDP_AC_NAME_G726_16 "G726-16" #define SDP_AC_NAME_G726_24 "G726-24" #define SDP_AC_NAME_G726_32 "G726-32" #define SDP_AC_NAME_G726_40 "G726-40" #define SDP_AC_NAME_TELEPHONE_EV "telephone-event" // Check on fmtp parameter values #define VALID_ILBC_MODE(mode) ((mode) == 20 || (mode == 30)) using namespace std; enum t_sdp_ntwk_type { SDP_NTWK_NULL, SDP_NTWK_IN }; string sdp_ntwk_type2str(t_sdp_ntwk_type n); t_sdp_ntwk_type str2sdp_ntwk_type(string s); enum t_sdp_addr_type { SDP_ADDR_NULL, SDP_ADDR_IP4, SDP_ADDR_IP6 }; string sdp_addr_type2str(t_sdp_addr_type a); t_sdp_addr_type str2sdp_addr_type(string s); /** Transport protocol */ enum t_sdp_transport { SDP_TRANS_RTP, /**< RTP/AVP */ SDP_TRANS_UDP, /**< UDP */ SDP_TRANS_OTHER /**< Another protocol not yet supported */ }; string sdp_transport2str(t_sdp_transport t); t_sdp_transport str2sdp_transport(string s); enum t_sdp_media_direction { SDP_INACTIVE, SDP_SENDONLY, SDP_RECVONLY, SDP_SENDRECV }; string sdp_media_direction2str(t_sdp_media_direction d); enum t_sdp_media_type { SDP_AUDIO, SDP_VIDEO, SDP_OTHER }; t_sdp_media_type str2sdp_media_type(string s); string sdp_media_type2str(t_sdp_media_type m); class t_sdp_origin { public: string username; string session_id; string session_version; t_sdp_ntwk_type network_type; t_sdp_addr_type address_type; string address; t_sdp_origin(); t_sdp_origin(string _username, string _session_id, string _session_version, string _address); string encode(void) const; }; class t_sdp_connection { public: t_sdp_ntwk_type network_type; t_sdp_addr_type address_type; string address; t_sdp_connection(); t_sdp_connection(string _address); string encode(void) const; }; class t_sdp_attr { public: string name; string value; t_sdp_attr(string _name); t_sdp_attr(string _name, string _value); string encode(void) const; }; /** * Media definition. * The data from an m= line and associated a= lines. */ class t_sdp_media { private: /** Dynamic payload type for DTMF */ unsigned short format_dtmf; public: /** The media type, e.g. audio, video */ string media_type; /** Port to receive media */ unsigned short port; /** Transport protocol, e.g. RTP/AVP */ string transport; /** * @name Media formats * Depending on the media type, formats are in numeric format or * alpha numeric format. Only one of the following formats will * be populated. */ //@{ /** Media formats in numeric form, i.e. audio codecs */ list formats; /** Media formats in alpha numeric form. */ list alpha_num_formats; //@} /** Optional connection information if not specified on global level. */ t_sdp_connection connection; /** Attributes (a= lines) */ list attributes; t_sdp_media(); t_sdp_media(t_sdp_media_type _media_type, unsigned short _port, const list &_formats, unsigned short _format_dtmf, const map &ac2format); string encode(void) const; void add_format(unsigned short f, t_audio_codec codec); t_sdp_attr *get_attribute(const string &name); listget_attributes(const string &name); t_sdp_media_direction get_direction(void) const; t_sdp_media_type get_media_type(void) const; t_sdp_transport get_transport(void) const; }; class t_sdp : public t_sip_body { public: unsigned short version; t_sdp_origin origin; string session_name; t_sdp_connection connection; list attributes; list media; t_sdp(); // Create SDP with a single audio media stream t_sdp(const string &user, const string &sess_id, const string &sess_version, const string &user_host, const string &media_host, unsigned short media_port, const list &formats, unsigned short format_dtmf, const map &ac2format); // Create SDP without media streams t_sdp(const string &user, const string &sess_id, const string &sess_version, const string &user_host, const string &media_host); // Add media stream void add_media(const t_sdp_media &m); string encode(void) const; t_sip_body *copy(void) const; t_body_type get_type(void) const; t_media get_media(void) const; // Return true if the current SDP is supported: // version is 0 // 1 audio stream RTP // IN IP4 addressing // connection at session level only // If false is returned, then a warning code and text is returned. bool is_supported(int &warn_code, string &warn_text) const; // Get/set codec/rtp info for first media stream having a non-zero // value for the port of the given media type string get_rtp_host(t_sdp_media_type media_type) const; unsigned short get_rtp_port(t_sdp_media_type media_type) const; list get_codecs(t_sdp_media_type media_type) const; // Get codec description from rtpmap string get_codec_description(t_sdp_media_type media_type, unsigned short codec) const; t_audio_codec get_rtpmap_codec(const string &rtpmap) const; t_audio_codec get_codec(t_sdp_media_type media_type, unsigned short codec) const; t_sdp_media_direction get_direction(t_sdp_media_type media_type) const; // Get ftmp attribute string get_fmtp(t_sdp_media_type media_type, unsigned short codec) const; // Get a specific parameter from fmtp, assuming the fmtp string is a list // of paramter=value strings separated by semi-colons // Returns -1 on failure int get_fmtp_int_param(t_sdp_media_type media_type, unsigned short codec, const string param) const; // Get ptime. Returns 0 if ptime is not present unsigned short get_ptime(t_sdp_media_type media_type) const; bool get_zrtp_support(t_sdp_media_type media_type) const; void set_ptime(t_sdp_media_type media_type, unsigned short ptime); void set_direction(t_sdp_media_type media_type, t_sdp_media_direction direction); void set_fmtp(t_sdp_media_type media_type, unsigned short codec, const string &fmtp); void set_fmtp_int_param(t_sdp_media_type media_type, unsigned short codec, const string ¶m, int value); void set_zrtp_support(t_sdp_media_type media_type); // Returns a pointer to the first media stream in the list of media // streams having a non-zero port value for the give media type. // Returns NULL if no such media stream can be found. const t_sdp_media *get_first_media(t_sdp_media_type media_type) const; /** * Check if all local IP address are correctly filled in. This * check is an integrity check to help debugging the auto IP * discover feature. */ virtual bool local_ip_check(void) const; }; #endif twinkle-1.4.2/src/sdp/sdp_scanner.cxx0000644000175000001440000014316211127716010014513 00000000000000#line 2 "sdp_scanner.cxx" #line 4 "sdp_scanner.cxx" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 33 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yysdprestart(yysdpin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yysdpleng; extern FILE *yysdpin, *yysdpout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yysdptext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yysdptext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef unsigned int yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yysdprestart()), so that the user can continue scanning by * just pointing yysdpin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yysdptext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yysdpleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yysdpwrap()'s to do buffer switches * instead of setting up a fresh yysdpin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yysdprestart (FILE *input_file ); void yysdp_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yysdp_create_buffer (FILE *file,int size ); void yysdp_delete_buffer (YY_BUFFER_STATE b ); void yysdp_flush_buffer (YY_BUFFER_STATE b ); void yysdppush_buffer_state (YY_BUFFER_STATE new_buffer ); void yysdppop_buffer_state (void ); static void yysdpensure_buffer_stack (void ); static void yysdp_load_buffer_state (void ); static void yysdp_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yysdp_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yysdp_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yysdp_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yysdp_scan_bytes (yyconst char *bytes,int len ); void *yysdpalloc (yy_size_t ); void *yysdprealloc (void *,yy_size_t ); void yysdpfree (void * ); #define yy_new_buffer yysdp_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yysdpensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yysdp_create_buffer(yysdpin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yysdpensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yysdp_create_buffer(yysdpin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) #define yysdpwrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yysdpin = (FILE *) 0, *yysdpout = (FILE *) 0; typedef int yy_state_type; extern int yysdplineno; extern char *yysdptext; #define yytext_ptr yysdptext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yysdptext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yysdpleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 27 #define YY_END_OF_BUFFER 28 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[51] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 12, 11, 10, 12, 8, 8, 8, 8, 8, 8, 8, 8, 15, 14, 17, 15, 13, 23, 25, 26, 20, 19, 22, 20, 18, 9, 8, 5, 7, 4, 6, 2, 3, 1, 16, 13, 23, 24, 21, 18, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 6, 6, 5, 6, 7, 1, 1, 7, 7, 1, 7, 7, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 1, 9, 1, 6, 6, 10, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 13, 11, 14, 11, 11, 11, 15, 11, 11, 16, 11, 11, 11, 11, 6, 1, 6, 6, 7, 6, 10, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 13, 11, 14, 11, 11, 11, 15, 11, 11, 16, 11, 11, 11, 11, 6, 6, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[17] = { 0, 1, 1, 2, 2, 3, 4, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5 } ; static yyconst flex_int16_t yy_base[58] = { 0, 0, 9, 24, 31, 4, 26, 39, 44, 87, 88, 88, 88, 83, 0, 76, 75, 74, 73, 72, 71, 65, 88, 88, 88, 68, 30, 0, 88, 34, 88, 88, 88, 33, 0, 88, 0, 88, 88, 88, 88, 88, 88, 88, 88, 23, 0, 88, 88, 0, 88, 49, 54, 59, 64, 67, 72, 74 } ; static yyconst flex_int16_t yy_def[58] = { 0, 51, 50, 52, 52, 53, 53, 54, 54, 50, 50, 50, 50, 50, 55, 55, 55, 55, 55, 55, 55, 55, 50, 50, 50, 50, 50, 56, 50, 50, 50, 50, 50, 50, 57, 50, 55, 50, 50, 50, 50, 50, 50, 50, 50, 50, 56, 50, 50, 57, 0, 50, 50, 50, 50, 50, 50, 50 } ; static yyconst flex_int16_t yy_nxt[105] = { 0, 10, 11, 12, 13, 50, 10, 28, 29, 10, 10, 11, 12, 13, 14, 10, 14, 14, 10, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 28, 29, 45, 26, 23, 24, 25, 48, 47, 45, 26, 30, 31, 32, 33, 30, 30, 31, 32, 33, 30, 14, 14, 14, 14, 14, 22, 22, 22, 22, 22, 27, 27, 27, 27, 27, 34, 34, 34, 34, 34, 36, 44, 36, 46, 43, 46, 46, 46, 49, 49, 42, 41, 40, 39, 38, 37, 35, 50, 9, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 } ; static yyconst flex_int16_t yy_chk[105] = { 0, 1, 1, 1, 1, 0, 1, 5, 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 6, 6, 45, 3, 4, 4, 4, 33, 29, 26, 4, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 25, 55, 56, 21, 56, 56, 56, 57, 57, 20, 19, 18, 17, 16, 15, 13, 9, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yysdp_flex_debug; int yysdp_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yysdptext; #line 1 "sdp_scanner.lxx" /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #line 20 "sdp_scanner.lxx" #include #include "sdp_parse_ctrl.h" #include "sdp_parser.h" #include "audits/memman.h" using namespace std; #line 516 "sdp_scanner.cxx" #define INITIAL 0 #define C_NUM 1 #define C_LINE 2 #define C_SAFE 3 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yysdpwrap (void ); #else extern int yysdpwrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = NULL; static void yy_push_state (int new_state ); static void yy_pop_state (void ); static int yy_top_state (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( yysdptext, yysdpleng, 1, yysdpout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yysdpin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yysdpin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yysdpin))==0 && ferror(yysdpin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yysdpin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yysdplex (void); #define YY_DECL int yysdplex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yysdptext and yysdpleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ if ( yysdpleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yysdptext[yysdpleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 41 "sdp_scanner.lxx" switch (t_sdp_parser::context) { case t_sdp_parser::X_NUM: BEGIN(C_NUM); break; case t_sdp_parser::X_LINE: BEGIN(C_LINE); break; case t_sdp_parser::X_SAFE: BEGIN(C_SAFE); break; default: BEGIN(INITIAL); } /* SDP lines */ #line 695 "sdp_scanner.cxx" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yysdpin ) yysdpin = stdin; if ( ! yysdpout ) yysdpout = stdout; if ( ! YY_CURRENT_BUFFER ) { yysdpensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yysdp_create_buffer(yysdpin,YY_BUF_SIZE ); } yysdp_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yysdptext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 51 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 88 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 50 "sdp_scanner.lxx" { return T_LINE_VERSION; } YY_BREAK case 2: YY_RULE_SETUP #line 51 "sdp_scanner.lxx" { return T_LINE_ORIGIN; } YY_BREAK case 3: YY_RULE_SETUP #line 52 "sdp_scanner.lxx" { return T_LINE_SESSION_NAME; } YY_BREAK case 4: YY_RULE_SETUP #line 53 "sdp_scanner.lxx" { return T_LINE_CONNECTION; } YY_BREAK case 5: YY_RULE_SETUP #line 54 "sdp_scanner.lxx" { return T_LINE_ATTRIBUTE; } YY_BREAK case 6: YY_RULE_SETUP #line 55 "sdp_scanner.lxx" { return T_LINE_MEDIA; } YY_BREAK case 7: YY_RULE_SETUP #line 56 "sdp_scanner.lxx" { return T_LINE_UNKNOWN; } YY_BREAK /* Token as define in RFC 3261 */ case 8: YY_RULE_SETUP #line 59 "sdp_scanner.lxx" { yysdplval.yysdpt_str = new string(yysdptext); MEMMAN_NEW(yysdplval.yysdpt_str); return T_TOKEN; } YY_BREAK /* End of line */ case 9: /* rule 9 can match eol */ YY_RULE_SETUP #line 64 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 10: /* rule 10 can match eol */ YY_RULE_SETUP #line 65 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 11: YY_RULE_SETUP #line 67 "sdp_scanner.lxx" /* Skip white space */ YY_BREAK /* Single character token */ case 12: YY_RULE_SETUP #line 70 "sdp_scanner.lxx" { return yysdptext[0]; } YY_BREAK /* Number */ case 13: YY_RULE_SETUP #line 73 "sdp_scanner.lxx" { yysdplval.yysdpt_int = atoi(yysdptext); return T_NUM; } YY_BREAK case 14: YY_RULE_SETUP #line 75 "sdp_scanner.lxx" /* Skip white space */ YY_BREAK case 15: YY_RULE_SETUP #line 76 "sdp_scanner.lxx" { return yysdptext[0]; } YY_BREAK case 16: /* rule 16 can match eol */ YY_RULE_SETUP #line 77 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 17: /* rule 17 can match eol */ YY_RULE_SETUP #line 78 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK /* Safe */ case 18: YY_RULE_SETUP #line 81 "sdp_scanner.lxx" { yysdplval.yysdpt_str = new string(yysdptext); MEMMAN_NEW(yysdplval.yysdpt_str); return T_SAFE; } YY_BREAK case 19: YY_RULE_SETUP #line 84 "sdp_scanner.lxx" /* Skip white space */ YY_BREAK case 20: YY_RULE_SETUP #line 85 "sdp_scanner.lxx" { return yysdptext[0]; } YY_BREAK case 21: /* rule 21 can match eol */ YY_RULE_SETUP #line 86 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 22: /* rule 22 can match eol */ YY_RULE_SETUP #line 87 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK /* Get all text till end of line */ case 23: YY_RULE_SETUP #line 90 "sdp_scanner.lxx" { yysdplval.yysdpt_str = new string(yysdptext); MEMMAN_NEW(yysdplval.yysdpt_str); return T_LINE; } YY_BREAK case 24: /* rule 24 can match eol */ YY_RULE_SETUP #line 93 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 25: /* rule 25 can match eol */ YY_RULE_SETUP #line 94 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 26: YY_RULE_SETUP #line 95 "sdp_scanner.lxx" { return T_CRLF; } YY_BREAK case 27: YY_RULE_SETUP #line 96 "sdp_scanner.lxx" ECHO; YY_BREAK #line 935 "sdp_scanner.cxx" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(C_NUM): case YY_STATE_EOF(C_LINE): case YY_STATE_EOF(C_SAFE): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yysdpin at a new source and called * yysdplex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yysdpin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yysdpwrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yysdptext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yysdplex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yysdprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yysdprestart(yysdpin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 51 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 51 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 50); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yysdptext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yysdprestart(yysdpin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yysdpwrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yysdptext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yysdprestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yysdpensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yysdp_create_buffer(yysdpin,YY_BUF_SIZE ); } yysdp_init_buffer(YY_CURRENT_BUFFER,input_file ); yysdp_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yysdp_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yysdppop_buffer_state(); * yysdppush_buffer_state(new_buffer); */ yysdpensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yysdp_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yysdpwrap()) processing, but the only time this flag * is looked at is after yysdpwrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yysdp_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yysdpin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yysdp_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yysdpalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yysdp_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yysdpalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yysdp_create_buffer()" ); b->yy_is_our_buffer = 1; yysdp_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yysdp_create_buffer() * */ void yysdp_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yysdpfree((void *) b->yy_ch_buf ); yysdpfree((void *) b ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yysdprestart() or at EOF. */ static void yysdp_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yysdp_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yysdp_init_buffer was _probably_ * called from yysdprestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yysdp_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yysdp_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yysdppush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yysdpensure_buffer_stack(); /* This block is copied from yysdp_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yysdp_switch_to_buffer. */ yysdp_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yysdppop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yysdp_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yysdp_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yysdpensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yysdpalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yysdprealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yysdp_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yysdpalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yysdp_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yysdp_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yysdplex() will * scan from a @e copy of @a str. * @param str a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yysdp_scan_bytes() instead. */ YY_BUFFER_STATE yysdp_scan_string (yyconst char * yystr ) { return yysdp_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yysdplex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yysdp_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yysdpalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yysdp_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yysdp_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yysdp_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } static void yy_push_state (int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) yysdpalloc(new_size ); else (yy_start_stack) = (int *) yysdprealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } static void yy_pop_state (void) { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } static int yy_top_state (void) { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yysdptext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yysdptext[yysdpleng] = (yy_hold_char); \ (yy_c_buf_p) = yysdptext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yysdpleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the input stream. * */ FILE *yysdpget_in (void) { return yysdpin; } /** Get the output stream. * */ FILE *yysdpget_out (void) { return yysdpout; } /** Get the length of the current token. * */ int yysdpget_leng (void) { return yysdpleng; } /** Get the current token. * */ char *yysdpget_text (void) { return yysdptext; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yysdp_switch_to_buffer */ void yysdpset_in (FILE * in_str ) { yysdpin = in_str ; } void yysdpset_out (FILE * out_str ) { yysdpout = out_str ; } int yysdpget_debug (void) { return yysdp_flex_debug; } void yysdpset_debug (int bdebug ) { yysdp_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yysdplex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; (yy_start_stack_ptr) = 0; (yy_start_stack_depth) = 0; (yy_start_stack) = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yysdpin = stdin; yysdpout = stdout; #else yysdpin = (FILE *) 0; yysdpout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yysdplex_init() */ return 0; } /* yysdplex_destroy is for both reentrant and non-reentrant scanners. */ int yysdplex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yysdp_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yysdppop_buffer_state(); } /* Destroy the stack itself. */ yysdpfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Destroy the start condition stack. */ yysdpfree((yy_start_stack) ); (yy_start_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yysdplex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yysdpalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yysdprealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yysdpfree (void * ptr ) { free( (char *) ptr ); /* see yysdprealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 96 "sdp_scanner.lxx" twinkle-1.4.2/src/sdp/sdp_scanner.lxx0000644000175000001440000000521411127714060014522 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %{ #include #include "sdp_parse_ctrl.h" #include "sdp_parser.h" #include "audits/memman.h" using namespace std; %} %option noyywrap %option stack DIGIT [0-9] ALPHA [a-zA-Z] ALNUM [a-zA-Z0-9] TOKEN_SYM [[:alnum:]\-\.!%\*_\+\'~] SAFE_SYM [[:alnum:]'`\-\.\/:\?\"#\$&\*;=@\[\]\^_\{|\}\+~\"] %x C_NUM %x C_LINE %x C_SAFE %% switch (t_sdp_parser::context) { case t_sdp_parser::X_NUM: BEGIN(C_NUM); break; case t_sdp_parser::X_LINE: BEGIN(C_LINE); break; case t_sdp_parser::X_SAFE: BEGIN(C_SAFE); break; default: BEGIN(INITIAL); } /* SDP lines */ ^v= { return T_LINE_VERSION; } ^o= { return T_LINE_ORIGIN; } ^s= { return T_LINE_SESSION_NAME; } ^c= { return T_LINE_CONNECTION; } ^a= { return T_LINE_ATTRIBUTE; } ^m= { return T_LINE_MEDIA; } ^{ALPHA}= { return T_LINE_UNKNOWN; } /* Token as define in RFC 3261 */ {TOKEN_SYM}+ { yysdplval.yysdpt_str = new string(yysdptext); MEMMAN_NEW(yysdplval.yysdpt_str); return T_TOKEN; } /* End of line */ \r\n { return T_CRLF; } \n { return T_CRLF; } [[:blank:]] /* Skip white space */ /* Single character token */ . { return yysdptext[0]; } /* Number */ {DIGIT}+ { yysdplval.yysdpt_int = atoi(yysdptext); return T_NUM; } [[:blank:]] /* Skip white space */ . { return yysdptext[0]; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Safe */ {SAFE_SYM}+ { yysdplval.yysdpt_str = new string(yysdptext); MEMMAN_NEW(yysdplval.yysdpt_str); return T_SAFE; } [[:blank:]] /* Skip white space */ . { return yysdptext[0]; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Get all text till end of line */ [^\r\n]+ { yysdplval.yysdpt_str = new string(yysdptext); MEMMAN_NEW(yysdplval.yysdpt_str); return T_LINE; } \r\n { return T_CRLF; } \n { return T_CRLF; } \r { return T_CRLF; } twinkle-1.4.2/src/sdp/sdp.cpp0000644000175000001440000004641511127714053012772 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "protocol.h" #include "sdp_parse_ctrl.h" #include "sdp.h" #include "util.h" #include "parser/hdr_warning.h" #include "parser/parameter.h" #include "audits/memman.h" using namespace std; string sdp_ntwk_type2str(t_sdp_ntwk_type n) { switch(n) { case SDP_NTWK_NULL: return "NULL"; case SDP_NTWK_IN: return "IN"; default: assert(false); } } t_sdp_ntwk_type str2sdp_ntwk_type(string s) { if (s == "IN") return SDP_NTWK_IN; throw (t_sdp_syntax_error("unknown network type: " + s)); } string sdp_addr_type2str(t_sdp_addr_type a) { switch(a) { case SDP_ADDR_NULL: return "NULL"; case SDP_ADDR_IP4: return "IP4"; case SDP_ADDR_IP6: return "IP6"; default: assert(false); } } t_sdp_addr_type str2sdp_addr_type(string s) { if (s == "IP4") return SDP_ADDR_IP4; if (s == "IP6") return SDP_ADDR_IP6; throw (t_sdp_syntax_error("unknown address type: " + s)); } string sdp_transport2str(t_sdp_transport t) { switch(t) { case SDP_TRANS_RTP: return "RTP/AVP"; case SDP_TRANS_UDP: return "udp"; default: assert(false); } } t_sdp_transport str2sdp_transport(string s) { if (s == "RTP/AVP") return SDP_TRANS_RTP; if (s == "udp") return SDP_TRANS_UDP; // Other transports are not recognized and are mapped to other. return SDP_TRANS_OTHER; } t_sdp_media_type str2sdp_media_type(string s) { if (s == "audio") return SDP_AUDIO; if (s == "video") return SDP_VIDEO; return SDP_OTHER; } string sdp_media_type2str(t_sdp_media_type m) { switch(m) { case SDP_AUDIO: return "audio"; case SDP_VIDEO: return "video"; default: assert(false); } } string get_rtpmap(unsigned format, t_audio_codec codec) { string rtpmap; rtpmap = int2str(format); rtpmap += ' '; switch(codec) { case CODEC_G711_ULAW: rtpmap += SDP_RTPMAP_G711_ULAW; break; case CODEC_G711_ALAW: rtpmap += SDP_RTPMAP_G711_ALAW; break; case CODEC_GSM: rtpmap += SDP_RTPMAP_GSM; break; case CODEC_SPEEX_NB: rtpmap += SDP_RTPMAP_SPEEX_NB; break; case CODEC_SPEEX_WB: rtpmap += SDP_RTPMAP_SPEEX_WB; break; case CODEC_SPEEX_UWB: rtpmap += SDP_RTPMAP_SPEEX_UWB; break; case CODEC_ILBC: rtpmap += SDP_RTPMAP_ILBC; break; case CODEC_G726_16: rtpmap += SDP_RTPMAP_G726_16; break; case CODEC_G726_24: rtpmap += SDP_RTPMAP_G726_24; break; case CODEC_G726_32: rtpmap += SDP_RTPMAP_G726_32; break; case CODEC_G726_40: rtpmap += SDP_RTPMAP_G726_40; break; case CODEC_TELEPHONE_EVENT: rtpmap += SDP_RTPMAP_TELEPHONE_EV; break; default: assert(false); } return rtpmap; } string sdp_media_direction2str(t_sdp_media_direction d) { switch(d) { case SDP_INACTIVE: return "inactive"; case SDP_SENDONLY: return "sendonly"; case SDP_RECVONLY: return "recvonly"; case SDP_SENDRECV: return "sendrecv"; default: assert(false); } } /////////////////////////////////// // class t_sdp_origin /////////////////////////////////// t_sdp_origin::t_sdp_origin() { network_type = SDP_NTWK_NULL; address_type = SDP_ADDR_NULL; } t_sdp_origin::t_sdp_origin(string _username, string _session_id, string _session_version, string _address) : username(_username), session_id(_session_id), session_version(_session_version), address(_address) { network_type = SDP_NTWK_IN; address_type = SDP_ADDR_IP4; } string t_sdp_origin::encode(void) const { string s; s = "o="; s += username; s += ' ' + session_id; s += ' ' + session_version; s += ' ' + sdp_ntwk_type2str(network_type); s += ' ' + sdp_addr_type2str(address_type); s += ' ' + address; s += CRLF; return s; } /////////////////////////////////// // class t_sdp_connection /////////////////////////////////// t_sdp_connection::t_sdp_connection() { network_type = SDP_NTWK_NULL; } t_sdp_connection::t_sdp_connection(string _address) : address(_address) { network_type = SDP_NTWK_IN; address_type = SDP_ADDR_IP4; } string t_sdp_connection::encode(void) const { string s; s = "c="; s += sdp_ntwk_type2str(network_type); s += ' ' + sdp_addr_type2str(address_type); s += ' ' + address; s += CRLF; return s; } /////////////////////////////////// // class t_sdp_attr /////////////////////////////////// t_sdp_attr::t_sdp_attr(string _name) { name = _name; } t_sdp_attr::t_sdp_attr(string _name, string _value) { name = _name; value = _value; } string t_sdp_attr::encode(void) const { string s; s = "a="; s += name; if (value != "") { s += ':' + value; } s += CRLF; return s; } /////////////////////////////////// // class t_sdp_media /////////////////////////////////// t_sdp_media::t_sdp_media() { port = 0; format_dtmf = 0; } t_sdp_media::t_sdp_media(t_sdp_media_type _media_type, unsigned short _port, const list &_formats, unsigned short _format_dtmf, const map &ac2format) { media_type = sdp_media_type2str(_media_type); port = _port; transport = sdp_transport2str(SDP_TRANS_RTP); format_dtmf = _format_dtmf; for (list::const_iterator i = _formats.begin(); i != _formats.end(); i++) { map::const_iterator it; it = ac2format.find(*i); assert(it != ac2format.end()); add_format(it->second, *i); } if (format_dtmf > 0) { add_format(format_dtmf, CODEC_TELEPHONE_EVENT); } } string t_sdp_media::encode(void) const { string s; s = "m="; s += media_type; s += ' ' + int2str(port); s += ' ' + transport; // Encode media formats. Note that only one of the format lists // will be populated depending on the media type. // Numeric formats. for (list::const_iterator i = formats.begin(); i != formats.end(); ++i) { s += ' ' + int2str(*i); } // Alpha numeric formats. for (list::const_iterator i = alpha_num_formats.begin(); i != alpha_num_formats.end(); ++i) { s += ' ' + *i; } s += CRLF; // Connection information. if (connection.network_type != SDP_NTWK_NULL) { s += connection.encode(); } // Attributes. for (list::const_iterator i = attributes.begin(); i != attributes.end(); ++i) { s += i->encode(); } return s; } void t_sdp_media::add_format(unsigned short f, t_audio_codec codec) { formats.push_back(f); // RFC 3264 5.1 // All media descriptions SHOULD contain an rtpmap string rtpmap = get_rtpmap(f, codec); attributes.push_back(t_sdp_attr("rtpmap", rtpmap)); // RFC 2833 3.9 // Add fmtp parameter if (format_dtmf > 0 && f == format_dtmf) { string fmtp = int2str(f); fmtp += ' '; fmtp += "0-15"; attributes.push_back(t_sdp_attr("fmtp", fmtp)); } } t_sdp_attr *t_sdp_media::get_attribute(const string &name) { for (list::iterator i = attributes.begin(); i != attributes.end(); i++) { if (cmp_nocase(i->name, name) == 0) return &(*i); } // Attribute does not exist return NULL; } list t_sdp_media::get_attributes(const string &name) { list l; for (list::iterator i = attributes.begin(); i != attributes.end(); i++) { if (cmp_nocase(i->name, name) == 0) l.push_back(&(*i)); } return l; } t_sdp_media_direction t_sdp_media::get_direction(void) const { t_sdp_attr *a; t_sdp_media *self = const_cast(this); a = self->get_attribute("inactive"); if (a) return SDP_INACTIVE; a = self->get_attribute("sendonly"); if (a) return SDP_SENDONLY; a = self->get_attribute("recvonly"); if (a) return SDP_RECVONLY; return SDP_SENDRECV; } t_sdp_media_type t_sdp_media::get_media_type(void) const { return str2sdp_media_type(media_type); } t_sdp_transport t_sdp_media::get_transport(void) const { return str2sdp_transport(transport); } /////////////////////////////////// // class t_sdp /////////////////////////////////// t_sdp::t_sdp() : t_sip_body(), version(0) {} t_sdp::t_sdp(const string &user, const string &sess_id, const string &sess_version, const string &user_host, const string &media_host, unsigned short media_port, const list &formats, unsigned short format_dtmf, const map &ac2format) : t_sip_body(), version(0), origin(user, sess_id, sess_version, user_host), connection(media_host) { media.push_back(t_sdp_media(SDP_AUDIO, media_port, formats, format_dtmf, ac2format)); } t_sdp::t_sdp(const string &user, const string &sess_id, const string &sess_version, const string &user_host, const string &media_host) : t_sip_body(), version(0), origin(user, sess_id, sess_version, user_host), connection(media_host) {} void t_sdp::add_media(const t_sdp_media &m) { media.push_back(m); } string t_sdp::encode(void) const { string s; s = "v=" + int2str(version) + CRLF; s += origin.encode(); if (session_name == "") { // RFC 3264 5 // Session name may no be empty. Recommende is '-' s += "s=-"; s += CRLF; } else { s += "s=" + session_name + CRLF; } if (connection.network_type != SDP_NTWK_NULL) { s += connection.encode(); } // RFC 3264 5 // Time parameter should be 0 0 s += "t=0 0"; s += CRLF; for (list::const_iterator i = attributes.begin(); i != attributes.end(); i++) { s += i->encode(); } for (list::const_iterator i = media.begin(); i != media.end(); i++) { s += i->encode(); } return s; } t_sip_body *t_sdp::copy(void) const { t_sdp *s = new t_sdp(*this); MEMMAN_NEW(s); return s; } t_body_type t_sdp::get_type(void) const { return BODY_SDP; } t_media t_sdp::get_media(void) const { return t_media("application", "sdp"); } bool t_sdp::is_supported(int &warn_code, string &warn_text) const { warn_text = ""; if (version != 0) { warn_code = W_399_MISCELLANEOUS; warn_text = "SDP version "; warn_text += int2str(version); warn_text += " not supported"; return false; } const t_sdp_media *m = get_first_media(SDP_AUDIO); // Connection information must be present at the session level // and/or the media level if (connection.network_type == SDP_NTWK_NULL) { if (m == NULL || m->connection.network_type == SDP_NTWK_NULL) { warn_code = W_399_MISCELLANEOUS; warn_text = "c-line missing"; return false; } } else { // Only Internet is supported if (connection.network_type != SDP_NTWK_IN) { warn_code = W_300_INCOMPATIBLE_NWK_PROT; return false; } // Only IPv4 is supported if (connection.address_type != SDP_ADDR_IP4) { warn_code = W_301_INCOMPATIBLE_ADDR_FORMAT; return false; } } // There must be at least 1 audio stream with a non-zero port value if (m == NULL && !media.empty()) { warn_code = W_304_MEDIA_TYPE_NOT_AVAILABLE; warn_text = "Valid media stream for audio is missing"; return false; } // RFC 3264 5, RFC 3725 flow IV // There may be 0 media streams if (media.empty()) { return true; } // Check connection information on media level if (m->connection.network_type != SDP_NTWK_NULL && m->connection.address_type != SDP_ADDR_IP4) { warn_code = W_301_INCOMPATIBLE_ADDR_FORMAT; return false; } if (m->get_transport() != SDP_TRANS_RTP) { warn_code = W_302_INCOMPATIBLE_TRANS_PROT; return false; } t_sdp_media *m2 = const_cast(m); const t_sdp_attr *a = m2->get_attribute("ptime"); if (a) { unsigned short p = atoi(a->value.c_str()); if (p < MIN_PTIME) { warn_code = W_306_ATTRIBUTE_NOT_UNDERSTOOD; warn_text = "Attribute 'ptime' too small. must be >= "; warn_text += int2str(MIN_PTIME); return false; } if (p > MAX_PTIME) { warn_code = W_306_ATTRIBUTE_NOT_UNDERSTOOD; warn_text = "Attribute 'ptime' too big. must be <= "; warn_text += int2str(MAX_PTIME); return false; } } return true; } string t_sdp::get_rtp_host(t_sdp_media_type media_type) const { const t_sdp_media *m = get_first_media(media_type); assert(m != NULL); // If the media line has its own connection information, then // take the host information from there. if (m->connection.network_type == SDP_NTWK_IN) { return m->connection.address; } // The host information must be in the session connection info assert(connection.network_type == SDP_NTWK_IN); return connection.address; } unsigned short t_sdp::get_rtp_port(t_sdp_media_type media_type) const { const t_sdp_media *m = get_first_media(media_type); assert(m != NULL); return m->port; } list t_sdp::get_codecs(t_sdp_media_type media_type) const { const t_sdp_media *m = get_first_media(media_type); assert(m != NULL); return m->formats; } string t_sdp::get_codec_description(t_sdp_media_type media_type, unsigned short codec) const { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); const list attrs = m->get_attributes("rtpmap"); if (attrs.empty()) return ""; for (list::const_iterator i = attrs.begin(); i != attrs.end(); i++) { vector l = split_ws((*i)->value); if (atoi(l.front().c_str()) == codec) { return l.back(); } } return ""; } t_audio_codec t_sdp::get_rtpmap_codec(const string &rtpmap) const { if (rtpmap.empty()) return CODEC_NULL; vector rtpmap_elems = split(rtpmap, '/'); if (rtpmap_elems.size() < 2) { // RFC 2327 // The rtpmap should at least contain the encoding name // and sample rate return CODEC_UNSUPPORTED; } string codec_name = trim(rtpmap_elems[0]); int sample_rate = atoi(trim(rtpmap_elems[1]).c_str()); if (cmp_nocase(codec_name, SDP_AC_NAME_G711_ULAW) == 0 && sample_rate == 8000) { return CODEC_G711_ULAW; } else if (cmp_nocase(codec_name, SDP_AC_NAME_G711_ALAW) == 0 && sample_rate == 8000) { return CODEC_G711_ALAW; } else if (cmp_nocase(codec_name, SDP_AC_NAME_GSM) == 0 && sample_rate == 8000) { return CODEC_GSM; } else if (cmp_nocase(codec_name, SDP_AC_NAME_SPEEX) == 0 && sample_rate == 8000) { return CODEC_SPEEX_NB; } else if (cmp_nocase(codec_name, SDP_AC_NAME_SPEEX) == 0 && sample_rate == 16000) { return CODEC_SPEEX_WB; } else if (cmp_nocase(codec_name, SDP_AC_NAME_SPEEX) == 0 && sample_rate == 32000) { return CODEC_SPEEX_UWB; } else if (cmp_nocase(codec_name, SDP_AC_NAME_ILBC) == 0 && sample_rate == 8000) { return CODEC_ILBC; } else if (cmp_nocase(codec_name, SDP_AC_NAME_G726_16) == 0 && sample_rate == 8000) { return CODEC_G726_16; } else if (cmp_nocase(codec_name, SDP_AC_NAME_G726_24) == 0 && sample_rate == 8000) { return CODEC_G726_24; } else if (cmp_nocase(codec_name, SDP_AC_NAME_G726_32) == 0 && sample_rate == 8000) { return CODEC_G726_32; } else if (cmp_nocase(codec_name, SDP_AC_NAME_G726_40) == 0 && sample_rate == 8000) { return CODEC_G726_40; } else if (cmp_nocase(codec_name, SDP_AC_NAME_TELEPHONE_EV) == 0) { return CODEC_TELEPHONE_EVENT; } return CODEC_UNSUPPORTED; } t_audio_codec t_sdp::get_codec(t_sdp_media_type media_type, unsigned short codec) const { string rtpmap = get_codec_description(media_type, codec); // If there is no rtpmap description then use the static // payload definition as defined by RFC 3551 if (rtpmap.empty()) { switch(codec) { case SDP_FORMAT_G711_ULAW: return CODEC_G711_ULAW; case SDP_FORMAT_G711_ALAW: return CODEC_G711_ALAW; case SDP_FORMAT_GSM: return CODEC_GSM; default: return CODEC_UNSUPPORTED; } } // Use the rtpmap description to map the payload number // to a codec return get_rtpmap_codec(rtpmap); } t_sdp_media_direction t_sdp::get_direction(t_sdp_media_type media_type) const { const t_sdp_media *m = get_first_media(media_type); assert(m != NULL); return m->get_direction(); } string t_sdp::get_fmtp(t_sdp_media_type media_type, unsigned short codec) const { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); const list attrs = m->get_attributes("fmtp"); if (attrs.empty()) return ""; for (list::const_iterator i = attrs.begin(); i != attrs.end(); i++) { vector l = split_ws((*i)->value); if (atoi(l.front().c_str()) == codec) { return l.back(); } } return ""; } int t_sdp::get_fmtp_int_param(t_sdp_media_type media_type, unsigned short codec, const string param) const { string fmtp = get_fmtp(media_type, codec); if (fmtp.empty()) return -1; int value; list l = str2param_list(fmtp); list::const_iterator it = find(l.begin(), l.end(), t_parameter(param, "")); if (it != l.end()) { value = atoi(it->value.c_str()); } else { value = -1; } return value; } unsigned short t_sdp::get_ptime(t_sdp_media_type media_type) const { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); const t_sdp_attr *a = m->get_attribute("ptime"); if (!a) return 0; return atoi(a->value.c_str()); } bool t_sdp::get_zrtp_support(t_sdp_media_type media_type) const { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); const t_sdp_attr *a = m->get_attribute("zrtp"); if (!a) return false; return true; } void t_sdp::set_ptime(t_sdp_media_type media_type, unsigned short ptime) { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); t_sdp_attr a("ptime", int2str(ptime)); m->attributes.push_back(a); } void t_sdp::set_direction(t_sdp_media_type media_type, t_sdp_media_direction direction) { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); t_sdp_attr a(sdp_media_direction2str(direction)); m->attributes.push_back(a); } void t_sdp::set_fmtp(t_sdp_media_type media_type, unsigned short codec, const string &fmtp) { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); string s = int2str(codec); s += ' '; s += fmtp; t_sdp_attr a("fmtp", s); m->attributes.push_back(a); } void t_sdp::set_fmtp_int_param(t_sdp_media_type media_type, unsigned short codec, const string ¶m, int value) { string fmtp(param); fmtp += '='; fmtp += int2str(value); set_fmtp(media_type, codec, fmtp); } void t_sdp::set_zrtp_support(t_sdp_media_type media_type) { t_sdp_media *m = const_cast(get_first_media(media_type)); assert(m != NULL); t_sdp_attr a("zrtp"); m->attributes.push_back(a); } const t_sdp_media *t_sdp::get_first_media(t_sdp_media_type media_type) const { for (list::const_iterator i = media.begin(); i != media.end(); i++) { if (i->get_media_type() == media_type && i->port != 0) { return &(*i); } } return NULL; } bool t_sdp::local_ip_check(void) const { if (origin.address == AUTO_IP4_ADDRESS) return false; if (connection.address == AUTO_IP4_ADDRESS) return false; for (list::const_iterator it = media.begin(); it != media.end(); ++it) { if (it->connection.address == AUTO_IP4_ADDRESS) return false; } return true; } twinkle-1.4.2/src/sdp/sdp_parser.h0000644000175000001440000000576711127714045014021 00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_NUM = 258, T_TOKEN = 259, T_SAFE = 260, T_LINE = 261, T_CRLF = 262, T_LINE_VERSION = 263, T_LINE_ORIGIN = 264, T_LINE_SESSION_NAME = 265, T_LINE_CONNECTION = 266, T_LINE_ATTRIBUTE = 267, T_LINE_MEDIA = 268, T_LINE_UNKNOWN = 269, T_NULL = 270 }; #endif /* Tokens. */ #define T_NUM 258 #define T_TOKEN 259 #define T_SAFE 260 #define T_LINE 261 #define T_CRLF 262 #define T_LINE_VERSION 263 #define T_LINE_ORIGIN 264 #define T_LINE_SESSION_NAME 265 #define T_LINE_CONNECTION 266 #define T_LINE_ATTRIBUTE 267 #define T_LINE_MEDIA 268 #define T_LINE_UNKNOWN 269 #define T_NULL 270 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 50 "sdp_parser.yxx" { int yysdpt_int; string *yysdpt_str; t_sdp_ntwk_type yysdpt_ntwk_type; t_sdp_addr_type yysdpt_addr_type; t_sdp_connection *yysdpt_connection; list *yysdpt_attributes; t_sdp_attr *yysdpt_attribute; t_sdp_media *yysdpt_media; list *yysdpt_token_list; } /* Line 1529 of yacc.c. */ #line 91 "sdp_parser.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yysdplval; twinkle-1.4.2/src/sdp/sdp_parse_ctrl.h0000644000175000001440000000360111127714045014644 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Parser control #ifndef _SDP_PARSE_CTRL_H #define _SDP_PARSE_CTRL_H #include "sdp.h" #include "threads/mutex.h" #define SDP t_sdp_parser::sdp #define CTX_INITIAL (t_sdp_parser::context = t_sdp_parser::X_INITIAL) #define CTX_SAFE (t_sdp_parser::context = t_sdp_parser::X_SAFE) #define CTX_NUM (t_sdp_parser::context = t_sdp_parser::X_NUM) #define CTX_LINE (t_sdp_parser::context = t_sdp_parser::X_LINE) // The t_sdp_parser controls the direction of the scanner/parser // process and it stores the results from the parser. class t_sdp_parser { private: /** Mutex to synchronize parse operations */ static t_mutex mtx_parser; public: enum t_context { X_INITIAL, // Initial context X_SAFE, // Safe context X_NUM, // Number context X_LINE, // Whole line context }; static t_context context; // Scan context static t_sdp *sdp; // SDP that has been parsed // Parse string s. Throw int exception when parsing fails. static t_sdp *parse(const string &s); }; // Error that can be thrown as exception class t_sdp_syntax_error { public: string error; t_sdp_syntax_error(const string &e); }; #endif twinkle-1.4.2/src/sdp/sdp_parser.cxx0000644000175000001440000015604611127716006014370 00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse yysdpparse #define yylex yysdplex #define yyerror yysdperror #define yylval yysdplval #define yychar yysdpchar #define yydebug yysdpdebug #define yynerrs yysdpnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_NUM = 258, T_TOKEN = 259, T_SAFE = 260, T_LINE = 261, T_CRLF = 262, T_LINE_VERSION = 263, T_LINE_ORIGIN = 264, T_LINE_SESSION_NAME = 265, T_LINE_CONNECTION = 266, T_LINE_ATTRIBUTE = 267, T_LINE_MEDIA = 268, T_LINE_UNKNOWN = 269, T_NULL = 270 }; #endif /* Tokens. */ #define T_NUM 258 #define T_TOKEN 259 #define T_SAFE 260 #define T_LINE 261 #define T_CRLF 262 #define T_LINE_VERSION 263 #define T_LINE_ORIGIN 264 #define T_LINE_SESSION_NAME 265 #define T_LINE_CONNECTION 266 #define T_LINE_ATTRIBUTE 267 #define T_LINE_MEDIA 268 #define T_LINE_UNKNOWN 269 #define T_NULL 270 /* Copy the first part of user declarations. */ #line 19 "sdp_parser.yxx" #include #include #include #include "sdp_parse_ctrl.h" #include "sdp.h" #include "util.h" #include "audits/memman.h" using namespace std; extern int yysdplex(void); void yysdperror(const char *s); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 50 "sdp_parser.yxx" { int yysdpt_int; string *yysdpt_str; t_sdp_ntwk_type yysdpt_ntwk_type; t_sdp_addr_type yysdpt_addr_type; t_sdp_connection *yysdpt_connection; list *yysdpt_attributes; t_sdp_attr *yysdpt_attribute; t_sdp_media *yysdpt_media; list *yysdpt_token_list; } /* Line 193 of yacc.c. */ #line 161 "sdp_parser.cxx" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 174 "sdp_parser.cxx" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 7 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 48 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 18 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 31 /* YYNRULES -- Number of rules. */ #define YYNRULES 39 /* YYNRULES -- Number of states. */ #define YYNSTATES 74 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 270 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 12, 15, 16, 17, 23, 24, 25, 36, 38, 40, 41, 42, 48, 50, 51, 57, 59, 60, 63, 67, 69, 70, 71, 77, 78, 81, 82, 83, 96, 98, 102, 103, 106, 107, 110, 111, 112 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 19, 0, -1, 20, 23, 28, 45, 31, 45, 33, 39, -1, 1, 15, -1, -1, -1, 8, 21, 3, 22, 7, -1, -1, -1, 9, 24, 5, 25, 4, 4, 26, 27, 4, 7, -1, 4, -1, 4, -1, -1, -1, 10, 29, 6, 30, 7, -1, 32, -1, -1, 11, 26, 27, 4, 7, -1, 34, -1, -1, 34, 35, -1, 12, 36, 7, -1, 4, -1, -1, -1, 4, 16, 37, 6, 38, -1, -1, 39, 40, -1, -1, -1, 13, 4, 41, 3, 42, 43, 44, 7, 45, 32, 45, 34, -1, 4, -1, 4, 17, 4, -1, -1, 44, 4, -1, -1, 45, 46, -1, -1, -1, 14, 47, 6, 48, 7, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 105, 105, 117, 125, 125, 125, 130, 130, 130, 144, 159, 170, 171, 170, 176, 181, 182, 192, 197, 198, 203, 207, 211, 211, 211, 218, 219, 225, 225, 225, 261, 263, 271, 272, 279, 280, 283, 283, 283 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "T_NUM", "T_TOKEN", "T_SAFE", "T_LINE", "T_CRLF", "T_LINE_VERSION", "T_LINE_ORIGIN", "T_LINE_SESSION_NAME", "T_LINE_CONNECTION", "T_LINE_ATTRIBUTE", "T_LINE_MEDIA", "T_LINE_UNKNOWN", "T_NULL", "':'", "'/'", "$accept", "sdp_body", "version", "@1", "@2", "origin", "@3", "@4", "network_type", "address_type", "session_name", "@5", "@6", "sess_connection", "connection", "sess_attributes", "attributes", "attribute", "attribute2", "@7", "@8", "media_list", "media", "@9", "@10", "transport", "formats", "unknown_lines", "unknown_line", "@11", "@12", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 58, 47 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 18, 19, 19, 21, 22, 20, 24, 25, 23, 26, 27, 29, 30, 28, 31, 32, 32, 33, 34, 34, 35, 36, 37, 38, 36, 39, 39, 41, 42, 40, 43, 43, 44, 44, 45, 45, 47, 48, 46 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 8, 2, 0, 0, 5, 0, 0, 10, 1, 1, 0, 0, 5, 1, 0, 5, 1, 0, 2, 3, 1, 0, 0, 5, 0, 2, 0, 0, 12, 1, 3, 0, 2, 0, 2, 0, 0, 5 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 0, 4, 0, 0, 3, 0, 1, 7, 0, 5, 0, 12, 35, 0, 8, 0, 16, 6, 0, 13, 0, 37, 35, 15, 36, 0, 0, 10, 0, 0, 19, 0, 14, 11, 0, 38, 26, 18, 0, 0, 0, 2, 0, 20, 0, 17, 39, 0, 27, 22, 0, 0, 28, 23, 21, 9, 0, 0, 29, 24, 0, 25, 31, 33, 0, 0, 32, 34, 35, 16, 35, 19, 30 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 3, 4, 6, 14, 9, 11, 19, 29, 35, 13, 16, 27, 23, 24, 37, 38, 44, 51, 58, 62, 42, 49, 57, 61, 64, 66, 17, 25, 30, 41 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -32 static const yytype_int8 yypact[] = { 0, -11, -32, 7, 1, -32, 6, -32, -32, 2, -32, 8, -32, -32, 4, -32, 9, -9, -32, 10, -32, 12, -32, -32, -32, -32, 13, 11, -32, 15, 14, 16, 12, -32, -32, 17, -32, -32, 19, 15, 18, 20, 21, 22, -32, 24, -32, -32, 25, -32, 23, 26, 28, -32, -32, -32, -32, 29, 30, -32, -32, 33, -32, 5, -32, 34, -1, -32, -32, -32, -9, -32, 16, 19 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -32, -32, -32, -32, -32, -32, -32, -32, -8, -16, -32, -32, -32, -32, -30, -32, -31, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -23, -32, -32, -32 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 31, 1, 21, 68, 5, 22, 69, 7, 2, 10, 8, 18, 12, 15, 26, 20, 28, 32, 33, 34, 36, 40, 65, 45, 39, 46, 50, 47, 52, 53, 22, 43, 59, 55, 48, 56, 60, 63, 67, 54, 71, 73, 0, 0, 0, 0, 70, 0, 72 }; static const yytype_int8 yycheck[] = { 23, 1, 11, 4, 15, 14, 7, 0, 8, 3, 9, 7, 10, 5, 4, 6, 4, 4, 7, 4, 6, 4, 17, 39, 32, 7, 4, 7, 4, 4, 14, 12, 3, 7, 13, 7, 6, 4, 4, 16, 70, 72, -1, -1, -1, -1, 69, -1, 71 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 1, 8, 19, 20, 15, 21, 0, 9, 23, 3, 24, 10, 28, 22, 5, 29, 45, 7, 25, 6, 11, 14, 31, 32, 46, 4, 30, 4, 26, 47, 45, 4, 7, 4, 27, 6, 33, 34, 26, 4, 48, 39, 12, 35, 27, 7, 7, 13, 40, 4, 36, 4, 4, 16, 7, 7, 41, 37, 3, 6, 42, 38, 4, 43, 17, 44, 4, 4, 7, 45, 32, 45, 34 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex () #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule) #else static void yy_reduce_print (yyvsp, yyrule) YYSTYPE *yyvsp; int yyrule; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void yydestruct (yymsg, yytype, yyvaluep) const char *yymsg; int yytype; YYSTYPE *yyvaluep; #endif { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { case 4: /* "T_TOKEN" */ #line 80 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_str)); delete (yyvaluep->yysdpt_str); }; #line 1116 "sdp_parser.cxx" break; case 5: /* "T_SAFE" */ #line 81 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_str)); delete (yyvaluep->yysdpt_str); }; #line 1121 "sdp_parser.cxx" break; case 6: /* "T_LINE" */ #line 82 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_str)); delete (yyvaluep->yysdpt_str); }; #line 1126 "sdp_parser.cxx" break; case 32: /* "connection" */ #line 94 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_connection)); delete (yyvaluep->yysdpt_connection); }; #line 1131 "sdp_parser.cxx" break; case 34: /* "attributes" */ #line 95 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_attributes)); delete (yyvaluep->yysdpt_attributes); }; #line 1136 "sdp_parser.cxx" break; case 35: /* "attribute" */ #line 96 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_attribute)); delete (yyvaluep->yysdpt_attribute); }; #line 1141 "sdp_parser.cxx" break; case 36: /* "attribute2" */ #line 97 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_attribute)); delete (yyvaluep->yysdpt_attribute); }; #line 1146 "sdp_parser.cxx" break; case 40: /* "media" */ #line 98 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_media)); delete (yyvaluep->yysdpt_media); }; #line 1151 "sdp_parser.cxx" break; case 43: /* "transport" */ #line 99 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_str)); delete (yyvaluep->yysdpt_str); }; #line 1156 "sdp_parser.cxx" break; case 44: /* "formats" */ #line 100 "sdp_parser.yxx" { MEMMAN_DELETE((yyvaluep->yysdpt_token_list)); delete (yyvaluep->yysdpt_token_list); }; #line 1161 "sdp_parser.cxx" break; default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (void); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void) #else int yyparse () #endif #endif { int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 112 "sdp_parser.yxx" { /* Parsing stops here. Remaining text is * not parsed. */ YYACCEPT; } break; case 3: #line 117 "sdp_parser.yxx" { /* KLUDGE to avoid memory leak in bison. * See the SIP parser for an explanation. */ YYABORT; } break; case 4: #line 125 "sdp_parser.yxx" { CTX_NUM; } break; case 5: #line 125 "sdp_parser.yxx" { CTX_INITIAL; } break; case 6: #line 126 "sdp_parser.yxx" { SDP->version = (yyvsp[(3) - (5)].yysdpt_int); } break; case 7: #line 130 "sdp_parser.yxx" { CTX_SAFE; } break; case 8: #line 130 "sdp_parser.yxx" { CTX_INITIAL; } break; case 9: #line 131 "sdp_parser.yxx" { SDP->origin.username = *(yyvsp[(3) - (10)].yysdpt_str); SDP->origin.session_id = *(yyvsp[(5) - (10)].yysdpt_str); SDP->origin.session_version = *(yyvsp[(6) - (10)].yysdpt_str); SDP->origin.network_type = (yyvsp[(7) - (10)].yysdpt_ntwk_type); SDP->origin.address_type = (yyvsp[(8) - (10)].yysdpt_addr_type); SDP->origin.address = *(yyvsp[(9) - (10)].yysdpt_str); MEMMAN_DELETE((yyvsp[(3) - (10)].yysdpt_str)); delete (yyvsp[(3) - (10)].yysdpt_str); MEMMAN_DELETE((yyvsp[(5) - (10)].yysdpt_str)); delete (yyvsp[(5) - (10)].yysdpt_str); MEMMAN_DELETE((yyvsp[(6) - (10)].yysdpt_str)); delete (yyvsp[(6) - (10)].yysdpt_str); MEMMAN_DELETE((yyvsp[(9) - (10)].yysdpt_str)); delete (yyvsp[(9) - (10)].yysdpt_str); } break; case 10: #line 144 "sdp_parser.yxx" { try { (yyval.yysdpt_ntwk_type) = str2sdp_ntwk_type(*(yyvsp[(1) - (1)].yysdpt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_str)); delete (yyvsp[(1) - (1)].yysdpt_str); } catch (t_sdp_syntax_error) { // Invalid network type. // Set network type to NULL. This way the message // will not be discarded and the error can be // handled on the SIP level (error response or // call tear down). MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_str)); delete (yyvsp[(1) - (1)].yysdpt_str); (yyval.yysdpt_ntwk_type) = SDP_NTWK_NULL; } } break; case 11: #line 159 "sdp_parser.yxx" { try { (yyval.yysdpt_addr_type) = str2sdp_addr_type(*(yyvsp[(1) - (1)].yysdpt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_str)); delete (yyvsp[(1) - (1)].yysdpt_str); } catch (t_sdp_syntax_error) { // Invalid address type MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_str)); delete (yyvsp[(1) - (1)].yysdpt_str); (yyval.yysdpt_addr_type) = SDP_ADDR_NULL; } } break; case 12: #line 170 "sdp_parser.yxx" { CTX_LINE; } break; case 13: #line 171 "sdp_parser.yxx" { CTX_INITIAL; } break; case 14: #line 171 "sdp_parser.yxx" { SDP->session_name = *(yyvsp[(3) - (5)].yysdpt_str); MEMMAN_DELETE((yyvsp[(3) - (5)].yysdpt_str)); delete (yyvsp[(3) - (5)].yysdpt_str); } break; case 15: #line 176 "sdp_parser.yxx" { SDP->connection = *(yyvsp[(1) - (1)].yysdpt_connection); MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_connection)); delete (yyvsp[(1) - (1)].yysdpt_connection); } break; case 16: #line 181 "sdp_parser.yxx" { (yyval.yysdpt_connection) = new t_sdp_connection(); MEMMAN_NEW((yyval.yysdpt_connection)); } break; case 17: #line 183 "sdp_parser.yxx" { (yyval.yysdpt_connection) = new t_sdp_connection(); MEMMAN_NEW((yyval.yysdpt_connection)); (yyval.yysdpt_connection)->network_type = (yyvsp[(2) - (5)].yysdpt_ntwk_type); (yyval.yysdpt_connection)->address_type = (yyvsp[(3) - (5)].yysdpt_addr_type); (yyval.yysdpt_connection)->address = *(yyvsp[(4) - (5)].yysdpt_str); MEMMAN_DELETE((yyvsp[(4) - (5)].yysdpt_str)); delete (yyvsp[(4) - (5)].yysdpt_str); } break; case 18: #line 192 "sdp_parser.yxx" { SDP->attributes = *(yyvsp[(1) - (1)].yysdpt_attributes); MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_attributes)); delete (yyvsp[(1) - (1)].yysdpt_attributes); } break; case 19: #line 197 "sdp_parser.yxx" { (yyval.yysdpt_attributes) = new list; MEMMAN_NEW((yyval.yysdpt_attributes)); } break; case 20: #line 198 "sdp_parser.yxx" { (yyval.yysdpt_attributes)->push_back(*(yyvsp[(2) - (2)].yysdpt_attribute)); MEMMAN_DELETE((yyvsp[(2) - (2)].yysdpt_attribute)); delete (yyvsp[(2) - (2)].yysdpt_attribute); } break; case 21: #line 203 "sdp_parser.yxx" { (yyval.yysdpt_attribute) = (yyvsp[(2) - (3)].yysdpt_attribute); } break; case 22: #line 207 "sdp_parser.yxx" { (yyval.yysdpt_attribute) = new t_sdp_attr(*(yyvsp[(1) - (1)].yysdpt_str)); MEMMAN_NEW((yyval.yysdpt_attribute)); MEMMAN_DELETE((yyvsp[(1) - (1)].yysdpt_str)); delete (yyvsp[(1) - (1)].yysdpt_str); } break; case 23: #line 211 "sdp_parser.yxx" { CTX_LINE; } break; case 24: #line 211 "sdp_parser.yxx" { CTX_INITIAL; } break; case 25: #line 211 "sdp_parser.yxx" { (yyval.yysdpt_attribute) = new t_sdp_attr(*(yyvsp[(1) - (5)].yysdpt_str), *(yyvsp[(4) - (5)].yysdpt_str)); MEMMAN_NEW((yyval.yysdpt_attribute)); MEMMAN_DELETE((yyvsp[(1) - (5)].yysdpt_str)); delete (yyvsp[(1) - (5)].yysdpt_str); MEMMAN_DELETE((yyvsp[(4) - (5)].yysdpt_str)); delete (yyvsp[(4) - (5)].yysdpt_str); } break; case 27: #line 219 "sdp_parser.yxx" { SDP->media.push_back(*(yyvsp[(2) - (2)].yysdpt_media)); MEMMAN_DELETE((yyvsp[(2) - (2)].yysdpt_media)); delete (yyvsp[(2) - (2)].yysdpt_media); } break; case 28: #line 225 "sdp_parser.yxx" { CTX_NUM; } break; case 29: #line 225 "sdp_parser.yxx" { CTX_INITIAL; } break; case 30: #line 227 "sdp_parser.yxx" { (yyval.yysdpt_media) = new t_sdp_media(); MEMMAN_NEW((yyval.yysdpt_media)); if ((yyvsp[(4) - (12)].yysdpt_int) > 65535) YYERROR; (yyval.yysdpt_media)->media_type = tolower(*(yyvsp[(2) - (12)].yysdpt_str)); (yyval.yysdpt_media)->port = (yyvsp[(4) - (12)].yysdpt_int); (yyval.yysdpt_media)->transport = *(yyvsp[(6) - (12)].yysdpt_str); /* The format depends on the media type */ switch((yyval.yysdpt_media)->get_media_type()) { case SDP_AUDIO: case SDP_VIDEO: /* Numeric format */ for (list::const_iterator it = (yyvsp[(7) - (12)].yysdpt_token_list)->begin(); it != (yyvsp[(7) - (12)].yysdpt_token_list)->end(); ++it) { if (is_number(*it)) (yyval.yysdpt_media)->formats.push_back(atoi(it->c_str())); } break; default: /* Alpha numeric format */ (yyval.yysdpt_media)->alpha_num_formats = *(yyvsp[(7) - (12)].yysdpt_token_list); } (yyval.yysdpt_media)->connection = *(yyvsp[(10) - (12)].yysdpt_connection); (yyval.yysdpt_media)->attributes = *(yyvsp[(12) - (12)].yysdpt_attributes); MEMMAN_DELETE((yyvsp[(2) - (12)].yysdpt_str)); delete (yyvsp[(2) - (12)].yysdpt_str); MEMMAN_DELETE((yyvsp[(6) - (12)].yysdpt_str)); delete (yyvsp[(6) - (12)].yysdpt_str); MEMMAN_DELETE((yyvsp[(7) - (12)].yysdpt_token_list)); delete (yyvsp[(7) - (12)].yysdpt_token_list); MEMMAN_DELETE((yyvsp[(10) - (12)].yysdpt_connection)); delete (yyvsp[(10) - (12)].yysdpt_connection); MEMMAN_DELETE((yyvsp[(12) - (12)].yysdpt_attributes)); delete (yyvsp[(12) - (12)].yysdpt_attributes); } break; case 31: #line 261 "sdp_parser.yxx" { (yyval.yysdpt_str) = (yyvsp[(1) - (1)].yysdpt_str); } break; case 32: #line 263 "sdp_parser.yxx" { (yyval.yysdpt_str) = new string(*(yyvsp[(1) - (3)].yysdpt_str) + '/' + *(yyvsp[(3) - (3)].yysdpt_str)); MEMMAN_NEW((yyval.yysdpt_str)); MEMMAN_DELETE((yyvsp[(1) - (3)].yysdpt_str)); delete (yyvsp[(1) - (3)].yysdpt_str); MEMMAN_DELETE((yyvsp[(3) - (3)].yysdpt_str)); delete (yyvsp[(3) - (3)].yysdpt_str); } break; case 33: #line 271 "sdp_parser.yxx" { (yyval.yysdpt_token_list) = new list; MEMMAN_NEW((yyval.yysdpt_token_list)); } break; case 34: #line 272 "sdp_parser.yxx" { (yyval.yysdpt_token_list)->push_back(*(yyvsp[(2) - (2)].yysdpt_str)); MEMMAN_DELETE((yyvsp[(2) - (2)].yysdpt_str)); delete (yyvsp[(2) - (2)].yysdpt_str); } break; case 37: #line 283 "sdp_parser.yxx" { CTX_LINE; } break; case 38: #line 283 "sdp_parser.yxx" { CTX_INITIAL; } break; case 39: #line 284 "sdp_parser.yxx" { MEMMAN_DELETE((yyvsp[(3) - (5)].yysdpt_str)); delete (yyvsp[(3) - (5)].yysdpt_str); } break; /* Line 1267 of yacc.c. */ #line 1750 "sdp_parser.cxx" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (yymsg); } else { yyerror (YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 288 "sdp_parser.yxx" void yysdperror (const char *s) /* Called by yysdpparse on error */ { // printf ("%s\n", s); } twinkle-1.4.2/src/sdp/sdp_parser.yxx0000644000175000001440000001721211127714060014403 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %{ #include #include #include #include "sdp_parse_ctrl.h" #include "sdp.h" #include "util.h" #include "audits/memman.h" using namespace std; extern int yysdplex(void); void yysdperror(const char *s); %} // The %debug option causes a problem with the %destructor options later on. // The bison compilor generates undefined symbols: // // parser.y: In function `void yysymprint(FILE*, int, yystype)': // parser.y:0: error: `null' undeclared (first use this function) // // So if you need to debug, then outcomment the %destructor first. This will // do no harm to your debugging, it only will cause memory leaks during // error handling. // // %debug %expect 2 /* See below for the expected shift/reduce conflicts. */ %union { int yysdpt_int; string *yysdpt_str; t_sdp_ntwk_type yysdpt_ntwk_type; t_sdp_addr_type yysdpt_addr_type; t_sdp_connection *yysdpt_connection; list *yysdpt_attributes; t_sdp_attr *yysdpt_attribute; t_sdp_media *yysdpt_media; list *yysdpt_token_list; } %token T_NUM %token T_TOKEN %token T_SAFE %token T_LINE %token T_CRLF %token T_LINE_VERSION %token T_LINE_ORIGIN %token T_LINE_SESSION_NAME %token T_LINE_CONNECTION %token T_LINE_ATTRIBUTE %token T_LINE_MEDIA %token T_LINE_UNKNOWN // The token T_NULL is never returned by the scanner. %token T_NULL %destructor { MEMMAN_DELETE($$); delete $$; } T_TOKEN %destructor { MEMMAN_DELETE($$); delete $$; } T_SAFE %destructor { MEMMAN_DELETE($$); delete $$; } T_LINE %type address_type %type connection %type network_type %type attributes %type attribute %type attribute2 %type media %type transport %type formats %destructor { MEMMAN_DELETE($$); delete $$; } connection %destructor { MEMMAN_DELETE($$); delete $$; } attributes %destructor { MEMMAN_DELETE($$); delete $$; } attribute %destructor { MEMMAN_DELETE($$); delete $$; } attribute2 %destructor { MEMMAN_DELETE($$); delete $$; } media %destructor { MEMMAN_DELETE($$); delete $$; } transport %destructor { MEMMAN_DELETE($$); delete $$; } formats %% /* The unknown_lines cause an expected shift/reduce conflict */ sdp_body: version origin session_name unknown_lines sess_connection unknown_lines sess_attributes media_list { /* Parsing stops here. Remaining text is * not parsed. */ YYACCEPT; } | error T_NULL { /* KLUDGE to avoid memory leak in bison. * See the SIP parser for an explanation. */ YYABORT; } ; version: T_LINE_VERSION { CTX_NUM; } T_NUM { CTX_INITIAL; } T_CRLF { SDP->version = $3; } ; origin: T_LINE_ORIGIN { CTX_SAFE; } T_SAFE { CTX_INITIAL; } T_TOKEN T_TOKEN network_type address_type T_TOKEN T_CRLF { SDP->origin.username = *$3; SDP->origin.session_id = *$5; SDP->origin.session_version = *$6; SDP->origin.network_type = $7; SDP->origin.address_type = $8; SDP->origin.address = *$9; MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($5); delete $5; MEMMAN_DELETE($6); delete $6; MEMMAN_DELETE($9); delete $9; } ; network_type: T_TOKEN { try { $$ = str2sdp_ntwk_type(*$1); MEMMAN_DELETE($1); delete $1; } catch (t_sdp_syntax_error) { // Invalid network type. // Set network type to NULL. This way the message // will not be discarded and the error can be // handled on the SIP level (error response or // call tear down). MEMMAN_DELETE($1); delete $1; $$ = SDP_NTWK_NULL; } } ; address_type: T_TOKEN { try { $$ = str2sdp_addr_type(*$1); MEMMAN_DELETE($1); delete $1; } catch (t_sdp_syntax_error) { // Invalid address type MEMMAN_DELETE($1); delete $1; $$ = SDP_ADDR_NULL; } } ; session_name: T_LINE_SESSION_NAME { CTX_LINE; } T_LINE { CTX_INITIAL; } T_CRLF { SDP->session_name = *$3; MEMMAN_DELETE($3); delete $3; } ; sess_connection: connection { SDP->connection = *$1; MEMMAN_DELETE($1); delete $1; } ; connection: /* empty */ { $$ = new t_sdp_connection(); MEMMAN_NEW($$); } | T_LINE_CONNECTION network_type address_type T_TOKEN T_CRLF { $$ = new t_sdp_connection(); MEMMAN_NEW($$); $$->network_type = $2; $$->address_type = $3; $$->address = *$4; MEMMAN_DELETE($4); delete $4; } ; sess_attributes: attributes { SDP->attributes = *$1; MEMMAN_DELETE($1); delete $1; } ; attributes: /* emtpy */ { $$ = new list; MEMMAN_NEW($$); } | attributes attribute { $$->push_back(*$2); MEMMAN_DELETE($2); delete $2; } ; attribute: T_LINE_ATTRIBUTE attribute2 T_CRLF { $$ = $2; } ; attribute2: T_TOKEN { $$ = new t_sdp_attr(*$1); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; } | T_TOKEN ':' { CTX_LINE; } T_LINE { CTX_INITIAL; } { $$ = new t_sdp_attr(*$1, *$4); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($4); delete $4; } ; media_list: /* empty */ | media_list media { SDP->media.push_back(*$2); MEMMAN_DELETE($2); delete $2; } ; /* The unknown_lines cause an expected shift/reduce conflict */ media: T_LINE_MEDIA T_TOKEN { CTX_NUM; } T_NUM { CTX_INITIAL; } transport formats T_CRLF unknown_lines connection unknown_lines attributes { $$ = new t_sdp_media(); MEMMAN_NEW($$); if ($4 > 65535) YYERROR; $$->media_type = tolower(*$2); $$->port = $4; $$->transport = *$6; /* The format depends on the media type */ switch($$->get_media_type()) { case SDP_AUDIO: case SDP_VIDEO: /* Numeric format */ for (list::const_iterator it = $7->begin(); it != $7->end(); ++it) { if (is_number(*it)) $$->formats.push_back(atoi(it->c_str())); } break; default: /* Alpha numeric format */ $$->alpha_num_formats = *$7; } $$->connection = *$10; $$->attributes = *$12; MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($6); delete $6; MEMMAN_DELETE($7); delete $7; MEMMAN_DELETE($10); delete $10; MEMMAN_DELETE($12); delete $12; } ; transport: T_TOKEN { $$ = $1; } | T_TOKEN '/' T_TOKEN { $$ = new string(*$1 + '/' + *$3); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; } // For RTP/AVP a format is a number. For other transport protocols, // non-numerical formats are possible. formats: /* empty */ { $$ = new list; MEMMAN_NEW($$); } | formats T_TOKEN { $$->push_back(*$2); MEMMAN_DELETE($2); delete $2; } ; /* Skip unknown lines */ unknown_lines: /* empty */ | unknown_lines unknown_line ; unknown_line: T_LINE_UNKNOWN { CTX_LINE; } T_LINE { CTX_INITIAL; } T_CRLF { MEMMAN_DELETE($3); delete $3; } ; %% void yysdperror (const char *s) /* Called by yysdpparse on error */ { // printf ("%s\n", s); } twinkle-1.4.2/src/sdp/Makefile.am0000644000175000001440000000105411134635366013531 00000000000000AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src\ $(XML2_CFLAGS) AM_YFLAGS = -p yysdp -d AM_LFLAGS = -Pyysdp -olex.yy.c -i # This target is only for testing the parser in isolation # noinst_PROGRAMS = sdpparse # sdpparse_SOURCES = main.cpp # sdpparse_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/sdp/libsdpparser.a\ # $(top_builddir)/src/parser/sip_body.o noinst_LIBRARIES = libsdpparser.a libsdpparser_a_SOURCES =\ sdp.cpp\ sdp_parse_ctrl.cpp\ sdp_parser.yxx\ sdp_scanner.lxx\ sdp.h\ sdp_parse_ctrl.h twinkle-1.4.2/src/sdp/Makefile.in0000644000175000001440000004435111151323410013530 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/sdp DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ sdp_parser.cxx sdp_parser.h sdp_scanner.cxx ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libsdpparser_a_AR = $(AR) $(ARFLAGS) libsdpparser_a_LIBADD = am_libsdpparser_a_OBJECTS = sdp.$(OBJEXT) sdp_parse_ctrl.$(OBJEXT) \ sdp_parser.$(OBJEXT) sdp_scanner.$(OBJEXT) libsdpparser_a_OBJECTS = $(am_libsdpparser_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libsdpparser_a_SOURCES) DIST_SOURCES = $(libsdpparser_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src\ $(XML2_CFLAGS) AM_YFLAGS = -p yysdp -d AM_LFLAGS = -Pyysdp -olex.yy.c -i # This target is only for testing the parser in isolation # noinst_PROGRAMS = sdpparse # sdpparse_SOURCES = main.cpp # sdpparse_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/sdp/libsdpparser.a\ # $(top_builddir)/src/parser/sip_body.o noinst_LIBRARIES = libsdpparser.a libsdpparser_a_SOURCES = \ sdp.cpp\ sdp_parse_ctrl.cpp\ sdp_parser.yxx\ sdp_scanner.lxx\ sdp.h\ sdp_parse_ctrl.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .cxx .lxx .o .obj .yxx $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sdp/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/sdp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) sdp_parser.h: sdp_parser.cxx @if test ! -f $@; then \ rm -f sdp_parser.cxx; \ $(MAKE) sdp_parser.cxx; \ else :; fi libsdpparser.a: $(libsdpparser_a_OBJECTS) $(libsdpparser_a_DEPENDENCIES) -rm -f libsdpparser.a $(libsdpparser_a_AR) libsdpparser.a $(libsdpparser_a_OBJECTS) $(libsdpparser_a_LIBADD) $(RANLIB) libsdpparser.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdp_parse_ctrl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdp_parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdp_scanner.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .lxx.cxx: $(LEXCOMPILE) $< sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@ rm -f $(LEX_OUTPUT_ROOT).c .yxx.cxx: $(YACCCOMPILE) $< if test -f y.tab.h; then \ to=`echo "$*_H" | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \ sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \ y.tab.h >$*.ht; \ rm -f y.tab.h; \ if cmp -s $*.ht $*.h; then \ rm -f $*.ht ;\ else \ mv $*.ht $*.h; \ fi; \ fi if test -f y.output; then \ mv y.output $*.output; \ fi sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@ rm -f y.tab.c uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f sdp_parser.cxx -rm -f sdp_parser.h -rm -f sdp_scanner.cxx clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/sdp/sdp_parse_ctrl.cpp0000644000175000001440000000374111127714053015203 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sdp_parse_ctrl.h" #include "audits/memman.h" // Interface to Bison extern int yysdpparse(void); // Interface to Flex struct yy_buffer_state; extern struct yy_buffer_state *yysdp_scan_string(const char *); extern void yysdp_delete_buffer(struct yy_buffer_state *); t_mutex t_sdp_parser::mtx_parser; t_sdp_parser::t_context t_sdp_parser::context = t_sdp_parser::X_INITIAL; t_sdp *t_sdp_parser::sdp = NULL; t_sdp *t_sdp_parser::parse(const string &s) { int ret; struct yy_buffer_state *b; t_mutex_guard guard(mtx_parser); sdp = new t_sdp(); MEMMAN_NEW(sdp); // The SDP body should end with a CRLF. Some implementations // do not send this last CRLF. Allow this deviation by adding // the last CRLF if it is missing. char last_char = s.at(s.size()-1); if (last_char == '\n' || last_char == '\r') { // The SDP parser allows \r, \r\n and \n as CRLF b = yysdp_scan_string(s.c_str()); } else { // Last CRLF is missing. b = yysdp_scan_string((s + "\r\n").c_str()); } ret = yysdpparse(); yysdp_delete_buffer(b); if (ret != 0) { MEMMAN_DELETE(sdp); delete sdp; sdp = NULL; throw ret; } return sdp; } t_sdp_syntax_error::t_sdp_syntax_error(const string &e) { error = e; } twinkle-1.4.2/src/stun/0000777000175000001440000000000011151327751011757 500000000000000twinkle-1.4.2/src/stun/udp.h0000644000175000001440000001234111127714045012634 00000000000000#ifndef udp_h #define udp_h #ifdef __MACH__ typedef int socklen_t; #endif #include #ifdef WIN32 #include #include typedef int socklen_t; typedef SOCKET StunSocket; #define EWOULDBLOCK WSAEWOULDBLOCK #define EINPROGRESS WSAEINPROGRESS #define EALREADY WSAEALREADY #define ENOTSOCK WSAENOTSOCK #define EDESTADDRREQ WSAEDESTADDRREQ #define EMSGSIZE WSAEMSGSIZE #define EPROTOTYPE WSAEPROTOTYPE #define ENOPROTOOPT WSAENOPROTOOPT #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT #define EOPNOTSUPP WSAEOPNOTSUPP #define EPFNOSUPPORT WSAEPFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT #define EADDRINUSE WSAEADDRINUSE #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #define ENETDOWN WSAENETDOWN #define ENETUNREACH WSAENETUNREACH #define ENETRESET WSAENETRESET #define ECONNABORTED WSAECONNABORTED #define ECONNRESET WSAECONNRESET #define ENOBUFS WSAENOBUFS #define EISCONN WSAEISCONN #define ENOTCONN WSAENOTCONN #define ESHUTDOWN WSAESHUTDOWN #define ETOOMANYREFS WSAETOOMANYREFS #define ETIMEDOUT WSAETIMEDOUT #define ECONNREFUSED WSAECONNREFUSED #define ELOOP WSAELOOP #define EHOSTDOWN WSAEHOSTDOWN #define EHOSTUNREACH WSAEHOSTUNREACH #define EPROCLIM WSAEPROCLIM #define EUSERS WSAEUSERS #define EDQUOT WSAEDQUOT #define ESTALE WSAESTALE #define EREMOTE WSAEREMOTE typedef LONGLONG Int64; inline int getErrno() { return WSAGetLastError(); } #else typedef int StunSocket; static const StunSocket INVALID_SOCKET = -1; static const int SOCKET_ERROR = -1; inline int closesocket( StunSocket fd ) { return close(fd); }; inline int getErrno() { return errno; } #define WSANOTINITIALISED EPROTONOSUPPORT #endif /// Open a UDP socket to receive on the given port - if port is 0, pick a a /// port, if interfaceIp!=0 then use ONLY the interface specified instead of /// all of them StunSocket openPort( unsigned short port, unsigned int interfaceIp, bool verbose); /// recive a UDP message bool getMessage( StunSocket fd, char* buf, int* len, unsigned int* srcIp, unsigned short* srcPort, bool verbose); /// send a UDP message bool sendMessage( StunSocket fd, char* msg, int len, unsigned int dstIp, unsigned short dstPort, bool verbose); /// set up network - does nothing in unix but needed for windows void initNetwork(); /* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * . * */ // Local Variables: // mode:c++ // c-file-style:"ellemtel" // c-file-offsets:((case-label . +)) // indent-tabs-mode:nil // End: #endif twinkle-1.4.2/src/stun/stun_transaction.cpp0000644000175000001440000004706611127714054016011 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "stun_transaction.h" #include "events.h" #include "log.h" #include "phone.h" #include "sys_settings.h" #include "transaction_mgr.h" #include "translator.h" #include "util.h" #include "audits/memman.h" extern t_transaction_mgr *transaction_mgr; extern t_event_queue *evq_trans_layer; extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_sender; extern t_phone *phone; bool get_stun_binding(t_user *user_config, unsigned short src_port, unsigned long &mapped_ip, unsigned short &mapped_port, int &err_code, string &err_reason) { list destinations = user_config->get_stun_server().get_h_ip_srv("udp"); if (destinations.empty()) { // Cannot resolve STUN server address. log_file->write_header("::get_stun_binding", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw("Failed to resolve: "); log_file->write_raw(user_config->get_stun_server().encode()); log_file->write_endl(); log_file->write_raw("Return internal STUN bind error: 404 Not Found"); log_file->write_endl(); log_file->write_footer(); err_code = 404; err_reason = "Not Found"; return false; } int num_transmissions = 0; int wait_intval = DUR_STUN_START_INTVAL; t_socket_udp sock(src_port); sock.connect(destinations.front().ipaddr, destinations.front().port); // Build STUN request char buf[STUN_MAX_MESSAGE_SIZE + 1]; StunMessage req_bind; StunAtrString stun_null_str; stun_null_str.sizeValue = 0; stunBuildReqSimple(&req_bind, stun_null_str, false, false); char req_msg[STUN_MAX_MESSAGE_SIZE]; int req_msg_size = stunEncodeMessage(req_bind, req_msg, STUN_MAX_MESSAGE_SIZE, stun_null_str, false); // Send STUN request and retransmit till a response is received. while (num_transmissions < STUN_MAX_TRANSMISSIONS) { bool ret; try { sock.send(req_msg, req_msg_size); } catch (int err) { // Socket error (probably ICMP error) // Failover to next destination log_file->write_report("Send failed. Failover to next destination.", "::get_stun_binding"); destinations.pop_front(); if (destinations.empty()) { log_file->write_report("No next destination for failover.", "::get_stun_binding"); break; } num_transmissions = 0; wait_intval = DUR_STUN_START_INTVAL; sock.connect(destinations.front().ipaddr, destinations.front().port); continue; } log_file->write_header("::get_stun_binding", LOG_STUN); log_file->write_raw("Send to: "); log_file->write_raw(h_ip2str(destinations.front().ipaddr)); log_file->write_raw(":"); log_file->write_raw(destinations.front().port); log_file->write_endl(); log_file->write_raw(stunMsg2Str(req_bind)); log_file->write_footer(); try { ret = sock.select_read(wait_intval); } catch (int err) { // Socket error (probably ICMP error) // Failover to next destination log_file->write_report("Select failed. Failover to next destination.", "::get_stun_binding"); destinations.pop_front(); if (destinations.empty()) { log_file->write_report("No next destination for failover.", "::get_stun_binding"); break; } num_transmissions = 0; wait_intval = DUR_STUN_START_INTVAL; sock.connect(destinations.front().ipaddr, destinations.front().port); continue; } if (!ret) { // Time out num_transmissions++; if (wait_intval < DUR_STUN_MAX_INTVAL) { wait_intval *= 2; } continue; } // A message has been received int resp_msg_size; try { resp_msg_size = sock.recv(buf, STUN_MAX_MESSAGE_SIZE + 1); } catch (int err) { // Socket error (probably ICMP error) // Failover to next destination log_file->write_report("Recv failed. Failover to next destination.", "::get_stun_binding"); destinations.pop_front(); if (destinations.empty()) { log_file->write_report("No next destination for failover.", "::get_stun_binding"); break; } num_transmissions = 0; wait_intval = DUR_STUN_START_INTVAL; sock.connect(destinations.front().ipaddr, destinations.front().port); continue; } StunMessage resp_bind; if (!stunParseMessage(buf, resp_msg_size, resp_bind, false)) { log_file->write_report( "Received faulty STUN message", "::get_stun_binding", LOG_STUN); num_transmissions++; if (wait_intval < DUR_STUN_MAX_INTVAL) { wait_intval *= 2; } continue; } log_file->write_header("::get_stun_binding", LOG_STUN); log_file->write_raw("Received from: "); log_file->write_raw(h_ip2str(destinations.front().ipaddr)); log_file->write_raw(":"); log_file->write_raw(destinations.front().port); log_file->write_endl(); log_file->write_raw(stunMsg2Str(resp_bind)); log_file->write_footer(); // Check if id in msgHdr matches if (!stunEqualId(resp_bind, req_bind)) { num_transmissions++; if (wait_intval < DUR_STUN_MAX_INTVAL) { wait_intval *= 2; } continue; } if (resp_bind.msgHdr.msgType == BindResponseMsg && resp_bind.hasMappedAddress) { // Bind response received mapped_ip = resp_bind.mappedAddress.ipv4.addr; mapped_port = resp_bind.mappedAddress.ipv4.port; return true; } if (resp_bind.msgHdr.msgType == BindErrorResponseMsg && resp_bind.hasErrorCode) { // Bind error received err_code = resp_bind.errorCode.errorClass * 100 + resp_bind.errorCode.number; char s[STUN_MAX_STRING + 1]; strncpy(s, resp_bind.errorCode.reason, STUN_MAX_STRING); s[STUN_MAX_STRING] = 0; err_reason = s; return false; } // A wrong response has been received. log_file->write_report( "Invalid STUN response received", "::get_stun_binding", LOG_NORMAL); err_code = 500; err_reason = "Server Error"; return false; } // Request timed out log_file->write_report("STUN request timeout", "::get_stun_binding", LOG_NORMAL); err_code = 408; err_reason = "Request Timeout"; return false; } bool stun_discover_nat(t_phone_user *pu, string &err_msg) { t_user *user_config = pu->get_user_profile(); // By default enable STUN. If for some reason we cannot perform // NAT discovery, then enable STUN. It will not harm, but only // create non-needed STUN transactions if we are not behind a NAT. pu->use_stun = true; pu->use_nat_keepalive = true; list destinations = user_config->get_stun_server().get_h_ip_srv("udp"); if (destinations.empty()) { // Cannot resolve STUN server address. log_file->write_header("::main", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw("Failed to resolve: "); log_file->write_raw(user_config->get_stun_server().encode()); log_file->write_endl(); log_file->write_footer(); err_msg = TRANSLATE("Cannot resolve STUN server: %1"); err_msg = replace_first(err_msg, "%1", user_config->get_stun_server().encode()); return false; } while (!destinations.empty()) { StunAddress4 stun_ip4; stun_ip4.addr = destinations.front().ipaddr; stun_ip4.port = destinations.front().port; NatType nat_type = stunNatType(stun_ip4, false); log_file->write_header("::main"); log_file->write_raw("STUN NAT type discovery for "); log_file->write_raw(user_config->get_profile_name()); log_file->write_endl(); log_file->write_raw("NAT type: "); log_file->write_raw(stunNatType2Str(nat_type)); log_file->write_endl(); log_file->write_footer(); switch (nat_type) { case StunTypeOpen: // STUN is not needed. pu->use_stun = false; pu->use_nat_keepalive = false; return true; case StunTypeSymNat: err_msg = TRANSLATE("You are behind a symmetric NAT.\nSTUN will not work.\nConfigure a public IP address in the user profile\nand create the following static bindings (UDP) in your NAT."); err_msg += "\n\n"; err_msg += TRANSLATE("public IP: %1 --> private IP: %2 (SIP signaling)"); err_msg = replace_first(err_msg, "%1", int2str(sys_config->get_sip_port())); err_msg = replace_first(err_msg, "%2", int2str(sys_config->get_sip_port())); err_msg += "\n"; err_msg += TRANSLATE("public IP: %1-%2 --> private IP: %3-%4 (RTP/RTCP)"); err_msg = replace_first(err_msg, "%1", int2str(sys_config->get_rtp_port())); err_msg = replace_first(err_msg, "%2", int2str(sys_config->get_rtp_port() + 5)); err_msg = replace_first(err_msg, "%3", int2str(sys_config->get_rtp_port())); err_msg = replace_first(err_msg, "%4", int2str(sys_config->get_rtp_port() + 5)); pu->use_stun = false; pu->use_nat_keepalive = false; return false; case StunTypeSymFirewall: // STUN is not needed as we are on a pubic IP. // NAT keep alive is needed however to keep the firewall open. pu->use_stun = false; return true; case StunTypeBlocked: destinations.pop_front(); // The code for NAT type discovery does not handle // ICMP errors. So if the conclusion is that the network // connection is blocked, it might be due to a down STUN // server. Try alternative destination if avaliable. if (destinations.empty()) { err_msg = TRANSLATE("Cannot reach the STUN server: %1"); err_msg = replace_first(err_msg, "%1", user_config->get_stun_server().encode()); err_msg += "\n\n"; err_msg += TRANSLATE("If you are behind a firewall then you need to open the following UDP ports."); err_msg += "\n"; err_msg += TRANSLATE("Port %1 (SIP signaling)"); err_msg = replace_first(err_msg, "%1", int2str(sys_config->get_sip_port())); err_msg += "\n"; err_msg += TRANSLATE("Ports %1-%2 (RTP/RTCP)"); err_msg = replace_first(err_msg, "%1", int2str(sys_config->get_rtp_port())); err_msg = replace_first(err_msg, "%2", int2str(sys_config->get_rtp_port() + 5)); return false; } log_file->write_report("Failover to next destination.", "::stun_discover_nat"); break; case StunTypeFailure: destinations.pop_front(); log_file->write_report("Failover to next destination.", "::stun_discover_nat"); break; default: // Use STUN. return true; } } err_msg = TRANSLATE("NAT type discovery via STUN failed."); return false; } // Main function for STUN listener thread for media STUN requests. void *stun_listen_main(void *arg) { char buf[STUN_MAX_MESSAGE_SIZE + 1]; int data_size; t_socket_udp *sock = (t_socket_udp *)arg; while(true) { try { data_size = sock->recv(buf, STUN_MAX_MESSAGE_SIZE + 1); } catch (int err) { string msg("Failed to receive STUN response for media.\n"); msg += get_error_str(err); log_file->write_report(msg, "::stun_listen_main", LOG_NORMAL, LOG_CRITICAL); // The request will timeout, no need to send a response now. return NULL; } StunMessage m; if (!stunParseMessage(buf, data_size, m, false)) { log_file->write_report("Faulty STUN message", "::stun_listen_main"); continue; } log_file->write_header("::stun_listen_main", LOG_STUN); log_file->write_raw("Received: "); log_file->write_raw(stunMsg2Str(m)); log_file->write_footer(); evq_trans_mgr->push_stun_response(&m, 0, 0); } } ////////////////////////////////////////////// // Base STUN transaction ////////////////////////////////////////////// t_mutex t_stun_transaction::mtx_class; t_tid t_stun_transaction::next_id = 1; t_stun_transaction::t_stun_transaction(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst) { mtx_class.lock(); id = next_id++; if (next_id == 65535) next_id = 1; mtx_class.unlock(); state = TS_NULL; request = new StunMessage(*r); MEMMAN_NEW(request); tuid = _tuid; dur_req_timeout = DUR_STUN_START_INTVAL; num_transmissions = 0; destinations = dst; user_config = user->copy(); } t_stun_transaction::~t_stun_transaction() { MEMMAN_DELETE(request); delete request; MEMMAN_DELETE(user_config); delete user_config; } t_tid t_stun_transaction::get_id(void) const { return id; } t_trans_state t_stun_transaction::get_state(void) const { return state; } void t_stun_transaction::start_timer_req_timeout(void) { timer_req_timeout = transaction_mgr->start_stun_timer(dur_req_timeout, STUN_TMR_REQ_TIMEOUT, id); // RFC 3489 9.3 // Double the retransmision interval till a maximum if (dur_req_timeout < DUR_STUN_MAX_INTVAL) { dur_req_timeout = 2 * dur_req_timeout; } } void t_stun_transaction::stop_timer_req_timeout(void) { if (timer_req_timeout) { transaction_mgr->stop_timer(timer_req_timeout); timer_req_timeout = 0; } } void t_stun_transaction::process_response(StunMessage *r) { stop_timer_req_timeout(); evq_trans_layer->push_stun_response(r, tuid, id); state = TS_TERMINATED; } void t_stun_transaction::process_icmp(const t_icmp_msg &icmp) { stop_timer_req_timeout(); log_file->write_report("Failover to next destination.", "t_stun_transaction::process_icmp"); destinations.pop_front(); if (destinations.empty()) { log_file->write_report("No next destination for failover.", "t_stun_transaction::process_icmp"); log_file->write_header("t_stun_transaction::process_icmp", LOG_NORMAL, LOG_INFO); log_file->write_raw("ICMP error received.\n\n"); log_file->write_raw("Send internal: 500 Server Error\n"); log_file->write_footer(); // No server could be reached, Notify the TU with 500 Server // Error. StunMessage *resp = stunBuildError(*request, 500, "Server Error"); evq_trans_layer->push_stun_response(resp, tuid, id); MEMMAN_DELETE(resp); delete resp; state = TS_TERMINATED; return; } // Failover to next destination evq_sender->push_stun_request(user_config, request, TYPE_STUN_SIP, tuid, id, destinations.front().ipaddr, destinations.front().port); num_transmissions = 1; dur_req_timeout = DUR_STUN_START_INTVAL; start_timer_req_timeout(); } void t_stun_transaction::timeout(t_stun_timer t) { // RFC 3489 9.3 if (num_transmissions < STUN_MAX_TRANSMISSIONS) { retransmit(); start_timer_req_timeout(); return; } // Report timeout to TU StunMessage *timeout_resp; timeout_resp = stunBuildError(*request, 408, "Request Timeout"); log_file->write_report("STUN request timeout", "t_stun_transaction::timeout", LOG_NORMAL); evq_trans_layer->push_stun_response(timeout_resp, tuid, id); MEMMAN_DELETE(timeout_resp); delete timeout_resp; state = TS_TERMINATED; } bool t_stun_transaction::match(StunMessage *resp) const { return stunEqualId(*resp, *request); } // An ICMP error matches a transaction when the destination IP address/port // of the packet that caused the ICMP error equals the destination // IP address/port of the transaction. Other information of the packet causing // the ICMP error is not available. // In theory when multiple transactions are open for the same destination, the // wrong transaction may process the ICMP error. In practice this should rarely // happen as the destination will be unreachable for all those transactions. // If it happens a transaction gets aborted. bool t_stun_transaction::match(const t_icmp_msg &icmp) const { return (destinations.front().ipaddr == icmp.ipaddr && destinations.front().port == icmp.port); } ////////////////////////////////////////////// // SIP STUN transaction ////////////////////////////////////////////// void t_sip_stun_trans::retransmit(void) { // The SIP UDP sender will send out the STUN request. evq_sender->push_stun_request(user_config, request, TYPE_STUN_SIP, tuid, id, destinations.front().ipaddr, destinations.front().port); num_transmissions++; } t_sip_stun_trans::t_sip_stun_trans(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst) : t_stun_transaction(user, r, _tuid, dst) { // The SIP UDP sender will send out the STUN request. evq_sender->push_stun_request(user_config, request, TYPE_STUN_SIP, tuid, id, destinations.front().ipaddr, destinations.front().port); num_transmissions++; start_timer_req_timeout(); state = TS_PROCEEDING; } ////////////////////////////////////////////// // Media STUN transaction ////////////////////////////////////////////// // TODO: this code is not used anymore. Remove? void t_media_stun_trans::retransmit(void) { // Retransmit the STUN request StunAtrString stun_pass; stun_pass.sizeValue = 0; char m[STUN_MAX_MESSAGE_SIZE]; int msg_size = stunEncodeMessage(*request, m, STUN_MAX_MESSAGE_SIZE, stun_pass, false); try { sock->sendto(destinations.front().ipaddr, destinations.front().port, m, msg_size); } catch (int err) { string msg("Failed to send STUN request for media.\n"); msg += get_error_str(err); log_file->write_report(msg, "::t_media_stun_trans::retransmit", LOG_NORMAL, LOG_CRITICAL); StunMessage *resp; resp = stunBuildError(*request, 500, "Could not send request"); evq_trans_layer->push_stun_response(resp, tuid, id); MEMMAN_DELETE(resp); delete resp; return; } num_transmissions++; } t_media_stun_trans::t_media_stun_trans(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst, unsigned short src_port) : t_stun_transaction(user, r, _tuid, dst) { thr_listen = NULL; try { sock = new t_socket_udp(src_port); MEMMAN_NEW(sock); sock->connect(destinations.front().ipaddr, destinations.front().port); } catch (int err) { string msg("Failed to create a UDP socket (STUN) on port "); msg += int2str(src_port); msg += "\n"; msg += get_error_str(err); log_file->write_report(msg, "t_media_stun_trans::t_media_stun_trans", LOG_NORMAL, LOG_CRITICAL); delete sock; sock = NULL; StunMessage *resp; resp = stunBuildError(*request, 500, "Could not create socket"); evq_trans_layer->push_stun_response(resp, tuid, id); MEMMAN_DELETE(resp); delete resp; return; } // Send STUN request StunAtrString stun_pass; stun_pass.sizeValue = 0; char m[STUN_MAX_MESSAGE_SIZE]; int msg_size = stunEncodeMessage(*r, m, STUN_MAX_MESSAGE_SIZE, stun_pass, false); try { sock->send(m, msg_size); } catch (int err) { string msg("Failed to send STUN request for media.\n"); msg += get_error_str(err); log_file->write_report(msg, "::t_media_stun_trans::t_media_stun_trans", LOG_NORMAL, LOG_CRITICAL); StunMessage *resp; resp = stunBuildError(*request, 500, "Failed to send request"); evq_trans_layer->push_stun_response(resp, tuid, id); MEMMAN_DELETE(resp); delete resp; return; } num_transmissions++; try { thr_listen = new t_thread(stun_listen_main, sock); MEMMAN_NEW(thr_listen); } catch (int) { log_file->write_report("Failed to create STUN listener thread.", "::t_media_stun_trans::t_media_stun_trans", LOG_NORMAL, LOG_CRITICAL); delete thr_listen; thr_listen = NULL; StunMessage *resp; resp = stunBuildError(*request, 500, "Failed to create STUN listen thread"); evq_trans_layer->push_stun_response(resp, tuid, id); MEMMAN_DELETE(resp); delete resp; return; } start_timer_req_timeout(); state = TS_PROCEEDING; } t_media_stun_trans::~t_media_stun_trans() { if (sock) { MEMMAN_DELETE(sock); delete sock; } if (thr_listen) { thr_listen->cancel(); thr_listen->join(); MEMMAN_DELETE(thr_listen); delete thr_listen; } } twinkle-1.4.2/src/stun/Makefile.am0000644000175000001440000000032711134651206013725 00000000000000AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ $(CCRTP_CFLAGS)\ $(XML2_CFLAGS) noinst_LIBRARIES = libstun.a libstun_a_SOURCES =\ stun.cxx\ stun_transaction.cpp\ udp.cxx\ stun.h\ stun_transaction.h\ udp.h twinkle-1.4.2/src/stun/Makefile.in0000644000175000001440000004133511151323410013732 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/stun DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libstun_a_AR = $(AR) $(ARFLAGS) libstun_a_LIBADD = am_libstun_a_OBJECTS = stun.$(OBJEXT) stun_transaction.$(OBJEXT) \ udp.$(OBJEXT) libstun_a_OBJECTS = $(am_libstun_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libstun_a_SOURCES) DIST_SOURCES = $(libstun_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ $(CCRTP_CFLAGS)\ $(XML2_CFLAGS) noinst_LIBRARIES = libstun.a libstun_a_SOURCES = \ stun.cxx\ stun_transaction.cpp\ udp.cxx\ stun.h\ stun_transaction.h\ udp.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/stun/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/stun/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libstun.a: $(libstun_a_OBJECTS) $(libstun_a_DEPENDENCIES) -rm -f libstun.a $(libstun_a_AR) libstun.a $(libstun_a_OBJECTS) $(libstun_a_LIBADD) $(RANLIB) libstun.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stun.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stun_transaction.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udp.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/stun/udp.cxx0000644000175000001440000002117710503576706013225 00000000000000#include #include #include #include #include #include #include #ifdef WIN32 #include #include #include #else #include #include #include #include #include #include #include #include #include #include #endif #include #include "udp.h" using namespace std; StunSocket openPort( unsigned short port, unsigned int interfaceIp, bool verbose ) { StunSocket fd; fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if ( fd == INVALID_SOCKET ) { int err = getErrno(); cerr << "Could not create a UDP socket:" << err << endl; return INVALID_SOCKET; } struct sockaddr_in addr; memset((char*) &(addr),0, sizeof((addr))); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if ( (interfaceIp != 0) && ( interfaceIp != 0x100007f ) ) { addr.sin_addr.s_addr = htonl(interfaceIp); if (verbose ) { clog << "Binding to interface " << hex << "0x" << htonl(interfaceIp) << dec << endl; } } if ( bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 ) { int e = getErrno(); switch (e) { case 0: { cerr << "Could not bind socket" << endl; return INVALID_SOCKET; } case EADDRINUSE: { cerr << "Port " << port << " for receiving UDP is in use" << endl; return INVALID_SOCKET; } break; case EADDRNOTAVAIL: { if ( verbose ) { cerr << "Cannot assign requested address" << endl; } return INVALID_SOCKET; } break; default: { cerr << "Could not bind UDP receive port" << "Error=" << e << " " << strerror(e) << endl; return INVALID_SOCKET; } break; } } if ( verbose ) { clog << "Opened port " << port << " with fd " << fd << endl; } assert( fd != INVALID_SOCKET ); return fd; } bool getMessage( StunSocket fd, char* buf, int* len, unsigned int* srcIp, unsigned short* srcPort, bool verbose) { assert( fd != INVALID_SOCKET ); int originalSize = *len; assert( originalSize > 0 ); struct sockaddr_in from; int fromLen = sizeof(from); *len = recvfrom(fd, buf, originalSize, 0, (struct sockaddr *)&from, (socklen_t*)&fromLen); if ( *len == SOCKET_ERROR ) { int err = getErrno(); switch (err) { case ENOTSOCK: cerr << "Error fd not a socket" << endl; break; case ECONNRESET: cerr << "Error connection reset - host not reachable" << endl; break; default: cerr << "StunSocket Error=" << err << endl; } return false; } if ( *len < 0 ) { clog << "socket closed? negative len" << endl; return false; } if ( *len == 0 ) { clog << "socket closed? zero len" << endl; return false; } *srcPort = ntohs(from.sin_port); *srcIp = ntohl(from.sin_addr.s_addr); if ( (*len)+1 >= originalSize ) { if (verbose) { clog << "Received a message that was too large" << endl; } return false; } buf[*len]=0; return true; } bool sendMessage( StunSocket fd, char* buf, int l, unsigned int dstIp, unsigned short dstPort, bool verbose) { assert( fd != INVALID_SOCKET ); int s; if ( dstPort == 0 ) { // sending on a connected port assert( dstIp == 0 ); s = send(fd,buf,l,0); } else { assert( dstIp != 0 ); assert( dstPort != 0 ); struct sockaddr_in to; int toLen = sizeof(to); memset(&to,0,toLen); to.sin_family = AF_INET; to.sin_port = htons(dstPort); to.sin_addr.s_addr = htonl(dstIp); s = sendto(fd, buf, l, 0,(sockaddr*)&to, toLen); } if ( s == SOCKET_ERROR ) { int e = getErrno(); switch (e) { case ECONNREFUSED: case EHOSTDOWN: case EHOSTUNREACH: { // quietly ignore this } break; case EAFNOSUPPORT: { cerr << "err EAFNOSUPPORT in send" << endl; } break; default: { cerr << "err " << e << " " << strerror(e) << " in send" << endl; } } return false; } if ( s == 0 ) { cerr << "no data sent in send" << endl; return false; } if ( s != l ) { if (verbose) { cerr << "only " << s << " out of " << l << " bytes sent" << endl; } return false; } return true; } void initNetwork() { #ifdef WIN32 WORD wVersionRequested = MAKEWORD( 2, 2 ); WSADATA wsaData; int err; err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { // could not find a usable WinSock DLL cerr << "Could not load winsock" << endl; assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work exit(1); } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); cerr << "Bad winsock verion" << endl; assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work exit(1); } #endif } /* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * . * */ // Local Variables: // mode:c++ // c-file-style:"ellemtel" // c-file-offsets:((case-label . +)) // indent-tabs-mode:nil // End: twinkle-1.4.2/src/stun/stun.h0000644000175000001440000002532511127714045013043 00000000000000#ifndef STUN_H #define STUN_H #include #include #include using namespace std; // if you change this version, change in makefile too #define STUN_VERSION "0.94" #define STUN_MAX_STRING 256 #define STUN_MAX_UNKNOWN_ATTRIBUTES 8 #define STUN_MAX_MESSAGE_SIZE 2048 #define STUN_PORT 3478 // define some basic types typedef unsigned char UInt8; typedef unsigned short UInt16; typedef unsigned int UInt32; #if defined( WIN32 ) typedef unsigned __int64 UInt64; #else typedef unsigned long long UInt64; #endif typedef struct { unsigned char octet[16]; } UInt128; /// define a structure to hold a stun address const UInt8 IPv4Family = 0x01; const UInt8 IPv6Family = 0x02; // define flags const UInt32 ChangeIpFlag = 0x04; const UInt32 ChangePortFlag = 0x02; // define stun attribute const UInt16 MappedAddress = 0x0001; const UInt16 ResponseAddress = 0x0002; const UInt16 ChangeRequest = 0x0003; const UInt16 SourceAddress = 0x0004; const UInt16 ChangedAddress = 0x0005; const UInt16 Username = 0x0006; const UInt16 Password = 0x0007; const UInt16 MessageIntegrity = 0x0008; const UInt16 ErrorCode = 0x0009; const UInt16 UnknownAttribute = 0x000A; const UInt16 ReflectedFrom = 0x000B; const UInt16 XorMappedAddress = 0x0020; const UInt16 XorOnly = 0x0021; const UInt16 ServerName = 0x0022; const UInt16 SecondaryAddress = 0x0050; // Non standard extention // define types for a stun message const UInt16 BindRequestMsg = 0x0001; const UInt16 BindResponseMsg = 0x0101; const UInt16 BindErrorResponseMsg = 0x0111; const UInt16 SharedSecretRequestMsg = 0x0002; const UInt16 SharedSecretResponseMsg = 0x0102; const UInt16 SharedSecretErrorResponseMsg = 0x0112; typedef struct { UInt16 msgType; UInt16 msgLength; UInt128 id; } StunMsgHdr; typedef struct { UInt16 type; UInt16 length; } StunAtrHdr; typedef struct { UInt16 port; UInt32 addr; } StunAddress4; typedef struct { UInt8 pad; UInt8 family; StunAddress4 ipv4; } StunAtrAddress4; typedef struct { UInt32 value; } StunAtrChangeRequest; typedef struct { UInt16 pad; // all 0 UInt8 errorClass; UInt8 number; char reason[STUN_MAX_STRING]; UInt16 sizeReason; } StunAtrError; typedef struct { UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; UInt16 numAttributes; } StunAtrUnknown; typedef struct { char value[STUN_MAX_STRING]; UInt16 sizeValue; } StunAtrString; typedef struct { char hash[20]; } StunAtrIntegrity; typedef enum { HmacUnkown=0, HmacOK, HmacBadUserName, HmacUnkownUserName, HmacFailed, } StunHmacStatus; typedef struct { StunMsgHdr msgHdr; bool hasMappedAddress; StunAtrAddress4 mappedAddress; bool hasResponseAddress; StunAtrAddress4 responseAddress; bool hasChangeRequest; StunAtrChangeRequest changeRequest; bool hasSourceAddress; StunAtrAddress4 sourceAddress; bool hasChangedAddress; StunAtrAddress4 changedAddress; bool hasUsername; StunAtrString username; bool hasPassword; StunAtrString password; bool hasMessageIntegrity; StunAtrIntegrity messageIntegrity; bool hasErrorCode; StunAtrError errorCode; bool hasUnknownAttributes; StunAtrUnknown unknownAttributes; bool hasReflectedFrom; StunAtrAddress4 reflectedFrom; bool hasXorMappedAddress; StunAtrAddress4 xorMappedAddress; bool xorOnly; bool hasServerName; StunAtrString serverName; bool hasSecondaryAddress; StunAtrAddress4 secondaryAddress; } StunMessage; // Define enum with different types of NAT typedef enum { StunTypeUnknown=0, StunTypeOpen, StunTypeConeNat, StunTypeRestrictedNat, StunTypePortRestrictedNat, StunTypeSymNat, StunTypeSymFirewall, StunTypeBlocked, StunTypeFailure } NatType; #ifdef WIN32 typedef SOCKET StunSocket; #else typedef int StunSocket; #endif #define MAX_MEDIA_RELAYS 500 #define MAX_RTP_MSG_SIZE 1500 #define MEDIA_RELAY_TIMEOUT 3*60 typedef struct { int relayPort; // media relay port int fd; // media relay file descriptor StunAddress4 destination; // NAT IP:port time_t expireTime; // if no activity after time, close the socket } StunMediaRelay; typedef struct { StunAddress4 myAddr; StunAddress4 altAddr; StunSocket myFd; StunSocket altPortFd; StunSocket altIpFd; StunSocket altIpPortFd; bool relay; // true if media relaying is to be done StunMediaRelay relays[MAX_MEDIA_RELAYS]; } StunServerInfo; bool stunParseMessage( char* buf, unsigned int bufLen, StunMessage& message, bool verbose ); void stunBuildReqSimple( StunMessage* msg, const StunAtrString& username, bool changePort, bool changeIp, unsigned int id=0 ); unsigned int stunEncodeMessage( const StunMessage& message, char* buf, unsigned int bufLen, const StunAtrString& password, bool verbose); void stunCreateUserName(const StunAddress4& addr, StunAtrString* username); void stunGetUserNameAndPassword( const StunAddress4& dest, StunAtrString* username, StunAtrString* password); void stunCreatePassword(const StunAtrString& username, StunAtrString* password); // Twinkle // Build an error response StunMessage *stunBuildError(const StunMessage &m, int code, const char *reason); // Create a string representation of a STUN message string stunMsg2Str(const StunMessage &m); bool stunEqualId(const StunMessage &m1, const StunMessage &m2); string stunNatType2Str(NatType t); // Twinkle int stunRand(); UInt64 stunGetSystemTimeSecs(); /// find the IP address of a the specified stun server - return false is fails parse bool stunParseServerName( char* serverName, StunAddress4& stunServerAddr); bool stunParseHostName( char* peerName, UInt32& ip, UInt16& portVal, UInt16 defaultPort ); /// return true if all is OK /// Create a media relay and do the STERN thing if startMediaPort is non-zero bool stunInitServer(StunServerInfo& info, const StunAddress4& myAddr, const StunAddress4& altAddr, int startMediaPort, bool verbose); void stunStopServer(StunServerInfo& info); /// return true if all is OK bool stunServerProcess(StunServerInfo& info, bool verbose); /// returns number of address found - take array or addres int stunFindLocalInterfaces(UInt32* addresses, int maxSize ); void stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* srcAddr=0 ); NatType stunNatType( StunAddress4& dest, bool verbose, bool* preservePort=0, // if set, is return for if NAT preservers ports or not bool* hairpin=0 , // if set, is the return for if NAT will hairpin packets int port=0, // port to use for the test, 0 to choose random port StunAddress4* sAddr=0 // NIC to use ); /// prints a StunAddress std::ostream& operator<<( std::ostream& strm, const StunAddress4& addr); std::ostream& operator<< ( std::ostream& strm, const UInt128& ); bool stunServerProcessMsg( char* buf, unsigned int bufLen, StunAddress4& from, StunAddress4& myAddr, StunAddress4& altAddr, StunMessage* resp, StunAddress4* destination, StunAtrString* hmacPassword, bool* changePort, bool* changeIp, bool verbose); int stunOpenStunSocket( StunAddress4& dest, StunAddress4* mappedAddr, int port=0, StunAddress4* srcAddr=0, bool verbose=false ); bool stunOpenStunSocketPair( StunAddress4& dest, StunAddress4* mappedAddr, int* fd1, int* fd2, int srcPort=0, StunAddress4* srcAddr=0, bool verbose=false); #endif /* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * . * */ // Local Variables: // mode:c++ // c-file-style:"ellemtel" // c-file-offsets:((case-label . +)) // indent-tabs-mode:nil // End: twinkle-1.4.2/src/stun/stun_transaction.h0000644000175000001440000001120111127714045015434 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _STUN_TRANSACTION_H #define _STUN_TRANSACTION_H #include "stun.h" #include "phone_user.h" #include "protocol.h" #include "user.h" #include "transaction.h" #include "threads/mutex.h" #include "threads/thread.h" #include "sockets/socket.h" #include "sockets/url.h" // Create a binding in a NAT. // Returns true on success. Returns false when the STUN server returned // an error. Throws an int exception (containing errno) when some // socket operation fails. bool get_stun_binding(t_user *user_config, unsigned short src_port, unsigned long &mapped_ip, unsigned short &mapped_port, int &err_code, string &err_reason); // Discover the type of NAT and determine is STUN should be used or // wether STUN is useless. // It sets the use_stun attribute of phone if STUN should be used. // Return false if STUN cannot be used. err_msg will contain an // error message that can be displayed to the user. bool stun_discover_nat(t_phone_user *pu, string &err_msg); ////////////////////////////////////////////// // Base STUN transaction ////////////////////////////////////////////// class t_stun_transaction { private: static t_mutex mtx_class; // protect static members static t_tid next_id; // next id to be issued protected: t_tid id; // transaction id unsigned short tuid; // TU id t_trans_state state; // Timer for retransmissions unsigned short timer_req_timeout; // Duration for the next timer start in msec unsigned long dur_req_timeout; // Number of transmissions of the request unsigned short num_transmissions; // Destinations for the request list destinations; // User profile of user that created this transaction t_user *user_config; void start_timer_req_timeout(void); void stop_timer_req_timeout(void); // Retransmit STUN request virtual void retransmit(void) = 0; public: StunMessage *request; t_tid get_id(void) const; // Get state of the transaction t_trans_state get_state(void) const; // The transaction will keep a copy of the request t_stun_transaction(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst); // All request and response pointers contained by the // transaction will be deleted. virtual ~t_stun_transaction(); // Process STUN response virtual void process_response(StunMessage *r); // Process ICMP error virtual void process_icmp(const t_icmp_msg &icmp); // Process timeout virtual void timeout(t_stun_timer t); // Match response with transaction bool match(StunMessage *resp) const; // Match ICMP error with transaction bool match(const t_icmp_msg &icmp) const; }; ////////////////////////////////////////////// // SIP STUN transaction ////////////////////////////////////////////// // A SIP STUN transaction is a STUN request to get a binding // for the SIP port. Such a request must be sent from the SIP port. // So it must be sent out via the SIP sender thread. class t_sip_stun_trans : public t_stun_transaction { protected: virtual void retransmit(void); public: // Create transaction and send out STUN request t_sip_stun_trans(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst); }; ////////////////////////////////////////////// // Media STUN transaction ////////////////////////////////////////////// // TODO: this code is not used anymore. Remove? // A media STUN transaction is a STUN request to get a binding // for a media port. Such a request must be sent from the media // port. class t_media_stun_trans : public t_stun_transaction { private: t_socket_udp *sock; // UDP socket for STUN t_thread *thr_listen; // Listener thread protected: virtual void retransmit(void); public: // Create transaction and send out STUN request t_media_stun_trans(t_user *user, StunMessage *r, unsigned short _tuid, const list &dst, unsigned short src_port); ~t_media_stun_trans(); }; #endif twinkle-1.4.2/src/stun/stun.cxx0000644000175000001440000020635410503576706013430 00000000000000#include #include #include #include #include #ifdef WIN32 #include #include #include #include #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #if defined(__sparc__) || defined(WIN32) #define NOSSL #endif #define NOSSL #include "udp.h" #include "stun.h" // Twinkle #include "util.h" #include "sockets/socket.h" #include "audits/memman.h" using namespace std; static void computeHmac(char* hmac, const char* input, int length, const char* key, int keySize); static bool stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress4& result ) { if ( hdrLen != 8 ) { clog << "hdrLen wrong for Address" <= sizeof(result) ) { clog << "head on Error too large" << endl; return false; } else { memcpy(&result.pad, body, 2); body+=2; result.pad = ntohs(result.pad); result.errorClass = *body++; result.number = *body++; result.sizeReason = hdrLen - 4; memcpy(&result.reason, body, result.sizeReason); result.reason[result.sizeReason] = 0; return true; } } static bool stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown& result ) { if ( hdrLen >= sizeof(result) ) { return false; } else { if (hdrLen % 4 != 0) return false; result.numAttributes = hdrLen / 4; for (int i=0; i= STUN_MAX_STRING ) { clog << "String is too large" << endl; return false; } else { if (hdrLen % 4 != 0) { clog << "Bad length string " << hdrLen << endl; return false; } result.sizeValue = hdrLen; memcpy(&result.value, body, hdrLen); result.value[hdrLen] = 0; return true; } } static bool stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity& result ) { if ( hdrLen != 20) { clog << "MessageIntegrity must be 20 bytes" << endl; return false; } else { memcpy(&result.hash, body, hdrLen); return true; } } bool stunParseMessage( char* buf, unsigned int bufLen, StunMessage& msg, bool verbose) { if (verbose) clog << "Received stun message: " << bufLen << " bytes" << endl; memset(&msg, 0, sizeof(msg)); if (sizeof(StunMsgHdr) > bufLen) { return false; } memcpy(&msg.msgHdr, buf, sizeof(StunMsgHdr)); msg.msgHdr.msgType = ntohs(msg.msgHdr.msgType); msg.msgHdr.msgLength = ntohs(msg.msgHdr.msgLength); if (msg.msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen) { clog << "Message header length doesn't match message size: " << msg.msgHdr.msgLength << " - " << bufLen << endl; return false; } char* body = buf + sizeof(StunMsgHdr); unsigned int size = msg.msgHdr.msgLength; //clog << "bytes after header = " << size << endl; while ( size > 0 ) { // !jf! should check that there are enough bytes left in the buffer StunAtrHdr* attr = reinterpret_cast(body); unsigned int attrLen = ntohs(attr->length); int atrType = ntohs(attr->type); //if (verbose) clog << "Found attribute type=" << AttrNames[atrType] << " length=" << attrLen << endl; if ( attrLen+4 > size ) { clog << "claims attribute is larger than size of message " <<"(attribute type="<(&ndata), sizeof(UInt16)); return buf + sizeof(UInt16); } static char* encode32(char* buf, UInt32 data) { UInt32 ndata = htonl(data); memcpy(buf, reinterpret_cast(&ndata), sizeof(UInt32)); return buf + sizeof(UInt32); } static char* encode(char* buf, const char* data, unsigned int length) { memcpy(buf, data, length); return buf + length; } static char* encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4& atr) { ptr = encode16(ptr, type); ptr = encode16(ptr, 8); *ptr++ = atr.pad; *ptr++ = IPv4Family; ptr = encode16(ptr, atr.ipv4.port); ptr = encode32(ptr, atr.ipv4.addr); return ptr; } static char* encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest& atr) { ptr = encode16(ptr, ChangeRequest); ptr = encode16(ptr, 4); ptr = encode32(ptr, atr.value); return ptr; } static char* encodeAtrError(char* ptr, const StunAtrError& atr) { ptr = encode16(ptr, ErrorCode); ptr = encode16(ptr, 6 + atr.sizeReason); ptr = encode16(ptr, atr.pad); *ptr++ = atr.errorClass; *ptr++ = atr.number; ptr = encode(ptr, atr.reason, atr.sizeReason); return ptr; } static char* encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr) { ptr = encode16(ptr, UnknownAttribute); ptr = encode16(ptr, 2+2*atr.numAttributes); for (int i=0; i= sizeof(StunMsgHdr)); char* ptr = buf; ptr = encode16(ptr, msg.msgHdr.msgType); char* lengthp = ptr; ptr = encode16(ptr, 0); ptr = encode(ptr, reinterpret_cast(msg.msgHdr.id.octet), sizeof(msg.msgHdr.id)); if (verbose) clog << "Encoding stun message: " << endl; if (msg.hasMappedAddress) { if (verbose) clog << "Encoding MappedAddress: " << msg.mappedAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, MappedAddress, msg.mappedAddress); } if (msg.hasResponseAddress) { if (verbose) clog << "Encoding ResponseAddress: " << msg.responseAddress.ipv4 << endl; ptr = encodeAtrAddress4(ptr, ResponseAddress, msg.responseAddress); } if (msg.hasChangeRequest) { if (verbose) clog << "Encoding ChangeRequest: " << msg.changeRequest.value << endl; ptr = encodeAtrChangeRequest(ptr, msg.changeRequest); } if (msg.hasSourceAddress) { if (verbose) clog << "Encoding SourceAddress: " << msg.sourceAddress.ipv4 << endl; ptr = encodeAtrAddress4(ptr, SourceAddress, msg.sourceAddress); } if (msg.hasChangedAddress) { if (verbose) clog << "Encoding ChangedAddress: " << msg.changedAddress.ipv4 << endl; ptr = encodeAtrAddress4(ptr, ChangedAddress, msg.changedAddress); } if (msg.hasUsername) { if (verbose) clog << "Encoding Username: " << msg.username.value << endl; ptr = encodeAtrString(ptr, Username, msg.username); } if (msg.hasPassword) { if (verbose) clog << "Encoding Password: " << msg.password.value << endl; ptr = encodeAtrString(ptr, Password, msg.password); } if (msg.hasErrorCode) { if (verbose) clog << "Encoding ErrorCode: class=" << int(msg.errorCode.errorClass) << " number=" << int(msg.errorCode.number) << " reason=" << msg.errorCode.reason << endl; ptr = encodeAtrError(ptr, msg.errorCode); } if (msg.hasUnknownAttributes) { if (verbose) clog << "Encoding UnknownAttribute: ???" << endl; ptr = encodeAtrUnknown(ptr, msg.unknownAttributes); } if (msg.hasReflectedFrom) { if (verbose) clog << "Encoding ReflectedFrom: " << msg.reflectedFrom.ipv4 << endl; ptr = encodeAtrAddress4(ptr, ReflectedFrom, msg.reflectedFrom); } if (msg.hasXorMappedAddress) { if (verbose) clog << "Encoding XorMappedAddress: " << msg.xorMappedAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, XorMappedAddress, msg.xorMappedAddress); } if (msg.xorOnly) { if (verbose) clog << "Encoding xorOnly: " << endl; ptr = encodeXorOnly( ptr ); } if (msg.hasServerName) { if (verbose) clog << "Encoding ServerName: " << msg.serverName.value << endl; ptr = encodeAtrString(ptr, ServerName, msg.serverName); } if (msg.hasSecondaryAddress) { if (verbose) clog << "Encoding SecondaryAddress: " << msg.secondaryAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, SecondaryAddress, msg.secondaryAddress); } if (password.sizeValue > 0) { if (verbose) clog << "HMAC with password: " << password.value << endl; StunAtrIntegrity integrity; computeHmac(integrity.hash, buf, int(ptr-buf) , password.value, password.sizeValue); ptr = encodeAtrIntegrity(ptr, integrity); } if (verbose) clog << endl; encode16(lengthp, UInt16(ptr - buf - sizeof(StunMsgHdr))); return int(ptr - buf); } int stunRand() { // return 32 bits of random stuff assert( sizeof(int) == 4 ); static bool init=false; if ( !init ) { init = true; UInt64 tick; // Twinkle: removed platform dependent code (except WIN32 code) #if defined(WIN32) volatile unsigned int lowtick=0,hightick=0; __asm { rdtsc mov lowtick, eax mov hightick, edx } tick = hightick; tick <<= 32; tick |= lowtick; #else tick = time(NULL); #endif int seed = int(tick); #ifdef WIN32 srand(seed); #else srandom(seed); #endif } #ifdef WIN32 assert( RAND_MAX == 0x7fff ); int r1 = rand(); int r2 = rand(); int ret = (r1<<16) + r2; return ret; #else return random(); #endif } /// return a random number to use as a port static int randomPort() { int min=0x4000; int max=0x7FFF; int ret = stunRand(); ret = ret|min; ret = ret&max; return ret; } #ifdef NOSSL static void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) { strncpy(hmac,"hmac-not-implemented",20); } #else #include static void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) { unsigned int resultSize=0; HMAC(EVP_sha1(), key, sizeKey, reinterpret_cast(input), length, reinterpret_cast(hmac), &resultSize); assert(resultSize == 20); } #endif static void toHex(const char* buffer, int bufferSize, char* output) { static char hexmap[] = "0123456789abcdef"; const char* p = buffer; char* r = output; for (int i=0; i < bufferSize; i++) { unsigned char temp = *p++; int hi = (temp & 0xf0)>>4; int low = (temp & 0xf); *r++ = hexmap[hi]; *r++ = hexmap[low]; } *r = 0; } void stunCreateUserName(const StunAddress4& source, StunAtrString* username) { UInt64 time = stunGetSystemTimeSecs(); time -= (time % 20*60); //UInt64 hitime = time >> 32; UInt64 lotime = time & 0xFFFFFFFF; char buffer[1024]; sprintf(buffer, "%08x:%08x:%08x:", UInt32(source.addr), UInt32(stunRand()), UInt32(lotime)); assert( strlen(buffer) < 1024 ); assert(strlen(buffer) + 41 < STUN_MAX_STRING); char hmac[20]; char key[] = "Jason"; computeHmac(hmac, buffer, strlen(buffer), key, strlen(key) ); char hmacHex[41]; toHex(hmac, 20, hmacHex ); hmacHex[40] =0; strcat(buffer,hmacHex); int l = strlen(buffer); assert( l+1 < STUN_MAX_STRING ); assert( l%4 == 0 ); username->sizeValue = l; memcpy(username->value,buffer,l); username->value[l]=0; //if (verbose) clog << "computed username=" << username.value << endl; } void stunCreatePassword(const StunAtrString& username, StunAtrString* password) { char hmac[20]; char key[] = "Fluffy"; //char buffer[STUN_MAX_STRING]; computeHmac(hmac, username.value, strlen(username.value), key, strlen(key)); toHex(hmac, 20, password->value); password->sizeValue = 40; password->value[40]=0; //clog << "password=" << password->value << endl; } UInt64 stunGetSystemTimeSecs() { UInt64 time=0; #if defined(WIN32) SYSTEMTIME t; // CJ TODO - this probably has bug on wrap around every 24 hours GetSystemTime( &t ); time = (t.wHour*60+t.wMinute)*60+t.wSecond; #else struct timeval now; gettimeofday( &now , NULL ); //assert( now ); time = now.tv_sec; #endif return time; } ostream& operator<< ( ostream& strm, const UInt128& r ) { strm << int(r.octet[0]); for ( int i=1; i<16; i++ ) { strm << ':' << int(r.octet[i]); } return strm; } ostream& operator<<( ostream& strm, const StunAddress4& addr) { UInt32 ip = addr.addr; strm << ((int)(ip>>24)&0xFF) << "."; strm << ((int)(ip>>16)&0xFF) << "."; strm << ((int)(ip>> 8)&0xFF) << "."; strm << ((int)(ip>> 0)&0xFF) ; strm << ":" << addr.port; return strm; } // returns true if it scucceeded bool stunParseHostName( char* peerName, UInt32& ip, UInt16& portVal, UInt16 defaultPort ) { in_addr sin_addr; char host[512]; strncpy(host,peerName,512); host[512-1]='\0'; char* port = NULL; int portNum = defaultPort; // pull out the port part if present. char* sep = strchr(host,':'); if ( sep == NULL ) { portNum = defaultPort; } else { *sep = '\0'; port = sep + 1; // set port part char* endPtr=NULL; portNum = strtol(port,&endPtr,10); if ( endPtr != NULL ) { if ( *endPtr != '\0' ) { portNum = defaultPort; } } } if ( portNum < 1024 ) return false; if ( portNum >= 0xFFFF ) return false; // figure out the host part struct hostent* h; #ifdef WIN32 assert( strlen(host) >= 1 ); if ( isdigit( host[0] ) ) { // assume it is a ip address unsigned long a = inet_addr(host); //cerr << "a=0x" << hex << a << dec << endl; ip = ntohl( a ); } else { // assume it is a host name h = gethostbyname( host ); if ( h == NULL ) { int err = getErrno(); std::cerr << "error was " << err << std::endl; assert( err != WSANOTINITIALISED ); ip = ntohl( 0x7F000001L ); return false; } else { sin_addr = *(struct in_addr*)h->h_addr; ip = ntohl( sin_addr.s_addr ); } } #else h = gethostbyname( host ); if ( h == NULL ) { int err = getErrno(); std::cerr << "error was " << err << std::endl; ip = ntohl( 0x7F000001L ); return false; } else { sin_addr = *(struct in_addr*)h->h_addr; ip = ntohl( sin_addr.s_addr ); } #endif portVal = portNum; return true; } bool stunParseServerName( char* name, StunAddress4& addr) { assert(name); // TODO - put in DNS SRV stuff. bool ret = stunParseHostName( name, addr.addr, addr.port, 3478); if ( ret != true ) { addr.port=0xFFFF; } return ret; } static void stunCreateErrorResponse(StunMessage& response, int cl, int number, const char* msg) { response.msgHdr.msgType = BindErrorResponseMsg; response.hasErrorCode = true; response.errorCode.errorClass = cl; response.errorCode.number = number; strcpy(response.errorCode.reason, msg); } // Twinkle StunMessage *stunBuildError(const StunMessage &m, int code, const char *reason) { StunMessage *err = new StunMessage(); MEMMAN_NEW(err); stunCreateErrorResponse(*err, code / 100, code % 100, reason); for ( int i=0; i<16; i++ ) { err->msgHdr.id.octet[i] = m.msgHdr.id.octet[i]; } return err; } string stunMsg2Str(const StunMessage &m) { string s = "STUN "; // Message type if (m.msgHdr.msgType == BindRequestMsg) { s += "Bind Request"; } else if (m.msgHdr.msgType == BindResponseMsg) { s += "Bind Response"; } else if (m.msgHdr.msgType == BindErrorResponseMsg) { s += "Bind Error Response"; } else if (m.msgHdr.msgType == SharedSecretRequestMsg) { s += "Shared Secret Request"; } else if (m.msgHdr.msgType == SharedSecretResponseMsg) { s += "Shared Secret Response"; } else if (m.msgHdr.msgType == SharedSecretErrorResponseMsg) { s += "Shared Secret Error Response"; } s += "\n"; // Message ID s += "ID = "; for ( int i=0; i<16; i++ ) { char buf[3]; snprintf(buf, 3, "%X", m.msgHdr.id.octet[i]); s += buf; } s += "\n"; if (m.hasMappedAddress) { s += "Mapped Addres = "; s += h_ip2str(m.mappedAddress.ipv4.addr); s += ':'; s += int2str(m.mappedAddress.ipv4.port); s += "\n"; } if (m.hasResponseAddress) { s += "Response Addres = "; s += h_ip2str(m.responseAddress.ipv4.addr); s += ':'; s += int2str(m.responseAddress.ipv4.port); s += "\n"; } if (m.hasChangeRequest) { s += "Change Request = "; bool change_flags = false; if (m.changeRequest.value & ChangeIpFlag) { s += "change IP"; change_flags = true; } if (m.changeRequest.value & ChangePortFlag) { if (change_flags) s += ", "; s += "change port"; change_flags = true; } if (!change_flags) s += "none"; s += "\n"; } if (m.hasSourceAddress) { s += "Source Addres = "; s += h_ip2str(m.sourceAddress.ipv4.addr); s += ':'; s += int2str(m.sourceAddress.ipv4.port); s += "\n"; } if (m.hasChangedAddress) { s += "Changed Addres = "; s += h_ip2str(m.changedAddress.ipv4.addr); s += ':'; s += int2str(m.changedAddress.ipv4.port); s += "\n"; } if (m.hasErrorCode) { s += "Error Code = "; s += int2str(m.errorCode.errorClass * 100 + m.errorCode.number); s += ' '; s += m.errorCode.reason; s += "\n"; } return s; } bool stunEqualId(const StunMessage &m1, const StunMessage &m2) { for ( int i=0; i<16; i++ ) { if (m1.msgHdr.id.octet[i] != m2.msgHdr.id.octet[i]) { return false; } } return true; } string stunNatType2Str(NatType t) { switch (t) { case StunTypeUnknown: return "Unknow"; case StunTypeOpen: return "Open"; case StunTypeConeNat: return "Full cone"; case StunTypeRestrictedNat: return "Restriced cone"; case StunTypePortRestrictedNat: return "Port restricted cone"; case StunTypeSymNat: return "Symmetric"; case StunTypeSymFirewall: return "Symmetric firewall;"; case StunTypeBlocked: return "Blocked."; case StunTypeFailure: return "Failed"; default: return "NULL"; } } // Twinkle #if 0 static void stunCreateSharedSecretErrorResponse(StunMessage& response, int cl, int number, const char* msg) { response.msgHdr.msgType = SharedSecretErrorResponseMsg; response.hasErrorCode = true; response.errorCode.errorClass = cl; response.errorCode.number = number; strcpy(response.errorCode.reason, msg); } #endif static void stunCreateSharedSecretResponse(const StunMessage& request, const StunAddress4& source, StunMessage& response) { response.msgHdr.msgType = SharedSecretResponseMsg; response.msgHdr.id = request.msgHdr.id; response.hasUsername = true; stunCreateUserName( source, &response.username); response.hasPassword = true; stunCreatePassword( response.username, &response.password); } // This funtion takes a single message sent to a stun server, parses // and constructs an apropriate repsonse - returns true if message is // valid bool stunServerProcessMsg( char* buf, unsigned int bufLen, StunAddress4& from, StunAddress4& secondary, StunAddress4& myAddr, StunAddress4& altAddr, StunMessage* resp, StunAddress4* destination, StunAtrString* hmacPassword, bool* changePort, bool* changeIp, bool verbose) { // set up information for default response memset( resp, 0 , sizeof(*resp) ); *changeIp = false; *changePort = false; StunMessage req; bool ok = stunParseMessage( buf,bufLen, req, verbose); if (!ok) // Complete garbage, drop it on the floor { if (verbose) clog << "Request did not parse" << endl; return false; } if (verbose) clog << "Request parsed ok" << endl; StunAddress4 mapped = req.mappedAddress.ipv4; StunAddress4 respondTo = req.responseAddress.ipv4; UInt32 flags = req.changeRequest.value; switch (req.msgHdr.msgType) { case SharedSecretRequestMsg: if(verbose) clog << "Received SharedSecretRequestMsg on udp. send error 433." << endl; // !cj! - should fix so you know if this came over TLS or UDP stunCreateSharedSecretResponse(req, from, *resp); //stunCreateSharedSecretErrorResponse(*resp, 4, 33, "this request must be over TLS"); return true; case BindRequestMsg: if (!req.hasMessageIntegrity) { if (verbose) clog << "BindRequest does not contain MessageIntegrity" << endl; if (0) // !jf! mustAuthenticate { if(verbose) clog << "Received BindRequest with no MessageIntegrity. Sending 401." << endl; stunCreateErrorResponse(*resp, 4, 1, "Missing MessageIntegrity"); return true; } } else { if (!req.hasUsername) { if (verbose) clog << "No UserName. Send 432." << endl; stunCreateErrorResponse(*resp, 4, 32, "No UserName and contains MessageIntegrity"); return true; } else { if (verbose) clog << "Validating username: " << req.username.value << endl; // !jf! could retrieve associated password from provisioning here if (strcmp(req.username.value, "test") == 0) { if (0) { // !jf! if the credentials are stale stunCreateErrorResponse(*resp, 4, 30, "Stale credentials on BindRequest"); return true; } else { if (verbose) clog << "Validating MessageIntegrity" << endl; // need access to shared secret unsigned char hmac[20]; #ifndef NOSSL unsigned int hmacSize=20; HMAC(EVP_sha1(), "1234", 4, reinterpret_cast(buf), bufLen-20-4, hmac, &hmacSize); assert(hmacSize == 20); #endif if (memcmp(buf, hmac, 20) != 0) { if (verbose) clog << "MessageIntegrity is bad. Sending " << endl; stunCreateErrorResponse(*resp, 4, 3, "Unknown username. Try test with password 1234"); return true; } // need to compute this later after message is filled in resp->hasMessageIntegrity = true; assert(req.hasUsername); resp->hasUsername = true; resp->username = req.username; // copy username in } } else { if (verbose) clog << "Invalid username: " << req.username.value << "Send 430." << endl; } } } // TODO !jf! should check for unknown attributes here and send 420 listing the // unknown attributes. if ( respondTo.port == 0 ) respondTo = from; if ( mapped.port == 0 ) mapped = from; *changeIp = ( flags & ChangeIpFlag )?true:false; *changePort = ( flags & ChangePortFlag )?true:false; if (verbose) { clog << "Request is valid:" << endl; clog << "\t flags=" << flags << endl; clog << "\t changeIp=" << *changeIp << endl; clog << "\t changePort=" << *changePort << endl; clog << "\t from = " << from << endl; clog << "\t respond to = " << respondTo << endl; clog << "\t mapped = " << mapped << endl; } // form the outgoing message resp->msgHdr.msgType = BindResponseMsg; for ( int i=0; i<16; i++ ) { resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i]; } if ( req.xorOnly == false ) { resp->hasMappedAddress = true; resp->mappedAddress.ipv4.port = mapped.port; resp->mappedAddress.ipv4.addr = mapped.addr; } if (1) // do xorMapped address or not { resp->hasXorMappedAddress = true; UInt16 id16 = req.msgHdr.id.octet[7]<<8 | req.msgHdr.id.octet[6]; UInt32 id32 = req.msgHdr.id.octet[7]<<24 | req.msgHdr.id.octet[6]<<16 | req.msgHdr.id.octet[5]<<8 | req.msgHdr.id.octet[4];; resp->xorMappedAddress.ipv4.port = mapped.port^id16; resp->xorMappedAddress.ipv4.addr = mapped.addr^id32; } resp->hasSourceAddress = true; resp->sourceAddress.ipv4.port = (*changePort) ? altAddr.port : myAddr.port; resp->sourceAddress.ipv4.addr = (*changeIp) ? altAddr.addr : myAddr.addr; resp->hasChangedAddress = true; resp->changedAddress.ipv4.port = altAddr.port; resp->changedAddress.ipv4.addr = altAddr.addr; if ( secondary.port != 0 ) { resp->hasSecondaryAddress = true; resp->secondaryAddress.ipv4.port = secondary.port; resp->secondaryAddress.ipv4.addr = secondary.addr; } if ( req.hasUsername && req.username.sizeValue > 0 ) { // copy username in resp->hasUsername = true; assert( req.username.sizeValue % 4 == 0 ); assert( req.username.sizeValue < STUN_MAX_STRING ); memcpy( resp->username.value, req.username.value, req.username.sizeValue ); resp->username.sizeValue = req.username.sizeValue; } if (1) // add ServerName { resp->hasServerName = true; const char serverName[] = "Vovida.org " STUN_VERSION; // must pad to mult of 4 assert( sizeof(serverName) < STUN_MAX_STRING ); //cerr << "sizeof serverName is " << sizeof(serverName) << endl; assert( sizeof(serverName)%4 == 0 ); memcpy( resp->serverName.value, serverName, sizeof(serverName)); resp->serverName.sizeValue = sizeof(serverName); } if ( req.hasMessageIntegrity & req.hasUsername ) { // this creates the password that will be used in the HMAC when then // messages is sent stunCreatePassword( req.username, hmacPassword ); } if (req.hasUsername && (req.username.sizeValue > 64 ) ) { UInt32 source; assert( sizeof(int) == sizeof(UInt32) ); sscanf(req.username.value, "%x", &source); resp->hasReflectedFrom = true; resp->reflectedFrom.ipv4.port = 0; resp->reflectedFrom.ipv4.addr = source; } destination->port = respondTo.port; destination->addr = respondTo.addr; return true; default: if (verbose) clog << "Unknown or unsupported request " << endl; return false; } assert(0); return false; } bool stunInitServer(StunServerInfo& info, const StunAddress4& myAddr, const StunAddress4& altAddr, int startMediaPort, bool verbose ) { assert( myAddr.port != 0 ); assert( altAddr.port!= 0 ); assert( myAddr.addr != 0 ); //assert( altAddr.addr != 0 ); info.myAddr = myAddr; info.altAddr = altAddr; info.myFd = INVALID_SOCKET; info.altPortFd = INVALID_SOCKET; info.altIpFd = INVALID_SOCKET; info.altIpPortFd = INVALID_SOCKET; memset(info.relays, 0, sizeof(info.relays)); if (startMediaPort > 0) { info.relay = true; for (int i=0; irelayPort = startMediaPort+i; relay->fd = 0; relay->expireTime = 0; } } else { info.relay = false; } if ((info.myFd = openPort(myAddr.port, myAddr.addr,verbose)) == INVALID_SOCKET) { clog << "Can't open " << myAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << myAddr.addr << ":" << myAddr.port << " --> " << info.myFd << endl; if ((info.altPortFd = openPort(altAddr.port,myAddr.addr,verbose)) == INVALID_SOCKET) { clog << "Can't open " << myAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << myAddr.addr << ":" << altAddr.port << " --> " << info.altPortFd << endl; info.altIpFd = INVALID_SOCKET; if ( altAddr.addr != 0 ) { if ((info.altIpFd = openPort( myAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET) { clog << "Can't open " << altAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << altAddr.addr << ":" << myAddr.port << " --> " << info.altIpFd << endl;; } info.altIpPortFd = INVALID_SOCKET; if ( altAddr.addr != 0 ) { if ((info.altIpPortFd = openPort(altAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET) { clog << "Can't open " << altAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << altAddr.addr << ":" << altAddr.port << " --> " << info.altIpPortFd << endl;; } return true; } void stunStopServer(StunServerInfo& info) { if (info.myFd > 0) closesocket(info.myFd); if (info.altPortFd > 0) closesocket(info.altPortFd); if (info.altIpFd > 0) closesocket(info.altIpFd); if (info.altIpPortFd > 0) closesocket(info.altIpPortFd); if (info.relay) { for (int i=0; ifd) { closesocket(relay->fd); relay->fd = 0; } } } } bool stunServerProcess(StunServerInfo& info, bool verbose) { char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); bool ok = false; bool recvAltIp =false; bool recvAltPort = false; fd_set fdSet; #ifdef WIN32 unsigned int maxFd=0; #else int maxFd=0; #endif FD_ZERO(&fdSet); FD_SET(info.myFd,&fdSet); if ( info.myFd >= maxFd ) maxFd=info.myFd+1; FD_SET(info.altPortFd,&fdSet); if ( info.altPortFd >= maxFd ) maxFd=info.altPortFd+1; if ( info.altIpFd != INVALID_SOCKET ) { FD_SET(info.altIpFd,&fdSet); if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; } if ( info.altIpPortFd != INVALID_SOCKET ) { FD_SET(info.altIpPortFd,&fdSet); if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; } if (info.relay) { for (int i=0; ifd) { FD_SET(relay->fd, &fdSet); if (relay->fd >= maxFd) maxFd=relay->fd+1; } } } if ( info.altIpFd != INVALID_SOCKET ) { FD_SET(info.altIpFd,&fdSet); if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; } if ( info.altIpPortFd != INVALID_SOCKET ) { FD_SET(info.altIpPortFd,&fdSet); if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; } struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000; int e = select( maxFd, &fdSet, NULL,NULL, &tv ); if (e < 0) { int err = getErrno(); clog << "Error on select: " << strerror(err) << endl; } else if (e >= 0) { StunAddress4 from; // do the media relaying if (info.relay) { time_t now = time(0); for (int i=0; ifd) { if (FD_ISSET(relay->fd, &fdSet)) { char msg[MAX_RTP_MSG_SIZE]; int msgLen = sizeof(msg); StunAddress4 rtpFrom; ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose); if (ok) { sendMessage(info.myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose); relay->expireTime = now + MEDIA_RELAY_TIMEOUT; if ( verbose ) clog << "Relay packet on " << relay->fd << " from " << rtpFrom << " -> " << relay->destination << endl; } } else if (now > relay->expireTime) { closesocket(relay->fd); relay->fd = 0; } } } } if (FD_ISSET(info.myFd,&fdSet)) { if (verbose) clog << "received on A1:P1" << endl; recvAltIp = false; recvAltPort = false; ok = getMessage( info.myFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if (FD_ISSET(info.altPortFd, &fdSet)) { if (verbose) clog << "received on A1:P2" << endl; recvAltIp = false; recvAltPort = true; ok = getMessage( info.altPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if ( (info.altIpFd!=INVALID_SOCKET) && FD_ISSET(info.altIpFd,&fdSet)) { if (verbose) clog << "received on A2:P1" << endl; recvAltIp = true; recvAltPort = false; ok = getMessage( info.altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose); } else if ( (info.altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info.altIpPortFd, &fdSet)) { if (verbose) clog << "received on A2:P2" << endl; recvAltIp = true; recvAltPort = true; ok = getMessage( info.altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else { return true; } int relayPort = 0; if (info.relay) { for (int i=0; idestination.addr == from.addr && relay->destination.port == from.port) { relayPort = relay->relayPort; relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; break; } } if (relayPort == 0) { for (int i=0; ifd == 0) { if ( verbose ) clog << "Open relay port " << relay->relayPort << endl; relay->fd = openPort(relay->relayPort, info.myAddr.addr, verbose); relay->destination.addr = from.addr; relay->destination.port = from.port; relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; relayPort = relay->relayPort; break; } } } } if ( !ok ) { if ( verbose ) clog << "Get message did not return a valid message" < 0) && ( count < maxRet) ) { struct ifreq* ifr = (struct ifreq *)ptr; int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr); tl -= si; ptr += si; //char* name = ifr->ifr_ifrn.ifrn_name; //cerr << "name = " << name << endl; struct ifreq ifr2; ifr2 = *ifr; e = ioctl(s,SIOCGIFADDR,&ifr2); if ( e == -1 ) { break; } //cerr << "ioctl addr e = " << e << endl; struct sockaddr a = ifr2.ifr_addr; struct sockaddr_in* addr = (struct sockaddr_in*) &a; UInt32 ai = ntohl( addr->sin_addr.s_addr ); if (int((ai>>24)&0xFF) != 127) { addresses[count++] = ai; } #if 0 cerr << "Detected interface " << int((ai>>24)&0xFF) << "." << int((ai>>16)&0xFF) << "." << int((ai>> 8)&0xFF) << "." << int((ai )&0xFF) << endl; #endif } closesocket(s); return count; #endif } void stunBuildReqSimple( StunMessage* msg, const StunAtrString& username, bool changePort, bool changeIp, unsigned int id ) { assert( msg ); memset( msg , 0 , sizeof(*msg) ); msg->msgHdr.msgType = BindRequestMsg; for ( int i=0; i<16; i=i+4 ) { assert(i+3<16); int r = stunRand(); msg->msgHdr.id.octet[i+0]= r>>0; msg->msgHdr.id.octet[i+1]= r>>8; msg->msgHdr.id.octet[i+2]= r>>16; msg->msgHdr.id.octet[i+3]= r>>24; } if ( id != 0 ) { msg->msgHdr.id.octet[0] = id; } msg->hasChangeRequest = true; msg->changeRequest.value =(changeIp?ChangeIpFlag:0) | (changePort?ChangePortFlag:0); if ( username.sizeValue > 0 ) { msg->hasUsername = true; msg->username = username; } } static void stunSendTest( StunSocket myFd, StunAddress4& dest, const StunAtrString& username, const StunAtrString& password, int testNum, bool verbose ) { assert( dest.addr != 0 ); assert( dest.port != 0 ); bool changePort=false; bool changeIP=false; bool discard=false; switch (testNum) { case 1: case 10: case 11: break; case 2: //changePort=true; changeIP=true; break; case 3: changePort=true; break; case 4: changeIP=true; break; case 5: discard=true; break; default: cerr << "Test " << testNum <<" is unkown\n"; assert(0); } StunMessage req; memset(&req, 0, sizeof(StunMessage)); stunBuildReqSimple( &req, username, changePort , changeIP , testNum ); char buf[STUN_MAX_MESSAGE_SIZE]; int len = STUN_MAX_MESSAGE_SIZE; len = stunEncodeMessage( req, buf, len, password,verbose ); if ( verbose ) { clog << "About to send msg of len " << len << " to " << dest << endl; } sendMessage( myFd, buf, len, dest.addr, dest.port, verbose ); // add some delay so the packets don't get sent too quickly #ifdef WIN32 // !cj! TODO - should fix this up in windows clock_t now = clock(); assert( CLOCKS_PER_SEC == 1000 ); while ( clock() <= now+10 ) { }; #else usleep(10*1000); #endif } void stunGetUserNameAndPassword( const StunAddress4& dest, StunAtrString* username, StunAtrString* password) { // !cj! This is totally bogus - need to make TLS connection to dest and get a // username and password to use stunCreateUserName(dest, username); stunCreatePassword(*username, password); } void stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* sAddr ) { assert( dest.addr != 0 ); assert( dest.port != 0 ); int port = randomPort(); UInt32 interfaceIp=0; if (sAddr) { interfaceIp = sAddr->addr; if ( sAddr->port != 0 ) { port = sAddr->port; } } StunSocket myFd = openPort(port,interfaceIp,verbose); StunAtrString username; StunAtrString password; username.sizeValue = 0; password.sizeValue = 0; #ifdef USE_TLS stunGetUserNameAndPassword( dest, username, password ); #endif stunSendTest( myFd, dest, username, password, testNum, verbose ); char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = STUN_MAX_MESSAGE_SIZE; StunAddress4 from; getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); StunMessage resp; memset(&resp, 0, sizeof(StunMessage)); if ( verbose ) clog << "Got a response" << endl; bool ok = stunParseMessage( msg,msgLen, resp,verbose ); if ( verbose ) { clog << "\t ok=" << ok << endl; clog << "\t id=" << resp.msgHdr.id << endl; clog << "\t mappedAddr=" << resp.mappedAddress.ipv4 << endl; clog << "\t changedAddr=" << resp.changedAddress.ipv4 << endl; clog << endl; } if (sAddr) { sAddr->port = resp.mappedAddress.ipv4.port; sAddr->addr = resp.mappedAddress.ipv4.addr; } } NatType stunNatType( StunAddress4& dest, bool verbose, bool* preservePort, // if set, is return for if NAT preservers ports or not bool* hairpin, // if set, is the return for if NAT will hairpin packets int port, // port to use for the test, 0 to choose random port StunAddress4* sAddr // NIC to use ) { assert( dest.addr != 0 ); assert( dest.port != 0 ); if ( hairpin ) { *hairpin = false; } if ( port == 0 ) { port = randomPort(); } UInt32 interfaceIp=0; if (sAddr) { interfaceIp = sAddr->addr; } StunSocket myFd1 = openPort(port,interfaceIp,verbose); StunSocket myFd2 = openPort(port+1,interfaceIp,verbose); if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) ) { cerr << "Some problem opening port/interface to send on" << endl; return StunTypeFailure; } assert( myFd1 != INVALID_SOCKET ); assert( myFd2 != INVALID_SOCKET ); bool respTestI=false; bool isNat=true; StunAddress4 testIchangedAddr; StunAddress4 testImappedAddr; bool respTestI2=false; bool mappedIpSame = true; StunAddress4 testI2mappedAddr; StunAddress4 testI2dest=dest; bool respTestII=false; bool respTestIII=false; bool respTestHairpin=false; memset(&testImappedAddr,0,sizeof(testImappedAddr)); StunAtrString username; StunAtrString password; username.sizeValue = 0; password.sizeValue = 0; #ifdef USE_TLS stunGetUserNameAndPassword( dest, username, password ); #endif //stunSendTest( myFd1, dest, username, password, 1, verbose ); int count=0; while ( count < 7 ) { struct timeval tv; fd_set fdSet; #ifdef WIN32 unsigned int fdSetSize; #else int fdSetSize; #endif FD_ZERO(&fdSet); fdSetSize=0; FD_SET(myFd1,&fdSet); fdSetSize = (myFd1+1>fdSetSize) ? myFd1+1 : fdSetSize; FD_SET(myFd2,&fdSet); fdSetSize = (myFd2+1>fdSetSize) ? myFd2+1 : fdSetSize; tv.tv_sec=0; tv.tv_usec=150*1000; // 150 ms if ( count == 0 ) tv.tv_usec=0; int err = select(fdSetSize, &fdSet, NULL, NULL, &tv); int e = getErrno(); if ( err == SOCKET_ERROR ) { // error occured cerr << "Error " << e << " " << strerror(e) << " in select" << endl; closesocket(myFd1); closesocket(myFd2); return StunTypeFailure; } else if ( err == 0 ) { // timeout occured count++; if ( !respTestI ) { stunSendTest( myFd1, dest, username, password, 1 ,verbose ); } if ( (!respTestI2) && respTestI ) { // check the address to send to if valid if ( ( testI2dest.addr != 0 ) && ( testI2dest.port != 0 ) ) { stunSendTest( myFd1, testI2dest, username, password, 10 ,verbose); } } if ( !respTestII ) { stunSendTest( myFd2, dest, username, password, 2 ,verbose ); } if ( !respTestIII ) { stunSendTest( myFd2, dest, username, password, 3 ,verbose ); } if ( respTestI && (!respTestHairpin) ) { if ( ( testImappedAddr.addr != 0 ) && ( testImappedAddr.port != 0 ) ) { stunSendTest( myFd1, testImappedAddr, username, password, 11 ,verbose ); } } } else { //if (verbose) clog << "-----------------------------------------" << endl; assert( err>0 ); // data is avialbe on some fd for ( int i=0; i<2; i++) { StunSocket myFd; if ( i==0 ) { myFd=myFd1; } else { myFd=myFd2; } if ( myFd!=INVALID_SOCKET ) { if ( FD_ISSET(myFd,&fdSet) ) { char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); StunAddress4 from; getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); StunMessage resp; memset(&resp, 0, sizeof(StunMessage)); stunParseMessage( msg,msgLen, resp,verbose ); if ( verbose ) { clog << "Received message of type " << resp.msgHdr.msgType << " id=" << (int)(resp.msgHdr.id.octet[0]) << endl; } switch( resp.msgHdr.id.octet[0] ) { case 1: { if ( !respTestI ) { testIchangedAddr.addr = resp.changedAddress.ipv4.addr; testIchangedAddr.port = resp.changedAddress.ipv4.port; testImappedAddr.addr = resp.mappedAddress.ipv4.addr; testImappedAddr.port = resp.mappedAddress.ipv4.port; if ( preservePort ) { *preservePort = ( testImappedAddr.port == port ); } testI2dest.addr = resp.changedAddress.ipv4.addr; if (sAddr) { sAddr->port = testImappedAddr.port; sAddr->addr = testImappedAddr.addr; } count = 0; } respTestI=true; } break; case 2: { respTestII=true; } break; case 3: { respTestIII=true; } break; case 10: { if ( !respTestI2 ) { testI2mappedAddr.addr = resp.mappedAddress.ipv4.addr; testI2mappedAddr.port = resp.mappedAddress.ipv4.port; mappedIpSame = false; if ( (testI2mappedAddr.addr == testImappedAddr.addr ) && (testI2mappedAddr.port == testImappedAddr.port )) { mappedIpSame = true; } } respTestI2=true; } break; case 11: { if ( hairpin ) { *hairpin = true; } respTestHairpin = true; } break; } } } } } } // see if we can bind to this address //cerr << "try binding to " << testImappedAddr << endl; StunSocket s = openPort( 0/*use ephemeral*/, testImappedAddr.addr, false ); if ( s != INVALID_SOCKET ) { closesocket(s); isNat = false; //cerr << "binding worked" << endl; } else { isNat = true; //cerr << "binding failed" << endl; } closesocket(myFd1); closesocket(myFd2); if (verbose) { clog << "test I = " << respTestI << endl; clog << "test II = " << respTestII << endl; clog << "test III = " << respTestIII << endl; clog << "test I(2) = " << respTestI2 << endl; clog << "is nat = " << isNat <. * */ // Local Variables: // mode:c++ // c-file-style:"ellemtel" // c-file-offsets:((case-label . +)) // indent-tabs-mode:nil // End: twinkle-1.4.2/src/dialog.h0000644000175000001440000006432311143636535012326 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * SIP dialog established by an INVITE transaction. */ #ifndef _DIALOG_H #define _DIALOG_H #include #include #include #include #include "abstract_dialog.h" #include "client_request.h" #include "phone.h" #include "transaction_layer.h" #include "protocol.h" #include "redirect.h" #include "session.h" #include "user.h" #include "sockets/url.h" #include "threads/mutex.h" #include "parser/request.h" #include "sdp/sdp.h" #include "stun/stun.h" using namespace std; // Forward declarations class t_phone; class t_line; class t_session; class t_sub_refer; /** Dialog state */ enum t_dialog_state { DS_NULL, /**< Initial state */ // UAC states DS_W4INVITE_RESP, /**< INVITE sent, waiting for response */ DS_W4INVITE_RESP2, /**< Provisional response received */ DS_EARLY, /**< Provisional response with to-tag received */ DS_W4BYE_RESP, /**< BYE sent, waiting for response */ // UAS states DS_W4ACK, /**< Waiting for ACK on 2XX INVITE */ DS_W4ANSWER, /**< INVITE received, waiting for user to answer */ // UAS and UAC states DS_CONFIRMED, /**< Success received/sent */ DS_W4ACK_RE_INVITE, /**< Waiting for ACK on re-INVITE */ DS_W4RE_INVITE_RESP, /**< re-INVITE sent, waiting for response */ DS_W4RE_INVITE_RESP2, /**< re-INVITE sent, provisional response recvd */ DS_TERMINATED, /**< Dialog terminated */ // Subscription states DS_CONFIRMED_SUB, /**< Confirmed refer-subscription dialog */ }; /** Purpose for sending a re-INVITE request */ enum t_reinvite_purpose { REINVITE_HOLD, /**< Re-invite for call hold */ REINVITE_RETRIEVE, /**< Re-invite for call retrieve */ }; /** * SIP dialog established by an INVITE transaction. * * Dialog state diagrams: * @dot * digraph call { * label="Call setup and tear down state transitions" * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; * edge [fontname=Helvetica, fontsize=9]; * * null [label="DS_NULL" URL="\ref DS_NULL"]; * w4invite_resp [label="DS_W4INVITE_RESP" URL="\ref DS_W4INVITE_RESP"] * w4invite_resp2 [label="DS_W4INVITE_RESP2" URL="\ref DS_W4INVITE_RESP2"] * early [label="DS_EARLY" URL="\ref DS_EARLY"] * w4bye_resp [label="DS_W4BYE_RESP" URL="\ref DS_W4BYE_RESP"] * w4ack [label="DS_W4ACK" URL="\ref DS_W4ACK"] * w4answer [label="DS_W4ANSWER" URL="\ref DS_W4ANSWER"] * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] * * null -> w4invite_resp [label="send INVITE"] * null -> w4answer [label="receive INVITE"] * null -> terminated [label="receive INVITE\nSTUN media\nbind fails"] * null -> terminated [label="receive INVITE\nunsupported\nmedia or body"] * w4invite_resp -> w4invite_resp2 [label="receive 1XX without to-tag"] * w4invite_resp -> early [label="receive 1XX with to-tag"] * w4invite_resp -> confirmed [label="receive 2XX"] * w4invite_resp -> terminated [label="receive failure\nresponse"] * w4invite_resp2 -> confirmed [label="receive 2XX"] * w4invite_resp2 -> early [label="receive 1XX with to-tag"] * w4invite_resp2 -> terminated [label="receive failure\nresponse"] * early -> confirmed [label="receive 2XX"] * early -> terminated [label="receive failure\nresponse"] * w4answer -> w4ack [label="user answered, send 2XX"] * w4answer -> terminated [label="user rejected\nsend 4XX/6XX"] * w4answer -> terminated [label="receive CANCEL/BYE\nsend 487"] * w4ack -> confirmed [label="receive ACK"] * confirmed -> w4bye_resp [label="send BYE"] * confirmed -> terminated [label="receive BYE"] * w4bye_resp -> terminated [label="receive BYE response"] * } * @enddot * * @dot * digraph reinvite { * label="re-INVITE state transitions" * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; * edge [fontname=Helvetica, fontsize=9]; * * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] * w4ack_re_invite [label="DS_W4ACK_RE_INVITE" URL="\ref DS_W4ACK_RE_INVITE"] * w4re_invite_resp [label="DS_W4RE_INVITE_RESP" URL="\ref DS_W4RE_INVITE_RESP"] * w4re_invite_resp2 [label="DS_W4RE_INVITE_RESP2" URL="\ref DS_W4RE_INVITE_RESP2"] * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] * * confirmed -> w4ack_re_invite [label="receive re-INVITE, send 2XX"] * confirmed -> terminated [label="receive re-INVITE\nSTUN fails"] * confirmed -> confirmed [label="receive re-INVITE, send failure response"] * confirmed -> w4re_invite_resp [label="send re-INVITE"] * w4ack_re_invite -> confirmed [label="reveive ACK"] * w4re_invite_resp -> w4re_invite_resp2 [label="receive 1XX"] * w4re_invite_resp -> confirmed [label="receive final response"] * w4re_invite_resp2 -> confirmed [label="receive final response"] * w4re_invite_resp -> terminated [label="receive BYE"] * w4re_invite_resp2 -> terminated [label="receive BYE"] * } * @enddot * * @dot * digraph refer { * label="State transitions when REFER subscription is active" * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; * edge [fontname=Helvetica, fontsize=9]; * * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] * w4bye_resp [label="DS_W4BYE_RESP" URL="\ref DS_W4BYE_RESP"] * w4re_invite_resp [label="DS_W4RE_INVITE_RESP" URL="\ref DS_W4RE_INVITE_RESP"] * w4re_invite_resp2 [label="DS_W4RE_INVITE_RESP2" URL="\ref DS_W4RE_INVITE_RESP2"] * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] * confirmed_sub [label="DS_CONFIRMED_SUB" URL="DS_CONFIRMED_SUB"] * * confirmed -> confirmed_sub [label="receive BYE"] * w4re_invite_resp -> confirmed_sub [label="receive BYE"] * w4re_invite_resp2 -> confirmed_sub [label="receive BYE"] * w4bye_resp -> confirmed_sub [label="receive BYE response"] * confirmed_sub -> terminated [label="terminate subscription"] * } * @enddot * * @dot * digraph timeout { * label="State transitions due to timeouts" * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; * edge [fontname=Helvetica, fontsize=9]; * * w4answer [label="DS_W4ANSWER" URL="\ref DS_W4ANSWER"] * w4ack [label="DS_W4ACK" URL="\ref DS_W4ACK"] * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] * confirmed_sub [label="DS_CONFIRMED_SUB" URL="DS_CONFIRMED_SUB"] * * w4answer -> w4answer [label="LTMR_100REL_TIMEOUT\nretransmit 1XX" URL="LTMR_100REL_TIMEOUT"] * w4answer -> terminated [label="LTMR_100REL_GUARD\nsend 500" URL="LTMR_100REL_GUARD"] * w4ack -> w4ack [label="LTMR_ACK_TIMEOUT\nretransmit 2XX" URL="LTMR_ACK_TIMEOUT"] * w4ack -> confirmed [label="LTMR_ACK_GUARD\ntear down call" URL="LTMR_ACK_GUARD"] * confirmed_sub -> terminated [label="REFER subscription\ntimeout"] * } * @enddot */ class t_dialog : public t_abstract_dialog { friend class t_phone; protected: t_line *line; /**< Phone line owning this dialog. */ t_dialog_state state; /**< Dialog state. */ /** Session established by this dialog. */ t_session *session; /** * New session being established during re-invite. * When the re-INVITE transaction finishes successfully, then * this session information will override the general session. */ t_session *session_re_invite; /** The purpose of an outgoing re-INVITE request */ t_reinvite_purpose reinvite_purpose; /** Indicates if the last call hold action failed. */ bool hold_failed; t_client_request *req_out; /**< Pending outgoing non-INVITE request */ t_client_request *req_out_invite; /**< Pending outgoing INVITE */ t_client_request *req_in_invite; /**< Pending incoming INVITE */ t_client_request *req_cancel; /**< Pending outgoing CANCEL */ t_client_request *req_refer; /**< Pending outgoing REFER */ t_client_request *req_info; /**< Pending outgoing INFO */ /** * Last outgoing PRACK. While a PRACK is still pending a new 1xx * response might come in. A PRACK will be sent for this 1xx without * waiting for the response for the previous PRACK. */ t_client_request *req_prack; /** Pending STUN request */ t_client_request *req_stun; /** * Incoming request queue. A request may come in when it cannot be * served yet. Such a request is stored in the queue to be served * later. */ list inc_req_queue; /** Indication if request must be cancelled */ bool request_cancelled; /** * Indication that the dialog must be terminated after a 2XX * on an INVITE is received (e.g. when 2XX glares with CANCEL). */ bool end_after_2xx_invite; /** Indication that the dialog must be terminated after ACK. */ bool end_after_ack; /** * Indication that the user wants to answer the call. * Sending the answer must be delayed as we are still waiting for * a PRACK to acknowledge a 1xx containing SDP from the * far end (RFC 3262 3). */ bool answer_after_prack; /** Indication if 180 ringing has already been received */ bool ringing_received; /** Cached success response to INVITE needed for retransmission */ t_response *resp_invite; /** * Cached provisional response to INVITE needed for retransmission * when provisional responses are sent reliable (100rel) */ t_response *resp_1xx_invite; /** Cached ack needed for retransmission */ t_request *ack; /** Subscription created by REFER (RFC 3515) */ t_sub_refer *sub_refer; /** Queue of DTMF digits to be sent via INFO requests */ queue dtmf_queue; /** @name Process incoming responses */ //@{ /** * Process an incoming response in the @ref DS_W4INVITE_RESP state. * @param r The response * @param tuid Transaction user id * @param tid Transaction id */ void state_w4invite_resp(t_response *r, t_tuid tuid, t_tid tid); /** * Process an incoming response in the @ref DS_EARLY state. * @param r The response * @param tuid Transaction user id * @param tid Transaction id */ void state_early(t_response *r, t_tuid tuid, t_tid tid); /** * Process an incoming response in the @ref DS_W4BYE_RESP state. * @param r The response * @param tuid Transaction user id * @param tid Transaction id */ void state_w4bye_resp(t_response *r, t_tuid tuid, t_tid tid); /** * Process an incoming response in the @ref DS_CONFIRMED state. * @param r The response * @param tuid Transaction user id * @param tid Transaction id */ void state_confirmed_resp(t_response *r, t_tuid tuid, t_tid tid); /** * Process an incoming response in the @ref DS_W4RE_INVITE_RESP state. * @param r The response * @param tuid Transaction user id * @param tid Transaction id */ void state_w4re_invite_resp(t_response *r, t_tuid tuid, t_tid tid); //@} /** @name Process incoming requests */ //@{ /** * Process an incoming request in the @ref DS_NULL state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_null(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_W4ANSWER state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_w4answer(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_W4ACK state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_w4ack(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_W4ACK_RE_INVITE state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_w4ack_re_invite(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_W4RE_INVITE_RESP state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_w4re_invite_resp(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_W4BYE_RESP state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_w4bye_resp(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_CONFIRMED state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_confirmed(t_request *r, t_tuid tuid, t_tid tid); /** * Process an incoming request in the @ref DS_CONFIRMED_SUB state. * @param r The request * @param tuid Transaction user id * @param tid Transaction id */ void state_confirmed_sub(t_request *r, t_tuid tuid, t_tid tid); //@} /** @name Process requests in the confirmed state */ //@{ /** Proces incoming re-INVITE. */ void process_re_invite(t_request *r, t_tuid tuid, t_tid tid); /** Proces incoming REFER. */ void process_refer(t_request *r, t_tuid tuid, t_tid tid); /** Process incoming SUBSCRIBE (refer subscription). */ void process_subscribe(t_request *r, t_tuid tuid, t_tid tid); /** Process incoming NOTIFY (refer subscription). */ void process_notify(t_request *r, t_tuid tuid, t_tid tid); /** Process incoming INFO. */ void process_info(t_request *r, t_tuid tuid, t_tid tid); /** Process incoming MESSAGE. */ void process_message(t_request *r, t_tuid tuid, t_tid tid); //@} /** @name Process timeouts */ //@{ /** * Process timeout in @ref DS_W4INVITE_RESP state. * @param timer The expired timer. */ void state_w4invite_resp(t_line_timer timer); /** * Process timeout in @ref DS_EARLY state. * @param timer The expired timer. */ void state_early(t_line_timer timer); /** * Process timeout in @ref DS_W4ACK state. * @param timer The expired timer. */ void state_w4ack(t_line_timer timer); /** * Process timeout in @ref DS_W4ACK_RE_INVITE state. * @param timer The expired timer. */ void state_w4ack_re_invite(t_line_timer timer); /** * Process timeout in @ref DS_W4RE_INVITE_RESP state. * @param timer The expired timer. */ void state_w4re_invite_resp(t_line_timer timer); /** * Process timeout in @ref DS_W4ANSWER state. * @param timer The expired timer. */ void state_w4answer(t_line_timer timer); /** * Process timeout in @ref DS_CONFIRMED state. * @param timer The expired timer. */ void state_confirmed(t_line_timer timer); //@} /** Make the re-INVITE session the current session. */ void activate_new_session(void); /** * Process SDP answer in 1xx and 2xx responses if present. * Apply ringing tone for a 180 response. * Determine if call should be canceled due to unsupported * or missing SDP. * @param r The 1XX/2XX response. */ void process_1xx_2xx_invite_resp(t_response *r); /** * Acknowledge a reveived 2xx response on an INVITE. * @param r The 2XX response. */ void ack_2xx_invite(t_response *r); /** * Send PRACK if the response requires it. * @param r The response. */ void send_prack_if_required(t_response *r); /** * Determine if a reliable provisional repsonse must be discarded. * A provisional response must be discarded because it is a retransmission * or received out of order. * Initializes the remote response nr if the response is the * first response. * @param r The provisional response. * @return true, discard response. * @return false, otherwise */ bool must_discard_100rel(t_response *r); /** * Respond to an incoming PRACK. * @param r The incoming PRACK. * @param tuid Transaction user id * @param tid Transaction id * @return true, if a success response was given. * @return false if an error response was given. */ bool respond_prack(t_request *r, t_tuid tuid, t_tid tid); virtual void send_request(t_request *r, t_tuid tuid); public: /** @name Timer durations and timer id's */ //@{ unsigned long dur_ack_timeout; /**< @ref LTMR_ACK_TIMEOUT duration (ms) */ t_object_id id_ack_timeout; /**< @ref LTMR_ACK_TIMEOUT timer id */ t_object_id id_ack_guard; /**< @ref LTMR_ACK_GUARD timer id */ t_object_id id_re_invite_guard; /**< @ref LTMR_RE_INVITE_GUARD timer id */ t_object_id id_glare_retry; /**< @ref LTMR_GLARE_RETRY timer id */ t_object_id id_cancel_guard; /**< @ref LTMR_CANCEL_GUARD timer id */ //@} /** @name RFC 3262 100rel timers */ //@{ unsigned long dur_100rel_timeout; /**< @ref LTMR_100REL_TIMEOUT duration (ms) */ t_object_id id_100rel_timeout; /**< @ref LTMR_100REL_TIMEOUT timer id */ t_object_id id_100rel_guard; /**< @ref LTMR_100REL_GUARD timer id */ //@} /** Indicates if last incoming REFER was accepted. */ bool refer_accepted; /** Indicates if the call transfer triggered by the last outgoing REFER succeeded. */ bool refer_succeeded; /** Indicates if the last outgoing REFER request failed. */ bool out_refer_req_failed; /** * Indicates if this dialog is setup because the user told to do * so by a REFER. */ bool is_referred_call; /** State of an outgoing REFER. */ t_refer_state refer_state; /** * Constructor. * @param _line The line owning this dialog. */ t_dialog(t_line *_line); /** Destructor. */ virtual ~t_dialog(); virtual t_request *create_request(t_method m); virtual t_dialog *copy(void); /** * Send INIVTE request. * @param to_uri The URI to be used a request-URI and To header URI * @param to_display Display name for To header. * @param subject If not empty, this string will go into the Subject header. * @param hdr_referred_by The Reffered-By header to be put in the INVITE. * @param hdr_replaces The Replaces header to be put in the INVITE. * @param hdr_require Required extensions to be put in the Require header. * @param hdr_request_disposition Request-Disposition header to be put in the INVITE. * @param anonymous Inidicates if the INVITE should be sent anonymous. * * @pre Dialog is in @ref DS_NULL state. */ void send_invite(const t_url &to_uri, const string &to_display, const string &subject, const t_hdr_referred_by &hdr_referred_by, const t_hdr_replaces &hdr_replaces, const t_hdr_require &hdr_require, const t_hdr_request_disposition &hdr_request_disposition, bool anonymous); /** * Resend the INVITE with an authorization header containing credentials * for the challenge in the response. * @param resp, the response on the INVITE. * @return true, if resending succeeded. * @return false, if credentials could not be determined. * * @pre The response must be a 401 or 407. */ bool resend_invite_auth(t_response *resp); /** * Resend the INVITE because the far-end did not support all required * extensions. Extensions that could not be supported will not be * required this time. * @param resp The response in the INVITE. * @return true, if resending succeeded. * @return false, if far-end did not indicate which extensions are * unsupported. Or if a required extension could not be disabled. * * @pre The response must be a 420. */ bool resend_invite_unsupported(t_response *resp); /** * Redirect INVITE to the next destination. * @param resp The response on the INVITE. * @return true, if INIVTE was redirected succesfully. * @return false, if there is no next destination. * * @pre The response must be a 3XX. */ bool redirect_invite(t_response *resp); /** * Failover INVITE to the next destination from DNS lookup. * @return true, if INIVTE was succesfully sent. * @return false, if there is no next destination. */ bool failover_invite(void); /** Send BYE request. */ void send_bye(void); /** Send OPTIONS request. */ void send_options(void); /** * Send CANCEL request. * If an early dialog exists, then the CANCEL can be sent * right away as a response has been received for the INVITE. * Otherwise, the CANCEL will be sent as soon as an early dialog * is created. * @param early_dialog_exists Indicates if an early dialog exists. */ void send_cancel(bool early_dialog_exists); /** * Indicate that the dialog must be ended if a 2XX is received * on an INVITE. * @param on Set/clear indication. */ void set_end_after_2xx_invite(bool on); /** * Send re-INVITE. * @pre session_re_invite attribute contains the session * information for the re-INVITE. */ void send_re_invite(void); virtual bool resend_request_auth(t_response *resp); virtual bool redirect_request(t_response *resp); virtual bool failover_request(t_response *resp); /** * Hold call. * If rtp_only is false, then a re-INVITE will be sent. * @param rtponly Indicates if only the RTP streams should be stopped and * the soundcard freed without any SIP signaling. */ void hold(bool rtponly = false); /** Retrieve call (send re-INVITE if needed). */ void retrieve(void); /** Kill all RTP stream associated with this dialog. */ void kill_rtp(void); /** * Refer a call (send REFER). * @param uri URI of the refer target. * @param display Display name of the refer target. */ void send_refer(const t_url &uri, const string &display); /** * Send DTMF digit. * @param digit The digit. * @param inband Indicates if digit must be sent inband. * @param info Indicates if digit must be sent in a SIP INFO. * * @pre Either inband or info or none of the indicators is true. * @post If none of the indicators is true, then RFC 2833 is used. */ void send_dtmf(char digit, bool inband, bool info); /** * Create a binding for the media port via STUN. * @return true, if binding is created. * @return false, if binding cannot be created. */ bool stun_bind_media(void); /** @name Handle received events */ //@{ void recvd_response(t_response *r, t_tuid tuid, t_tid tid); void recvd_request(t_request *r, t_tuid tuid, t_tid tid); /** * Handle incoming CANCEL request. * @param r The CANCEL request. * @param cancel_tid Transaction id of the CANCEL transaction. * @param target_tid Transaction id of the transaction to be cancellerd. */ void recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid); /** * Handle incoming STUN response. * @param r The STUN response. * @param tuid Transaction user id * @param tid Transaction id */ void recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid); /** * Handle the response from the user on the question for refer * permission. This response is received on the dialog that received * the REFER before. * @param permission Permission response from the user. * @param r The REFER request that was received. */ void recvd_refer_permission(bool permission, t_request *r); //@} /** Answer a call (send 200 OK). */ void answer(void); /** * Reject a call. * @param code The response code to reject the call with. * @param reason A specific reason may be given to the error code. If no * reason is specified the default reason is used. * * @pre code >= 400 */ void reject(int code, string reason = ""); /** * Redirect a call. * @param code The response code to redirect the call with. * @param A specific reason may be give to the error code. If no * reason is specified the default reason is used. * @param destinations The list of redirect destinations in order of * preference. * * @pre code is 3XX. */ void redirect(const list &destinations, int code, string reason = ""); virtual bool match_response(t_response *r, t_tuid tuid); /** * Match STUN response with dialog. * @param r STUN response. * @param tuid Transaction user id * @return true, if response matches. * @return false, otherwise. */ bool match_response(StunMessage *r, t_tuid tuid); /** * Match CANCEL request with dialog. * @param r CANCEL request. * @param target_tid Transaction id of transaction to be cancelled. * @return true, if request matches. * @return false, otherwise. */ bool match_cancel(t_request *r, t_tid target_tid); /** * Check if an incoming INVITE is a retransmission. * @param r The INVITE request. * @return true, if INVITE is a retransmission. * @return false, otherwise. */ bool is_invite_retrans(t_request *r); /** Process a retransmission of an incoming INVITE. */ void process_invite_retrans(void); /** * Get the state of the dialog. * @return The dialog state. */ t_dialog_state get_state(void) const; /** * Process dialog timer timeout. * @param timer The timer that expired. */ void timeout(t_line_timer timer); /** * Process subcribe timer timeout (REFER subscription). * @param timer The timer that expired. * @param event_type Event type of the subscription. * @param event_id Event id of the subscription. */ void timeout_sub(t_subscribe_timer timer, const string &event_type, const string &event_id); /** * Get the phone that belongs to this dialog. * @return The phone object. */ t_phone *get_phone(void) const; /** * Get the line that belongs to this dialog. * @return The line object. */ t_line *get_line(void) const; /** * Get the session belonging to this dialog. * @return The session belonging to this dialog. * @return NULL if there is no session. */ t_session * get_session(void) const; /** * Get the audio session belonging to this dialog. * @return The audio session belonging to this dialog. * @return NULL if there is no audio session. */ t_audio_session *get_audio_session(void) const; /** * Check if the dialog has an acitve session. * @return true, if the dialog has an active session. * @return false, otherwise. */ bool has_active_session(void) const; /** * Notify the dialog of the progress of a reference. * @param r The response sent by the refer target. */ void notify_refer_progress(t_response *r); /** * Check if a dialog will be released. * @return true, if the dialog will be released. * @return false, otherwise. */ bool will_release(void) const; }; #endif twinkle-1.4.2/src/address_book.cpp0000644000175000001440000001046711130735732014054 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "address_book.h" #include "sys_settings.h" #include "translator.h" #include "userintf.h" #include "util.h" // Call history file #define ADDRESS_BOOK_FILE "twinkle.ab"; // Field seperator in call history file #define REC_SEPARATOR '|' //////////////////////////// // class t_address_card //////////////////////////// string t_address_card::get_display_name(void) const { string s; if (!name_first.empty()) { s = name_first; } if (!name_infix.empty()) { if (!s.empty()) s += ' '; s += name_infix; } if (!name_last.empty()) { if (!s.empty()) s += ' '; s += name_last; } return s; } bool t_address_card::create_file_record(vector &v) const { v.clear(); v.push_back(name_first); v.push_back(name_infix); v.push_back(name_last); v.push_back(sip_address); v.push_back(remark); return true; } bool t_address_card::populate_from_file_record(const vector &v) { // Check number of fields if (v.size() != 5) return false; name_first = v[0]; name_infix = v[1]; name_last = v[2]; sip_address = v[3]; remark = v[4]; return true; } bool t_address_card::operator==(const t_address_card other) const { return (name_first == other.name_first && name_infix == other.name_infix && name_last == other.name_last && sip_address == other.sip_address && remark == other.remark); } //////////////////////////// // class t_address_book //////////////////////////// // Private void t_address_book::find_address(t_user *user_config, const t_url &u) const { if (u == last_url) return; last_url = u; last_name.clear(); // Normalize url using number conversion rules t_url u_normalized(u); u_normalized.apply_conversion_rules(user_config); for (list::const_iterator i = records.begin(); i != records.end(); i++) { string full_address = ui->expand_destination(user_config, i->sip_address, u_normalized.get_scheme()); t_url url_phone(full_address); if (!url_phone.is_valid()) continue; if (u_normalized.user_host_match(url_phone, user_config->get_remove_special_phone_symbols(), user_config->get_special_phone_symbols())) { last_name = i->get_display_name(); return; } } } // Public t_address_book::t_address_book() : utils::t_record_file() { set_header("first_name|infix_name|last_name|sip_address|remark"); set_separator(REC_SEPARATOR); string s(DIR_HOME); s += "/"; s += USER_DIR; s += "/"; s += ADDRESS_BOOK_FILE; set_filename(s); } void t_address_book::add_address(const t_address_card &address) { mtx_records.lock(); records.push_back(address); mtx_records.unlock(); } bool t_address_book::del_address(const t_address_card &address) { mtx_records.lock(); list::iterator it = find(records.begin(), records.end(), address); if (it == records.end()) { mtx_records.unlock(); return false; } records.erase(it); // Invalidate the cache for the address finder last_url.set_url(""); mtx_records.unlock(); return true; } bool t_address_book::update_address(const t_address_card &old_address, const t_address_card &new_address) { mtx_records.lock(); if (!del_address(old_address)) { mtx_records.unlock(); return false; } records.push_back(new_address); mtx_records.unlock(); return true; } string t_address_book::find_name(t_user *user_config, const t_url &u) const { mtx_records.lock(); find_address(user_config, u); string name = last_name; mtx_records.unlock(); return name; } const list &t_address_book::get_address_list(void) const { return records; } twinkle-1.4.2/src/sub_refer.h0000644000175000001440000000405011127714045013025 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3515 // Refer event package #ifndef _SUB_REFER_H #define _SUB_REFER_H #include "subscription.h" #include "dialog.h" // State of reference as seen by the referrer enum t_sub_refer_result { SRR_INPROG, // Referee is referring call SRR_FAILED, // Refer failed SRR_SUCCEEDED, // Refer succeeded }; class t_sub_refer : public t_subscription { private: // Result of the reference as seen by the referrer. t_sub_refer_result sr_result; // Last response received from the refer-target t_response *last_response; // Current substate of the notification string current_substate; t_dialog *get_dialog(void) const; public: t_sub_refer(t_dialog *_dialog, t_subscription_role _role); t_sub_refer(t_dialog *_dialog, t_subscription_role _role, const string &_event_id); virtual ~t_sub_refer(); // Send a NOTIFY with the status line of the response as body // substate indicates the subscription state of refer // A reason should be given if substate == TERMINATED void send_notify(t_response *r, const string &substate, const string reason = ""); bool recv_notify(t_request *r, t_tuid tuid, t_tid tid); bool recv_subscribe(t_request *r, t_tuid tuid, t_tid tid); bool timeout(t_subscribe_timer timer); t_sub_refer_result get_sr_result(void) const; }; #endif twinkle-1.4.2/src/subscription_dialog.cpp0000644000175000001440000002554511127714054015463 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "subscription_dialog.h" #include #include "log.h" #include "phone.h" #include "phone_user.h" #include "protocol.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" extern t_phone *phone; extern string local_hostname; t_subscription_dialog::t_subscription_dialog(t_phone_user *_phone_user) : t_abstract_dialog(_phone_user), subscription(NULL) {} void t_subscription_dialog::send_request(t_request *r, t_tuid tuid) { t_user *user_config = phone_user->get_user_profile(); phone->send_request(user_config, r, tuid); } void t_subscription_dialog::process_subscribe(t_request *r, t_tuid tuid, t_tid tid) { if (get_subscription_state() == SS_NULL) { // Process initial incoming SUBSCRIBE. Create dialog state. // Set local tag if (r->hdr_to.tag.size() == 0) { local_tag = NEW_TAG; } else { local_tag = r->hdr_to.tag; } call_id = r->hdr_call_id.call_id; // Initialize local seqnr local_seqnr = NEW_SEQNR; local_resp_nr = NEW_SEQNR; remote_tag = r->hdr_from.tag; local_uri = r->hdr_to.uri; local_display = r->hdr_to.display; remote_uri = r->hdr_from.uri; remote_display = r->hdr_from.display; // Set remote target URI and display name remote_target_uri = r->hdr_contact.contact_list.front().uri; remote_target_display = r-> hdr_contact.contact_list.front().display; // Set route set if (r->hdr_record_route.is_populated()) { route_set = r->hdr_record_route.route_list; } } (void)subscription->recv_subscribe(r, tuid, tid); } void t_subscription_dialog::process_notify(t_request *r, t_tuid tuid, t_tid tid) { // RFC 3265 3.1.4.4 // A NOTIFY may be received before a 2XX response on the SUBSCRIBE. // If this happens, the remote information must be set using the // NOTIFY from header. if (remote_tag.empty()) { remote_tag = r->hdr_from.tag; remote_uri = r->hdr_from.uri; remote_display = r->hdr_from.display; } (void)subscription->recv_notify(r, tuid, tid); } bool t_subscription_dialog::process_initial_subscribe_response(t_response *r, t_tuid tuid, t_tid tid) { switch (r->get_class()) { case R_2XX: remote_tag = r->hdr_to.tag; remote_uri = r->hdr_to.uri; remote_display = r->hdr_to.display; create_route_set(r); create_remote_target(r); break; case R_4XX: if (r->code == R_423_INTERVAL_TOO_BRIEF) { if (!r->hdr_min_expires.is_populated()) { // Violation of RFC 3261 10.3 item 7 log_file->write_report("Expires header missing from 423 response.", "t_subscription_dialog::process_initial_subscribe_response", LOG_NORMAL, LOG_WARNING); break; } if (r->hdr_min_expires.time <= subscription->get_expiry()) { // Wrong Min-Expires time string s = "Min-Expires ("; s += ulong2str(r->hdr_min_expires.time); s += ") is smaller than the requested "; s += "time ("; s += ulong2str(subscription->get_expiry()); s += ")"; log_file->write_report(s, "t_subscription_dialog::process_initial_subscribe_response", LOG_NORMAL, LOG_WARNING); break; } // Subscribe with the advised interval subscribe(r->hdr_min_expires.time, remote_target_uri, remote_uri, remote_display); return true; } break; default: break; } return false; } t_subscription_dialog::~t_subscription_dialog() { if (subscription) { MEMMAN_DELETE(subscription); delete subscription; } } t_request *t_subscription_dialog::create_request(t_method m) { t_user *user_config = phone_user->get_user_profile(); t_request *r = t_abstract_dialog::create_request(m); // Contact header t_contact_param contact; switch (m) { case REFER: case SUBSCRIBE: case NOTIFY: // RFC 3265 7.1, RFC 3515 2.2 // Contact header is mandatory contact.uri.set_url(user_config->create_user_contact(false, h_ip2str(r->get_local_ip()))); r->hdr_contact.add_contact(contact); break; default: break; } return r; } bool t_subscription_dialog::resend_request_auth(t_response *resp) { t_client_request **current_cr = &(subscription->req_out); if (!*current_cr) return false; t_request *req = (*current_cr)->get_request(); if (phone_user->authorize(req, resp)) { resend_request(*current_cr); return true; } return false; } bool t_subscription_dialog::redirect_request(t_response *resp) { t_user *user_config = phone_user->get_user_profile(); t_client_request **current_cr = &(subscription->req_out); if (!*current_cr) return false; t_request *req = (*current_cr)->get_request(); // If the response is a 3XX response then add redirection // contacts if (resp->get_class() == R_3XX && resp->hdr_contact.is_populated()) { (*current_cr)->redirector.add_contacts( resp->hdr_contact.contact_list); } // Get next destination t_contact_param contact; if ((*current_cr)->redirector.get_next_contact(contact)) { // Ask user for permission to redirect if indicated // by user config bool permission = true; if (user_config->get_ask_user_to_redirect()) { permission = ui->cb_ask_user_to_redirect_request( user_config, contact.uri, contact.display, resp->hdr_cseq.method); } if (permission) { req->uri = contact.uri; req->calc_destinations(*user_config); ui->cb_redirecting_request(user_config, contact); resend_request(*current_cr); return true; } } return false; } bool t_subscription_dialog::failover_request(t_response *resp) { t_client_request **current_cr = &(subscription->req_out); if (!*current_cr) return false; t_request *req = (*current_cr)->get_request(); if (req->next_destination()) { log_file->write_report("Failover to next destination.", "t_subscription_dialog::handle_response_out_of_dialog"); resend_request(*current_cr); return true; } return false; } void t_subscription_dialog::recvd_response(t_response *r, t_tuid tuid, t_tid tid) { t_user *user_config = phone_user->get_user_profile(); t_abstract_dialog::recvd_response(r, tuid ,tid); t_client_request *cr = subscription->req_out; if (!cr) return; // Check cseq if (r->hdr_cseq.method != cr->get_request()->method) { return; } if (r->hdr_cseq.seqnr != cr->get_request()->hdr_cseq.seqnr) return; // Authentication if (r->must_authenticate()) { if (resend_request_auth(r)) { return; } // Authentication failed // Handle the 401/407 as a normal failure response } // RFC 3263 4.3 // Failover if (r->code == R_503_SERVICE_UNAVAILABLE) { if (failover_request(r)) { return; } } // Redirect failed request if there is another destination if (r->get_class() > R_2XX && user_config->get_allow_redirection()) { if (redirect_request(r)) { return; } } // Set the transaction identifier. This identifier is needed if the // transaction must be aborted at a later time. cr->set_tid(tid); switch (r->hdr_cseq.method) { case SUBSCRIBE: // Process response to initial SUBSCRIBE if (get_subscription_state() == SS_NULL) { if (process_initial_subscribe_response(r, tuid, tid)) { return; } } break; default: break; } (void)subscription->recv_response(r, tuid, tid); } void t_subscription_dialog::recvd_request(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_abstract_dialog::recvd_request(r, tuid, tid); // Check cseq // RFC 3261 12.2.2 if (remote_seqnr_set && r->hdr_cseq.seqnr <= remote_seqnr) { // Request received out of order. log_file->write_header("t_subscription_dialog::recvd_request", LOG_NORMAL, LOG_WARNING); log_file->write_raw("CSeq seqnr is out of sequence.\n"); log_file->write_raw("Reveived seqnr: "); log_file->write_raw(r->hdr_cseq.seqnr); log_file->write_endl(); log_file->write_raw("Remote seqnr: "); log_file->write_raw(remote_seqnr); log_file->write_endl(); log_file->write_footer(); resp = r->create_response(R_500_INTERNAL_SERVER_ERROR, "Request received out of order"); phone->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } remote_seqnr = r->hdr_cseq.seqnr; remote_seqnr_set = true; switch (r->method) { case SUBSCRIBE: process_subscribe(r, tuid, tid); break; case NOTIFY: process_notify(r, tuid, tid); break; default: // Other requests are not supported in a subscription dialog. resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); phone->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } } bool t_subscription_dialog::match_request(t_request *r, bool &partial) { if (!subscription->match(r)) return false; if (t_abstract_dialog::match_request(r)) { return true; } partial = t_abstract_dialog::match_partial_request(r); return false; } t_subscription_state t_subscription_dialog::get_subscription_state(void) const { return subscription->get_state(); } string t_subscription_dialog::get_reason_termination(void) const { return subscription->get_reason_termination(); } unsigned long t_subscription_dialog::get_resubscribe_after(void) const { return subscription->get_resubscribe_after(); } bool t_subscription_dialog::get_may_resubscribe(void) const { return subscription->get_may_resubscribe(); } bool t_subscription_dialog::timeout(t_subscribe_timer timer) { return subscription->timeout(timer); } bool t_subscription_dialog::match_timer(t_subscribe_timer timer, t_object_id id_timer) const { return subscription->match_timer(timer, id_timer); } void t_subscription_dialog::subscribe(unsigned long expires, const t_url &req_uri, const t_url &to_uri, const string &to_display) { t_user *user_config = phone_user->get_user_profile(); assert (get_subscription_state() == SS_NULL); call_id = NEW_CALL_ID(user_config); call_id_owner = true; local_tag = NEW_TAG; local_display = user_config->get_display(false); local_uri = user_config->create_user_uri(false); local_seqnr = rand() % 1000 + 1; remote_uri = to_uri; remote_display = to_display; remote_tag.clear(); remote_target_uri = req_uri; route_set = phone_user->get_service_route(); subscription->subscribe(expires); } void t_subscription_dialog::unsubscribe(void) { subscription->unsubscribe(); } void t_subscription_dialog::refresh_subscribe(void) { subscription->refresh_subscribe(); } twinkle-1.4.2/src/diamondcard.h0000644000175000001440000000424711147573536013340 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** @file * Diamondcard settings (www.diamondcard.us) */ #ifndef _DIAMONDCARD_H #define _DIAMONDCARD_H #include #include #include "user.h" #include "phone.h" #define DIAMONDCARD_DOMAIN "diamondcard.us" using namespace std; /** Actions that can be performed on the Diamondcard web site */ enum t_dc_action { DC_ACT_SIGNUP, DC_ACT_BALANCE_HISTORY, DC_ACT_RECHARGE, DC_ACT_CALL_HISTORY, DC_ACT_ADMIN_CENTER }; /** * Get the URL of a Diamondcard web page for an action. * @param action [in] Action for which the URL is requested. * @param displayName [in] The display name of the user. * @param accountId [in] Account ID of the user. N/A for signup. * @param pinCode [in] PIN code of the user. N/A for signup. * @return URL of the web page for the requested action. */ string diamondcard_url(t_dc_action action, const string &accountId, const string &pinCode); /** * Configure a user profile for a Diamondcard account. * @param user [inout] The user profile to configure. * @param accountId [in] Account ID of the user. * @param pinCode [in] PIN code of the user. */ void diamondcard_set_user_config(t_user &user, const string &displayName, const string &accountId, const string &pinCode); /** * Get all active Diamondcard users. * @return List of active Diamondcard users. */ listdiamondcard_get_users(t_phone *phone); #endif twinkle-1.4.2/src/id_object.h0000644000175000001440000000303011127714045012770 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Objects with a unique object id. */ #ifndef _ID_OBJECT_H #define _ID_OBJECT_H #include "threads/mutex.h" /** * Object identifier. */ typedef unsigned short t_object_id; /** * Parent class for objects that need a unique object id. */ class t_id_object { private: /** Mutex for concurrent object id creation. */ static t_mutex mtx_next_id; /** Id for the next object. */ static t_object_id next_id; /** Unique object identifier. */ t_object_id id; public: /** Constructor */ t_id_object(); /** * Get the object id. * @return Object id. */ t_object_id get_object_id(); /** * Generate a new object identifier. This can be useful * after making a copy of an object. */ void generate_new_id(); }; #endif twinkle-1.4.2/src/audio/0000777000175000001440000000000011151327733012067 500000000000000twinkle-1.4.2/src/audio/gsm/0000777000175000001440000000000011151327736012660 500000000000000twinkle-1.4.2/src/audio/gsm/inc/0000777000175000001440000000000011151327736013431 500000000000000twinkle-1.4.2/src/audio/gsm/inc/private.h0000644000175000001440000001715311127714045015173 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/private.h,v 1.6 1996/07/02 10:15:26 jutta Exp $*/ #ifndef PRIVATE_H #define PRIVATE_H typedef short word; /* 16 bit signed int */ typedef long longword; /* 32 bit signed int */ typedef unsigned short uword; /* unsigned word */ typedef unsigned long ulongword; /* unsigned longword */ struct gsm_state { word dp0[ 280 ]; word z1; /* preprocessing.c, Offset_com. */ longword L_z2; /* Offset_com. */ int mp; /* Preemphasis */ word u[8]; /* short_term_aly_filter.c */ word LARpp[2][8]; /* */ word j; /* */ word ltp_cut; /* long_term.c, LTP crosscorr. */ word nrp; /* 40 */ /* long_term.c, synthesis */ word v[9]; /* short_term.c, synthesis */ word msr; /* decoder.c, Postprocessing */ char verbose; /* only used if !NDEBUG */ char fast; /* only used if FAST */ char wav_fmt; /* only used if WAV49 defined */ unsigned char frame_index; /* odd/even chaining */ unsigned char frame_chain; /* half-byte to carry forward */ }; #define MIN_WORD (-32767 - 1) #define MAX_WORD 32767 #define MIN_LONGWORD (-2147483647 - 1) #define MAX_LONGWORD 2147483647 #ifdef SASR /* flag: >> is a signed arithmetic shift right */ #undef SASR #define SASR(x, by) ((x) >> (by)) #else #define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) #endif /* SASR */ #include "proto.h" /* * Prototypes from add.c */ extern word gsm_mult P((word a, word b)); extern longword gsm_L_mult P((word a, word b)); extern word gsm_mult_r P((word a, word b)); extern word gsm_div P((word num, word denum)); extern word gsm_add P(( word a, word b )); extern longword gsm_L_add P(( longword a, longword b )); extern word gsm_sub P((word a, word b)); extern longword gsm_L_sub P((longword a, longword b)); extern word gsm_abs P((word a)); extern word gsm_norm P(( longword a )); extern longword gsm_L_asl P((longword a, int n)); extern word gsm_asl P((word a, int n)); extern longword gsm_L_asr P((longword a, int n)); extern word gsm_asr P((word a, int n)); /* * Inlined functions from add.h */ /* * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) */ #define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) # define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ (SASR( ((longword)(a) * (longword)(b)), 15 )) # define GSM_L_MULT(a, b) /* word a, word b */ \ (((longword)(a) * (longword)(b)) << 1) # define GSM_L_ADD(a, b) \ ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ : ((b) <= 0 ? (a) + (b) \ : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ ? MAX_LONGWORD : utmp)) /* * # define GSM_ADD(a, b) \ * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) */ /* Nonportable, but faster: */ #define GSM_ADD(a, b) \ ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) # define GSM_SUB(a, b) \ ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) # define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) /* Use these if necessary: # define GSM_MULT_R(a, b) gsm_mult_r(a, b) # define GSM_MULT(a, b) gsm_mult(a, b) # define GSM_L_MULT(a, b) gsm_L_mult(a, b) # define GSM_L_ADD(a, b) gsm_L_add(a, b) # define GSM_ADD(a, b) gsm_add(a, b) # define GSM_SUB(a, b) gsm_sub(a, b) # define GSM_ABS(a) gsm_abs(a) */ /* * More prototypes from implementations.. */ extern void Gsm_Coder P(( struct gsm_state * S, word * s, /* [0..159] samples IN */ word * LARc, /* [0..7] LAR coefficients OUT */ word * Nc, /* [0..3] LTP lag OUT */ word * bc, /* [0..3] coded LTP gain OUT */ word * Mc, /* [0..3] RPE grid selection OUT */ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ word * xMc /* [13*4] normalized RPE samples OUT */)); extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ struct gsm_state * S, word * d, /* [0..39] residual signal IN */ word * dp, /* [-120..-1] d' IN */ word * e, /* [0..40] OUT */ word * dpp, /* [0..40] OUT */ word * Nc, /* correlation lag OUT */ word * bc /* gain factor OUT */)); extern void Gsm_LPC_Analysis P(( struct gsm_state * S, word * s, /* 0..159 signals IN/OUT */ word * LARc)); /* 0..7 LARc's OUT */ extern void Gsm_Preprocess P(( struct gsm_state * S, word * s, word * so)); extern void Gsm_Encoding P(( struct gsm_state * S, word * e, word * ep, word * xmaxc, word * Mc, word * xMc)); extern void Gsm_Short_Term_Analysis_Filter P(( struct gsm_state * S, word * LARc, /* coded log area ratio [0..7] IN */ word * d /* st res. signal [0..159] IN/OUT */)); extern void Gsm_Decoder P(( struct gsm_state * S, word * LARcr, /* [0..7] IN */ word * Ncr, /* [0..3] IN */ word * bcr, /* [0..3] IN */ word * Mcr, /* [0..3] IN */ word * xmaxcr, /* [0..3] IN */ word * xMcr, /* [0..13*4] IN */ word * s)); /* [0..159] OUT */ extern void Gsm_Decoding P(( struct gsm_state * S, word xmaxcr, word Mcr, word * xMcr, /* [0..12] IN */ word * erp)); /* [0..39] OUT */ extern void Gsm_Long_Term_Synthesis_Filtering P(( struct gsm_state* S, word Ncr, word bcr, word * erp, /* [0..39] IN */ word * drp)); /* [-120..-1] IN, [0..40] OUT */ void Gsm_RPE_Decoding P(( struct gsm_state *S, word xmaxcr, word Mcr, word * xMcr, /* [0..12], 3 bits IN */ word * erp)); /* [0..39] OUT */ void Gsm_RPE_Encoding P(( struct gsm_state * S, word * e, /* -5..-1][0..39][40..44 IN/OUT */ word * xmaxc, /* OUT */ word * Mc, /* OUT */ word * xMc)); /* [0..12] OUT */ extern void Gsm_Short_Term_Synthesis_Filter P(( struct gsm_state * S, word * LARcr, /* log area ratios [0..7] IN */ word * drp, /* received d [0...39] IN */ word * s)); /* signal s [0..159] OUT */ extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( word * dpp, /* [0...39] IN */ word * ep, /* [0...39] IN */ word * dp)); /* [-120...-1] IN/OUT */ /* * Tables from table.c */ #ifndef GSM_TABLE_C extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; extern word gsm_INVA[8]; extern word gsm_DLB[4], gsm_QLB[4]; extern word gsm_H[11]; extern word gsm_NRFAC[8]; extern word gsm_FAC[8]; #endif /* GSM_TABLE_C */ /* * Debugging */ #ifdef NDEBUG # define gsm_debug_words(a, b, c, d) /* nil */ # define gsm_debug_longwords(a, b, c, d) /* nil */ # define gsm_debug_word(a, b) /* nil */ # define gsm_debug_longword(a, b) /* nil */ #else /* !NDEBUG => DEBUG */ extern void gsm_debug_words P((char * name, int, int, word *)); extern void gsm_debug_longwords P((char * name, int, int, longword *)); extern void gsm_debug_longword P((char * name, longword)); extern void gsm_debug_word P((char * name, word)); #endif /* !NDEBUG */ #include "unproto.h" #endif /* PRIVATE_H */ twinkle-1.4.2/src/audio/gsm/inc/gsm.h0000644000175000001440000000322111127714045014276 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /home/kbs/jutta/src/gsm/gsm-1.0/inc/RCS/gsm.h,v 1.11 1996/07/05 18:02:56 jutta Exp $*/ #ifndef GSM_H #define GSM_H #ifdef __cplusplus # define NeedFunctionPrototypes 1 #endif #if __STDC__ # define NeedFunctionPrototypes 1 #endif #ifdef _NO_PROTO # undef NeedFunctionPrototypes #endif #ifdef NeedFunctionPrototypes # include /* for FILE * */ #endif #undef GSM_P #if NeedFunctionPrototypes # define GSM_P( protos ) protos #else # define GSM_P( protos ) ( /* protos */ ) #endif /* * Interface */ typedef struct gsm_state * gsm; typedef short gsm_signal; /* signed 16 bit */ typedef unsigned char gsm_byte; typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ #define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ #define GSM_PATCHLEVEL 10 #define GSM_MINOR 0 #define GSM_MAJOR 1 #define GSM_OPT_VERBOSE 1 #define GSM_OPT_FAST 2 #define GSM_OPT_LTP_CUT 3 #define GSM_OPT_WAV49 4 #define GSM_OPT_FRAME_INDEX 5 #define GSM_OPT_FRAME_CHAIN 6 extern gsm gsm_create GSM_P((void)); extern void gsm_destroy GSM_P((gsm)); extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); extern int gsm_option GSM_P((gsm, int, int *)); extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); #undef GSM_P #endif /* GSM_H */ twinkle-1.4.2/src/audio/gsm/inc/unproto.h0000644000175000001440000000073411127714045015224 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/unproto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/ #ifdef PROTO_H /* sic */ #undef PROTO_H #undef P #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 #undef P5 #undef P6 #undef P7 #undef P8 #endif /* PROTO_H */ twinkle-1.4.2/src/audio/gsm/inc/config.h0000644000175000001440000000256611127714045014770 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/ #ifndef CONFIG_H #define CONFIG_H /*efine SIGHANDLER_T int /* signal handlers are void */ /*efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */ #define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */ /*efine HAS_LIMITS_H 1 /* /usr/include/limits.h */ #define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */ /*efine HAS_ERRNO_DECL 1 /* errno.h declares errno */ #define HAS_FSTAT 1 /* fstat syscall */ #define HAS_FCHMOD 1 /* fchmod syscall */ #define HAS_CHMOD 1 /* chmod syscall */ #define HAS_FCHOWN 1 /* fchown syscall */ #define HAS_CHOWN 1 /* chown syscall */ /*efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */ #define HAS_STRING_H 1 /* /usr/include/string.h */ /*efine HAS_STRINGS_H 1 /* /usr/include/strings.h */ #define HAS_UNISTD_H 1 /* /usr/include/unistd.h */ #define HAS_UTIME 1 /* POSIX utime(path, times) */ /*efine HAS_UTIMES 1 /* use utimes() syscall instead */ #define HAS_UTIME_H 1 /* UTIME header file */ /*efine HAS_UTIMBUF 1 /* struct utimbuf */ /*efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */ #endif /* CONFIG_H */ twinkle-1.4.2/src/audio/gsm/inc/proto.h0000644000175000001440000000311311127714045014653 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/proto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/ #ifndef PROTO_H #define PROTO_H #if __cplusplus # define NeedFunctionPrototypes 1 #endif #if __STDC__ # define NeedFunctionPrototypes 1 #endif #ifdef _NO_PROTO # undef NeedFunctionPrototypes #endif #undef P /* gnu stdio.h actually defines this... */ #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 #undef P5 #undef P6 #undef P7 #undef P8 #if NeedFunctionPrototypes # define P( protos ) protos # define P0() (void) # define P1(x, a) (a) # define P2(x, a, b) (a, b) # define P3(x, a, b, c) (a, b, c) # define P4(x, a, b, c, d) (a, b, c, d) # define P5(x, a, b, c, d, e) (a, b, c, d, e) # define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) # define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) # define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) #else /* !NeedFunctionPrototypes */ # define P( protos ) ( /* protos */ ) # define P0() () # define P1(x, a) x a; # define P2(x, a, b) x a; b; # define P3(x, a, b, c) x a; b; c; # define P4(x, a, b, c, d) x a; b; c; d; # define P5(x, a, b, c, d, e) x a; b; c; d; e; # define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; # define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; # define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; #endif /* !NeedFunctionPrototypes */ #endif /* PROTO_H */ twinkle-1.4.2/src/audio/gsm/src/0000777000175000001440000000000011151327735013446 500000000000000twinkle-1.4.2/src/audio/gsm/src/gsm_destroy.cpp0000644000175000001440000000107511127714054016425 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */ #include "gsm.h" #include "config.h" #include "proto.h" #ifdef HAS_STDLIB_H # include #else # ifdef HAS_MALLOC_H # include # else extern void free(); # endif #endif void gsm_destroy P1((S), gsm S) { if (S) free((char *)S); } twinkle-1.4.2/src/audio/gsm/src/gsm_decode.cpp0000644000175000001440000002465611127714054016171 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_decode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; #ifdef WAV49 if (s->wav_fmt) { uword sr = 0; s->frame_index = !s->frame_index; if (s->frame_index) { sr = *c++; LARc[0] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 2; LARc[1] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 4; LARc[2] = sr & 0x1f; sr >>= 5; LARc[3] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 2; LARc[4] = sr & 0xf; sr >>= 4; LARc[5] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; /* 5 */ LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[0] = sr & 0x7f; sr >>= 7; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[0] = sr & 0x3f; sr >>= 6; xmc[0] = sr & 0x7; sr >>= 3; sr = *c++; xmc[1] = sr & 0x7; sr >>= 3; xmc[2] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; xmc[5] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 10 */ xmc[6] = sr & 0x7; sr >>= 3; xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; sr = *c++; xmc[9] = sr & 0x7; sr >>= 3; xmc[10] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[1] = sr & 0x7f; sr >>= 7; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[1] = sr & 0x3f; sr >>= 6; xmc[13] = sr & 0x7; sr >>= 3; sr = *c++; /* 15 */ xmc[14] = sr & 0x7; sr >>= 3; xmc[15] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; xmc[18] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[19] = sr & 0x7; sr >>= 3; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; sr = *c++; xmc[22] = sr & 0x7; sr >>= 3; xmc[23] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; /* 20 */ Nc[2] = sr & 0x7f; sr >>= 7; bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[2] = sr & 0x3f; sr >>= 6; xmc[26] = sr & 0x7; sr >>= 3; sr = *c++; xmc[27] = sr & 0x7; sr >>= 3; xmc[28] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; xmc[31] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[32] = sr & 0x7; sr >>= 3; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; sr = *c++; /* 25 */ xmc[35] = sr & 0x7; sr >>= 3; xmc[36] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[3] = sr & 0x7f; sr >>= 7; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[3] = sr & 0x3f; sr >>= 6; xmc[39] = sr & 0x7; sr >>= 3; sr = *c++; xmc[40] = sr & 0x7; sr >>= 3; xmc[41] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 30 */ xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; xmc[44] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[45] = sr & 0x7; sr >>= 3; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; sr = *c++; xmc[48] = sr & 0x7; sr >>= 3; xmc[49] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; s->frame_chain = sr & 0xf; } else { sr = s->frame_chain; sr |= (uword)*c++ << 4; /* 1 */ LARc[0] = sr & 0x3f; sr >>= 6; LARc[1] = sr & 0x3f; sr >>= 6; sr = *c++; LARc[2] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 3; LARc[3] = sr & 0x1f; sr >>= 5; LARc[4] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; LARc[5] = sr & 0xf; sr >>= 4; LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr = *c++; /* 5 */ Nc[0] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[0] = sr & 0x3f; sr >>= 6; xmc[0] = sr & 0x7; sr >>= 3; xmc[1] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[2] = sr & 0x7; sr >>= 3; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; sr = *c++; xmc[5] = sr & 0x7; sr >>= 3; xmc[6] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 10 */ xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; xmc[9] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[10] = sr & 0x7; sr >>= 3; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr = *c++; Nc[1] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[1] = sr & 0x3f; sr >>= 6; xmc[13] = sr & 0x7; sr >>= 3; xmc[14] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 15 */ xmc[15] = sr & 0x7; sr >>= 3; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; sr = *c++; xmc[18] = sr & 0x7; sr >>= 3; xmc[19] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; xmc[22] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[23] = sr & 0x7; sr >>= 3; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr = *c++; Nc[2] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; /* 20 */ bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[2] = sr & 0x3f; sr >>= 6; xmc[26] = sr & 0x7; sr >>= 3; xmc[27] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[28] = sr & 0x7; sr >>= 3; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; sr = *c++; xmc[31] = sr & 0x7; sr >>= 3; xmc[32] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; xmc[35] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 25 */ xmc[36] = sr & 0x7; sr >>= 3; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr = *c++; Nc[3] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[3] = sr & 0x3f; sr >>= 6; xmc[39] = sr & 0x7; sr >>= 3; xmc[40] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[41] = sr & 0x7; sr >>= 3; xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; sr = *c++; /* 30 */ xmc[44] = sr & 0x7; sr >>= 3; xmc[45] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; xmc[48] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[49] = sr & 0x7; sr >>= 3; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; } } else #endif { /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; Nc[0] = (*c >> 1) & 0x7F; bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; Mc[0] = (*c >> 5) & 0x3; xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; Nc[1] = (*c >> 1) & 0x7F; bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; Mc[1] = (*c >> 5) & 0x3; xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; Nc[2] = (*c >> 1) & 0x7F; bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; Mc[2] = (*c >> 5) & 0x3; xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; Nc[3] = (*c >> 1) & 0x7F; bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; Mc[3] = (*c >> 5) & 0x3; xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ } Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); return 0; } twinkle-1.4.2/src/audio/gsm/src/rpe.cpp0000644000175000001440000002547011127714054014661 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/rpe.c,v 1.3 1994/05/10 20:18:46 jutta Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* 4.2.13 .. 4.2.17 RPE ENCODING SECTION */ /* 4.2.13 */ static void Weighting_filter P2((e, x), register word * e, /* signal [-5..0.39.44] IN */ word * x /* signal [0..39] OUT */ ) /* * The coefficients of the weighting filter are stored in a table * (see table 4.4). The following scaling is used: * * H[0..10] = integer( real_H[ 0..10] * 8192 ); */ { /* word wt[ 50 ]; */ register longword L_result; register int k /* , i */ ; /* Initialization of a temporary working array wt[0...49] */ /* for (k = 0; k <= 4; k++) wt[k] = 0; * for (k = 5; k <= 44; k++) wt[k] = *e++; * for (k = 45; k <= 49; k++) wt[k] = 0; * * (e[-5..-1] and e[40..44] are allocated by the caller, * are initially zero and are not written anywhere.) */ e -= 5; /* Compute the signal x[0..39] */ for (k = 0; k <= 39; k++) { L_result = 8192 >> 1; /* for (i = 0; i <= 10; i++) { * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); * L_result = GSM_L_ADD( L_result, L_temp ); * } */ #undef STEP #define STEP( i, H ) (e[ k + i ] * (longword)H) /* Every one of these multiplications is done twice -- * but I don't see an elegant way to optimize this. * Do you? */ #ifdef STUPID_COMPILER L_result += STEP( 0, -134 ) ; L_result += STEP( 1, -374 ) ; /* + STEP( 2, 0 ) */ L_result += STEP( 3, 2054 ) ; L_result += STEP( 4, 5741 ) ; L_result += STEP( 5, 8192 ) ; L_result += STEP( 6, 5741 ) ; L_result += STEP( 7, 2054 ) ; /* + STEP( 8, 0 ) */ L_result += STEP( 9, -374 ) ; L_result += STEP( 10, -134 ) ; #else L_result += STEP( 0, -134 ) + STEP( 1, -374 ) /* + STEP( 2, 0 ) */ + STEP( 3, 2054 ) + STEP( 4, 5741 ) + STEP( 5, 8192 ) + STEP( 6, 5741 ) + STEP( 7, 2054 ) /* + STEP( 8, 0 ) */ + STEP( 9, -374 ) + STEP(10, -134 ) ; #endif /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) * * x[k] = SASR( L_result, 16 ); */ /* 2 adds vs. >>16 => 14, minus one shift to compensate for * those we lost when replacing L_MULT by '*'. */ L_result = SASR( L_result, 13 ); x[k] = ( L_result < MIN_WORD ? MIN_WORD : (L_result > MAX_WORD ? MAX_WORD : L_result )); } } /* 4.2.14 */ static void RPE_grid_selection P3((x,xM,Mc_out), word * x, /* [0..39] IN */ word * xM, /* [0..12] OUT */ word * Mc_out /* OUT */ ) /* * The signal x[0..39] is used to select the RPE grid which is * represented by Mc. */ { /* register word temp1; */ register int /* m, */ i; register longword L_result, L_temp; longword EM; /* xxx should be L_EM? */ word Mc; longword L_common_0_3; EM = 0; Mc = 0; /* for (m = 0; m <= 3; m++) { * L_result = 0; * * * for (i = 0; i <= 12; i++) { * * temp1 = SASR( x[m + 3*i], 2 ); * * assert(temp1 != MIN_WORD); * * L_temp = GSM_L_MULT( temp1, temp1 ); * L_result = GSM_L_ADD( L_temp, L_result ); * } * * if (L_result > EM) { * Mc = m; * EM = L_result; * } * } */ #undef STEP #define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ L_result += L_temp * L_temp; /* common part of 0 and 3 */ L_result = 0; STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); L_common_0_3 = L_result; /* i = 0 */ STEP( 0, 0 ); L_result <<= 1; /* implicit in L_MULT */ EM = L_result; /* i = 1 */ L_result = 0; STEP( 1, 0 ); STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); L_result <<= 1; if (L_result > EM) { Mc = 1; EM = L_result; } /* i = 2 */ L_result = 0; STEP( 2, 0 ); STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); L_result <<= 1; if (L_result > EM) { Mc = 2; EM = L_result; } /* i = 3 */ L_result = L_common_0_3; STEP( 3, 12 ); L_result <<= 1; if (L_result > EM) { Mc = 3; EM = L_result; } /**/ /* Down-sampling by a factor 3 to get the selected xM[0..12] * RPE sequence. */ for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; *Mc_out = Mc; } /* 4.12.15 */ static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), word xmaxc, /* IN */ word * exp_out, /* OUT */ word * mant_out ) /* OUT */ { word exp, mant; /* Compute exponent and mantissa of the decoded version of xmaxc */ exp = 0; if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; mant = xmaxc - (exp << 3); if (mant == 0) { exp = -4; mant = 7; } else { while (mant <= 7) { mant = mant << 1 | 1; exp--; } mant -= 8; } assert( exp >= -4 && exp <= 6 ); assert( mant >= 0 && mant <= 7 ); *exp_out = exp; *mant_out = mant; } static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), word * xM, /* [0..12] IN */ word * xMc, /* [0..12] OUT */ word * mant_out, /* OUT */ word * exp_out, /* OUT */ word * xmaxc_out /* OUT */ ) { int i, itest; word xmax, xmaxc, temp, temp1, temp2; word exp, mant; /* Find the maximum absolute value xmax of xM[0..12]. */ xmax = 0; for (i = 0; i <= 12; i++) { temp = xM[i]; temp = GSM_ABS(temp); if (temp > xmax) xmax = temp; } /* Qantizing and coding of xmax to get xmaxc. */ exp = 0; temp = SASR( xmax, 9 ); itest = 0; for (i = 0; i <= 5; i++) { itest |= (temp <= 0); temp = SASR( temp, 1 ); assert(exp <= 5); if (itest == 0) exp++; /* exp = add (exp, 1) */ } assert(exp <= 6 && exp >= 0); temp = exp + 5; assert(temp <= 11 && temp >= 0); xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); /* Quantizing and coding of the xM[0..12] RPE sequence * to get the xMc[0..12] */ APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); /* This computation uses the fact that the decoded version of xmaxc * can be calculated by using the exponent and the mantissa part of * xmaxc (logarithmic table). * So, this method avoids any division and uses only a scaling * of the RPE samples by a function of the exponent. A direct * multiplication by the inverse of the mantissa (NRFAC[0..7] * found in table 4.5) gives the 3 bit coded version xMc[0..12] * of the RPE samples. */ /* Direct computation of xMc[0..12] using table 4.5 */ assert( exp <= 4096 && exp >= -4096); assert( mant >= 0 && mant <= 7 ); temp1 = 6 - exp; /* normalization by the exponent */ temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ for (i = 0; i <= 12; i++) { assert(temp1 >= 0 && temp1 < 16); temp = xM[i] << temp1; temp = GSM_MULT( temp, temp2 ); temp = SASR(temp, 12); xMc[i] = temp + 4; /* see note below */ } /* NOTE: This equation is used to make all the xMc[i] positive. */ *mant_out = mant; *exp_out = exp; *xmaxc_out = xmaxc; } /* 4.2.16 */ static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), register word * xMc, /* [0..12] IN */ word mant, word exp, register word * xMp) /* [0..12] OUT */ /* * This part is for decoding the RPE sequence of coded xMc[0..12] * samples to obtain the xMp[0..12] array. Table 4.6 is used to get * the mantissa of xmaxc (FAC[0..7]). */ { int i; word temp, temp1, temp2, temp3; longword ltmp; assert( mant >= 0 && mant <= 7 ); temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); for (i = 13; i--;) { assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */ /* temp = gsm_sub( *xMc++ << 1, 7 ); */ temp = (*xMc++ << 1) - 7; /* restore sign */ assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */ temp <<= 12; /* 16 bit signed */ temp = GSM_MULT_R( temp1, temp ); temp = GSM_ADD( temp, temp3 ); *xMp++ = gsm_asr( temp, temp2 ); } } /* 4.2.17 */ static void RPE_grid_positioning P3((Mc,xMp,ep), word Mc, /* grid position IN */ register word * xMp, /* [0..12] IN */ register word * ep /* [0..39] OUT */ ) /* * This procedure computes the reconstructed long term residual signal * ep[0..39] for the LTP analysis filter. The inputs are the Mc * which is the grid position selection and the xMp[0..12] decoded * RPE samples which are upsampled by a factor of 3 by inserting zero * values. */ { int i = 13; assert(0 <= Mc && Mc <= 3); switch (Mc) { case 3: *ep++ = 0; case 2: do { *ep++ = 0; case 1: *ep++ = 0; case 0: *ep++ = *xMp++; } while (--i); } while (++Mc < 4) *ep++ = 0; /* int i, k; for (k = 0; k <= 39; k++) ep[k] = 0; for (i = 0; i <= 12; i++) { ep[ Mc + (3*i) ] = xMp[i]; } */ } /* 4.2.18 */ /* This procedure adds the reconstructed long term residual signal * ep[0..39] to the estimated signal dpp[0..39] from the long term * analysis filter to compute the reconstructed short term residual * signal dp[-40..-1]; also the reconstructed short term residual * array dp[-120..-41] is updated. */ #if 0 /* Has been inlined in code.c */ void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), word * dpp, /* [0...39] IN */ word * ep, /* [0...39] IN */ word * dp) /* [-120...-1] IN/OUT */ { int k; for (k = 0; k <= 79; k++) dp[ -120 + k ] = dp[ -80 + k ]; for (k = 0; k <= 39; k++) dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); } #endif /* Has been inlined in code.c */ void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), struct gsm_state * S, word * e, /* -5..-1][0..39][40..44 IN/OUT */ word * xmaxc, /* OUT */ word * Mc, /* OUT */ word * xMc) /* [0..12] OUT */ { word x[40]; word xM[13], xMp[13]; word mant, exp; Weighting_filter(e, x); RPE_grid_selection(x, xM, Mc); APCM_quantization( xM, xMc, &mant, &exp, xmaxc); APCM_inverse_quantization( xMc, mant, exp, xMp); RPE_grid_positioning( *Mc, xMp, e ); } void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), struct gsm_state * S, word xmaxcr, word Mcr, word * xMcr, /* [0..12], 3 bits IN */ word * erp /* [0..39] OUT */ ) { word exp, mant; word xMp[ 13 ]; APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); APCM_inverse_quantization( xMcr, mant, exp, xMp ); RPE_grid_positioning( Mcr, xMp, erp ); } twinkle-1.4.2/src/audio/gsm/src/debug.cpp0000644000175000001440000000301411127714054015147 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/debug.c,v 1.2 1993/01/29 18:22:20 jutta Exp $ */ #include "private.h" #ifndef NDEBUG /* If NDEBUG _is_ defined and no debugging should be performed, * calls to functions in this module are #defined to nothing * in private.h. */ #include #include "proto.h" void gsm_debug_words P4( (name, from, to, ptr), char * name, int from, int to, word * ptr) { int nprinted = 0; fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); while (from <= to) { fprintf(stderr, "%d ", ptr[ from ] ); from++; if (nprinted++ >= 7) { nprinted = 0; if (from < to) putc('\n', stderr); } } putc('\n', stderr); } void gsm_debug_longwords P4( (name, from, to, ptr), char * name, int from, int to, longword * ptr) { int nprinted = 0; fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); while (from <= to) { fprintf(stderr, "%d ", ptr[ from ] ); from++; if (nprinted++ >= 7) { nprinted = 0; if (from < to) putc('\n', stderr); } } putc('\n', stderr); } void gsm_debug_longword P2( (name, value), char * name, longword value ) { fprintf(stderr, "%s: %d\n", name, (long)value ); } void gsm_debug_word P2( (name, value), char * name, word value ) { fprintf(stderr, "%s: %d\n", name, (long)value); } #endif twinkle-1.4.2/src/audio/gsm/src/code.cpp0000644000175000001440000000501511127714054014776 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */ #include "config.h" #include #ifdef HAS_STDLIB_H #include #else # include "proto.h" extern char * memcpy P((char *, char *, int)); #endif #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER */ void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc), struct gsm_state * S, word * s, /* [0..159] samples IN */ /* * The RPE-LTD coder works on a frame by frame basis. The length of * the frame is equal to 160 samples. Some computations are done * once per frame to produce at the output of the coder the * LARc[1..8] parameters which are the coded LAR coefficients and * also to realize the inverse filtering operation for the entire * frame (160 samples of signal d[0..159]). These parts produce at * the output of the coder: */ word * LARc, /* [0..7] LAR coefficients OUT */ /* * Procedure 4.2.11 to 4.2.18 are to be executed four times per * frame. That means once for each sub-segment RPE-LTP analysis of * 40 samples. These parts produce at the output of the coder: */ word * Nc, /* [0..3] LTP lag OUT */ word * bc, /* [0..3] coded LTP gain OUT */ word * Mc, /* [0..3] RPE grid selection OUT */ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ word * xMc /* [13*4] normalized RPE samples OUT */ ) { int k; word * dp = S->dp0 + 120; /* [ -120...-1 ] */ word * dpp = dp; /* [ 0...39 ] */ static word e[50]; word so[160]; Gsm_Preprocess (S, s, so); Gsm_LPC_Analysis (S, so, LARc); Gsm_Short_Term_Analysis_Filter (S, LARc, so); for (k = 0; k <= 3; k++, xMc += 13) { Gsm_Long_Term_Predictor ( S, so+k*40, /* d [0..39] IN */ dp, /* dp [-120..-1] IN */ e + 5, /* e [0..39] OUT */ dpp, /* dpp [0..39] OUT */ Nc++, bc++); Gsm_RPE_Encoding ( S, e + 5, /* e ][0..39][ IN/OUT */ xmaxc++, Mc++, xMc ); /* * Gsm_Update_of_reconstructed_short_time_residual_signal * ( dpp, e + 5, dp ); */ { register int i; register longword ltmp; for (i = 0; i <= 39; i++) dp[ i ] = GSM_ADD( e[5 + i], dpp[i] ); } dp += 40; dpp += 40; } (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), 120 * sizeof(*S->dp0) ); } twinkle-1.4.2/src/audio/gsm/src/lpc.cpp0000644000175000001440000001566511127714054014656 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" #undef P /* * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION */ /* 4.2.4 */ static void Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ longword * L_ACF) /* [0..8] OUT */ /* * The goal is to compute the array L_ACF[k]. The signal s[i] must * be scaled in order to avoid an overflow situation. */ { register int k, i; word temp, smax, scalauto; #ifdef USE_FLOAT_MUL float float_s[160]; #endif /* Dynamic scaling of the array s[0..159] */ /* Search for the maximum. */ smax = 0; for (k = 0; k <= 159; k++) { temp = GSM_ABS( s[k] ); if (temp > smax) smax = temp; } /* Computation of the scaling factor. */ if (smax == 0) scalauto = 0; else { assert(smax > 0); scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ } /* Scaling of the array s[0...159] */ if (scalauto > 0) { # ifdef USE_FLOAT_MUL # define SCALE(n) \ case n: for (k = 0; k <= 159; k++) \ float_s[k] = (float) \ (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ break; # else # define SCALE(n) \ case n: for (k = 0; k <= 159; k++) \ s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ break; # endif /* USE_FLOAT_MUL */ switch (scalauto) { SCALE(1) SCALE(2) SCALE(3) SCALE(4) } # undef SCALE } # ifdef USE_FLOAT_MUL else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; # endif /* Compute the L_ACF[..]. */ { # ifdef USE_FLOAT_MUL register float * sp = float_s; register float sl = *sp; # define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); # else word * sp = s; word sl = *sp; # define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); # endif # define NEXTI sl = *++sp for (k = 9; k--; L_ACF[k] = 0) ; STEP (0); NEXTI; STEP(0); STEP(1); NEXTI; STEP(0); STEP(1); STEP(2); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); for (i = 8; i <= 159; i++) { NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); STEP(8); } for (k = 9; k--; L_ACF[k] <<= 1) ; } /* Rescaling of the array s[0..159] */ if (scalauto > 0) { assert(scalauto <= 4); for (k = 160; k--; *s++ <<= scalauto) ; } } #if defined(USE_FLOAT_MUL) && defined(FAST) static void Fast_Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ longword * L_ACF) /* [0..8] OUT */ { register int k, i; float f_L_ACF[9]; float scale; float s_f[160]; register float *sf = s_f; for (i = 0; i < 160; ++i) sf[i] = s[i]; for (k = 0; k <= 8; k++) { register float L_temp2 = 0; register float *sfl = sf - k; for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; f_L_ACF[k] = L_temp2; } scale = MAX_LONGWORD / f_L_ACF[0]; for (k = 0; k <= 8; k++) { L_ACF[k] = f_L_ACF[k] * scale; } } #endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ /* 4.2.5 */ static void Reflection_coefficients P2( (L_ACF, r), longword * L_ACF, /* 0...8 IN */ register word * r /* 0...7 OUT */ ) { register int i, m, n; register word temp; register longword ltmp; word ACF[9]; /* 0..8 */ word P[ 9]; /* 0..8 */ word K[ 9]; /* 2..8 */ /* Schur recursion with 16 bits arithmetic. */ if (L_ACF[0] == 0) { for (i = 8; i--; *r++ = 0) ; return; } assert( L_ACF[0] != 0 ); temp = gsm_norm( L_ACF[0] ); assert(temp >= 0 && temp < 32); /* ? overflow ? */ for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); /* Initialize array P[..] and K[..] for the recursion. */ for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; /* Compute reflection coefficients */ for (n = 1; n <= 8; n++, r++) { temp = P[1]; temp = GSM_ABS(temp); if (P[0] < temp) { for (i = n; i <= 8; i++) *r++ = 0; return; } *r = gsm_div( temp, P[0] ); assert(*r >= 0); if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ assert (*r != MIN_WORD); if (n == 8) return; /* Schur recursion */ temp = GSM_MULT_R( P[1], *r ); P[0] = GSM_ADD( P[0], temp ); for (m = 1; m <= 8 - n; m++) { temp = GSM_MULT_R( K[ m ], *r ); P[m] = GSM_ADD( P[ m+1 ], temp ); temp = GSM_MULT_R( P[ m+1 ], *r ); K[m] = GSM_ADD( K[ m ], temp ); } } } /* 4.2.6 */ static void Transformation_to_Log_Area_Ratios P1((r), register word * r /* 0..7 IN/OUT */ ) /* * The following scaling for r[..] and LAR[..] has been used: * * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. * LAR[..] = integer( real_LAR[..] * 16384 ); * with -1.625 <= real_LAR <= 1.625 */ { register word temp; register int i; /* Computation of the LAR[0..7] from the r[0..7] */ for (i = 1; i <= 8; i++, r++) { temp = *r; temp = GSM_ABS(temp); assert(temp >= 0); if (temp < 22118) { temp >>= 1; } else if (temp < 31130) { assert( temp >= 11059 ); temp -= 11059; } else { assert( temp >= 26112 ); temp -= 26112; temp <<= 2; } *r = *r < 0 ? -temp : temp; assert( *r != MIN_WORD ); } } /* 4.2.7 */ static void Quantization_and_coding P1((LAR), register word * LAR /* [0..7] IN/OUT */ ) { register word temp; longword ltmp; /* This procedure needs four tables; the following equations * give the optimum scaling for the constants: * * A[0..7] = integer( real_A[0..7] * 1024 ) * B[0..7] = integer( real_B[0..7] * 512 ) * MAC[0..7] = maximum of the LARc[0..7] * MIC[0..7] = minimum of the LARc[0..7] */ # undef STEP # define STEP( A, B, MAC, MIC ) \ temp = GSM_MULT( A, *LAR ); \ temp = GSM_ADD( temp, B ); \ temp = GSM_ADD( temp, 256 ); \ temp = SASR( temp, 9 ); \ *LAR = temp>MAC ? MAC - MIC : (tempfast) Fast_Autocorrelation (s, L_ACF ); else #endif Autocorrelation (s, L_ACF ); Reflection_coefficients (L_ACF, LARc ); Transformation_to_Log_Area_Ratios (LARc); Quantization_and_coding (LARc); } twinkle-1.4.2/src/audio/gsm/src/gsm_explode.cpp0000644000175000001440000002564611127714054016406 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_explode.c,v 1.2 1996/07/02 14:32:42 jutta Exp jutta $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) { # define LARc target # define Nc *((gsm_signal (*) [17])(target + 8)) # define bc *((gsm_signal (*) [17])(target + 9)) # define Mc *((gsm_signal (*) [17])(target + 10)) # define xmaxc *((gsm_signal (*) [17])(target + 11)) #ifdef WAV49 if (s->wav_fmt) { uword sr = 0; if (s->frame_index == 1) { sr = *c++; LARc[0] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 2; LARc[1] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 4; LARc[2] = sr & 0x1f; sr >>= 5; LARc[3] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 2; LARc[4] = sr & 0xf; sr >>= 4; LARc[5] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; /* 5 */ LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[0] = sr & 0x7f; sr >>= 7; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[0] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 12) xmc[0] = sr & 0x7; sr >>= 3; sr = *c++; xmc[1] = sr & 0x7; sr >>= 3; xmc[2] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; xmc[5] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 10 */ xmc[6] = sr & 0x7; sr >>= 3; xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; sr = *c++; xmc[9] = sr & 0x7; sr >>= 3; xmc[10] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[1] = sr & 0x7f; sr >>= 7; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[1] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 29 - 13) xmc[13] = sr & 0x7; sr >>= 3; sr = *c++; /* 15 */ xmc[14] = sr & 0x7; sr >>= 3; xmc[15] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; xmc[18] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[19] = sr & 0x7; sr >>= 3; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; sr = *c++; xmc[22] = sr & 0x7; sr >>= 3; xmc[23] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; /* 20 */ Nc[2] = sr & 0x7f; sr >>= 7; bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[2] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 46 - 26) xmc[26] = sr & 0x7; sr >>= 3; sr = *c++; xmc[27] = sr & 0x7; sr >>= 3; xmc[28] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; xmc[31] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[32] = sr & 0x7; sr >>= 3; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; sr = *c++; /* 25 */ xmc[35] = sr & 0x7; sr >>= 3; xmc[36] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[3] = sr & 0x7f; sr >>= 7; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[3] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 63 - 39) xmc[39] = sr & 0x7; sr >>= 3; sr = *c++; xmc[40] = sr & 0x7; sr >>= 3; xmc[41] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 30 */ xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; xmc[44] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[45] = sr & 0x7; sr >>= 3; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; sr = *c++; xmc[48] = sr & 0x7; sr >>= 3; xmc[49] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; s->frame_chain = sr & 0xf; } else { sr = s->frame_chain; sr |= (uword)*c++ << 4; /* 1 */ LARc[0] = sr & 0x3f; sr >>= 6; LARc[1] = sr & 0x3f; sr >>= 6; sr = *c++; LARc[2] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 3; LARc[3] = sr & 0x1f; sr >>= 5; LARc[4] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; LARc[5] = sr & 0xf; sr >>= 4; LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr = *c++; /* 5 */ Nc[0] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[0] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 12) xmc[0] = sr & 0x7; sr >>= 3; xmc[1] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[2] = sr & 0x7; sr >>= 3; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; sr = *c++; xmc[5] = sr & 0x7; sr >>= 3; xmc[6] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 10 */ xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; xmc[9] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[10] = sr & 0x7; sr >>= 3; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr = *c++; Nc[1] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[1] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 29 - 13) xmc[13] = sr & 0x7; sr >>= 3; xmc[14] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 15 */ xmc[15] = sr & 0x7; sr >>= 3; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; sr = *c++; xmc[18] = sr & 0x7; sr >>= 3; xmc[19] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; xmc[22] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[23] = sr & 0x7; sr >>= 3; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr = *c++; Nc[2] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; /* 20 */ bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[2] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 46 - 26) xmc[26] = sr & 0x7; sr >>= 3; xmc[27] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[28] = sr & 0x7; sr >>= 3; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; sr = *c++; xmc[31] = sr & 0x7; sr >>= 3; xmc[32] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; xmc[35] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 25 */ xmc[36] = sr & 0x7; sr >>= 3; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr = *c++; Nc[3] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[3] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (target + 63 - 39) xmc[39] = sr & 0x7; sr >>= 3; xmc[40] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[41] = sr & 0x7; sr >>= 3; xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; sr = *c++; /* 30 */ xmc[44] = sr & 0x7; sr >>= 3; xmc[45] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; xmc[48] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[49] = sr & 0x7; sr >>= 3; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; } } else #endif { /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; Nc[0] = (*c >> 1) & 0x7F; bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; Mc[0] = (*c >> 5) & 0x3; xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 12) xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; Nc[1] = (*c >> 1) & 0x7F; bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; Mc[1] = (*c >> 5) & 0x3; xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 29 - 13) xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; Nc[2] = (*c >> 1) & 0x7F; bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; Mc[2] = (*c >> 5) & 0x3; xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 46 - 26) xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; Nc[3] = (*c >> 1) & 0x7F; bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; Mc[3] = (*c >> 5) & 0x3; xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 63 - 39) xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ } return 0; } twinkle-1.4.2/src/audio/gsm/src/gsm_encode.cpp0000644000175000001440000002624611127714054016200 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_encode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); /* variable size GSM_MAGIC 4 LARc[0] 6 LARc[1] 6 LARc[2] 5 LARc[3] 5 LARc[4] 4 LARc[5] 4 LARc[6] 3 LARc[7] 3 Nc[0] 7 bc[0] 2 Mc[0] 2 xmaxc[0] 6 xmc[0] 3 xmc[1] 3 xmc[2] 3 xmc[3] 3 xmc[4] 3 xmc[5] 3 xmc[6] 3 xmc[7] 3 xmc[8] 3 xmc[9] 3 xmc[10] 3 xmc[11] 3 xmc[12] 3 Nc[1] 7 bc[1] 2 Mc[1] 2 xmaxc[1] 6 xmc[13] 3 xmc[14] 3 xmc[15] 3 xmc[16] 3 xmc[17] 3 xmc[18] 3 xmc[19] 3 xmc[20] 3 xmc[21] 3 xmc[22] 3 xmc[23] 3 xmc[24] 3 xmc[25] 3 Nc[2] 7 bc[2] 2 Mc[2] 2 xmaxc[2] 6 xmc[26] 3 xmc[27] 3 xmc[28] 3 xmc[29] 3 xmc[30] 3 xmc[31] 3 xmc[32] 3 xmc[33] 3 xmc[34] 3 xmc[35] 3 xmc[36] 3 xmc[37] 3 xmc[38] 3 Nc[3] 7 bc[3] 2 Mc[3] 2 xmaxc[3] 6 xmc[39] 3 xmc[40] 3 xmc[41] 3 xmc[42] 3 xmc[43] 3 xmc[44] 3 xmc[45] 3 xmc[46] 3 xmc[47] 3 xmc[48] 3 xmc[49] 3 xmc[50] 3 xmc[51] 3 */ #ifdef WAV49 if (s->wav_fmt) { s->frame_index = !s->frame_index; if (s->frame_index) { uword sr; sr = 0; sr = sr >> 6 | LARc[0] << 10; sr = sr >> 6 | LARc[1] << 10; *c++ = sr >> 4; sr = sr >> 5 | LARc[2] << 11; *c++ = sr >> 7; sr = sr >> 5 | LARc[3] << 11; sr = sr >> 4 | LARc[4] << 12; *c++ = sr >> 6; sr = sr >> 4 | LARc[5] << 12; sr = sr >> 3 | LARc[6] << 13; *c++ = sr >> 7; sr = sr >> 3 | LARc[7] << 13; sr = sr >> 7 | Nc[0] << 9; *c++ = sr >> 5; sr = sr >> 2 | bc[0] << 14; sr = sr >> 2 | Mc[0] << 14; sr = sr >> 6 | xmaxc[0] << 10; *c++ = sr >> 3; sr = sr >> 3 | xmc[0] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[1] << 13; sr = sr >> 3 | xmc[2] << 13; sr = sr >> 3 | xmc[3] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[4] << 13; sr = sr >> 3 | xmc[5] << 13; sr = sr >> 3 | xmc[6] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[7] << 13; sr = sr >> 3 | xmc[8] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[9] << 13; sr = sr >> 3 | xmc[10] << 13; sr = sr >> 3 | xmc[11] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[12] << 13; sr = sr >> 7 | Nc[1] << 9; *c++ = sr >> 5; sr = sr >> 2 | bc[1] << 14; sr = sr >> 2 | Mc[1] << 14; sr = sr >> 6 | xmaxc[1] << 10; *c++ = sr >> 3; sr = sr >> 3 | xmc[13] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[14] << 13; sr = sr >> 3 | xmc[15] << 13; sr = sr >> 3 | xmc[16] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[17] << 13; sr = sr >> 3 | xmc[18] << 13; sr = sr >> 3 | xmc[19] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[20] << 13; sr = sr >> 3 | xmc[21] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[22] << 13; sr = sr >> 3 | xmc[23] << 13; sr = sr >> 3 | xmc[24] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[25] << 13; sr = sr >> 7 | Nc[2] << 9; *c++ = sr >> 5; sr = sr >> 2 | bc[2] << 14; sr = sr >> 2 | Mc[2] << 14; sr = sr >> 6 | xmaxc[2] << 10; *c++ = sr >> 3; sr = sr >> 3 | xmc[26] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[27] << 13; sr = sr >> 3 | xmc[28] << 13; sr = sr >> 3 | xmc[29] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[30] << 13; sr = sr >> 3 | xmc[31] << 13; sr = sr >> 3 | xmc[32] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[33] << 13; sr = sr >> 3 | xmc[34] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[35] << 13; sr = sr >> 3 | xmc[36] << 13; sr = sr >> 3 | xmc[37] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[38] << 13; sr = sr >> 7 | Nc[3] << 9; *c++ = sr >> 5; sr = sr >> 2 | bc[3] << 14; sr = sr >> 2 | Mc[3] << 14; sr = sr >> 6 | xmaxc[3] << 10; *c++ = sr >> 3; sr = sr >> 3 | xmc[39] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[40] << 13; sr = sr >> 3 | xmc[41] << 13; sr = sr >> 3 | xmc[42] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[43] << 13; sr = sr >> 3 | xmc[44] << 13; sr = sr >> 3 | xmc[45] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[46] << 13; sr = sr >> 3 | xmc[47] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[48] << 13; sr = sr >> 3 | xmc[49] << 13; sr = sr >> 3 | xmc[50] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[51] << 13; sr = sr >> 4; *c = sr >> 8; s->frame_chain = *c; } else { uword sr; sr = 0; sr = sr >> 4 | s->frame_chain << 12; sr = sr >> 6 | LARc[0] << 10; *c++ = sr >> 6; sr = sr >> 6 | LARc[1] << 10; *c++ = sr >> 8; sr = sr >> 5 | LARc[2] << 11; sr = sr >> 5 | LARc[3] << 11; *c++ = sr >> 6; sr = sr >> 4 | LARc[4] << 12; sr = sr >> 4 | LARc[5] << 12; *c++ = sr >> 6; sr = sr >> 3 | LARc[6] << 13; sr = sr >> 3 | LARc[7] << 13; *c++ = sr >> 8; sr = sr >> 7 | Nc[0] << 9; sr = sr >> 2 | bc[0] << 14; *c++ = sr >> 7; sr = sr >> 2 | Mc[0] << 14; sr = sr >> 6 | xmaxc[0] << 10; *c++ = sr >> 7; sr = sr >> 3 | xmc[0] << 13; sr = sr >> 3 | xmc[1] << 13; sr = sr >> 3 | xmc[2] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[3] << 13; sr = sr >> 3 | xmc[4] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[5] << 13; sr = sr >> 3 | xmc[6] << 13; sr = sr >> 3 | xmc[7] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[8] << 13; sr = sr >> 3 | xmc[9] << 13; sr = sr >> 3 | xmc[10] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[11] << 13; sr = sr >> 3 | xmc[12] << 13; *c++ = sr >> 8; sr = sr >> 7 | Nc[1] << 9; sr = sr >> 2 | bc[1] << 14; *c++ = sr >> 7; sr = sr >> 2 | Mc[1] << 14; sr = sr >> 6 | xmaxc[1] << 10; *c++ = sr >> 7; sr = sr >> 3 | xmc[13] << 13; sr = sr >> 3 | xmc[14] << 13; sr = sr >> 3 | xmc[15] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[16] << 13; sr = sr >> 3 | xmc[17] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[18] << 13; sr = sr >> 3 | xmc[19] << 13; sr = sr >> 3 | xmc[20] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[21] << 13; sr = sr >> 3 | xmc[22] << 13; sr = sr >> 3 | xmc[23] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[24] << 13; sr = sr >> 3 | xmc[25] << 13; *c++ = sr >> 8; sr = sr >> 7 | Nc[2] << 9; sr = sr >> 2 | bc[2] << 14; *c++ = sr >> 7; sr = sr >> 2 | Mc[2] << 14; sr = sr >> 6 | xmaxc[2] << 10; *c++ = sr >> 7; sr = sr >> 3 | xmc[26] << 13; sr = sr >> 3 | xmc[27] << 13; sr = sr >> 3 | xmc[28] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[29] << 13; sr = sr >> 3 | xmc[30] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[31] << 13; sr = sr >> 3 | xmc[32] << 13; sr = sr >> 3 | xmc[33] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[34] << 13; sr = sr >> 3 | xmc[35] << 13; sr = sr >> 3 | xmc[36] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[37] << 13; sr = sr >> 3 | xmc[38] << 13; *c++ = sr >> 8; sr = sr >> 7 | Nc[3] << 9; sr = sr >> 2 | bc[3] << 14; *c++ = sr >> 7; sr = sr >> 2 | Mc[3] << 14; sr = sr >> 6 | xmaxc[3] << 10; *c++ = sr >> 7; sr = sr >> 3 | xmc[39] << 13; sr = sr >> 3 | xmc[40] << 13; sr = sr >> 3 | xmc[41] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[42] << 13; sr = sr >> 3 | xmc[43] << 13; *c++ = sr >> 8; sr = sr >> 3 | xmc[44] << 13; sr = sr >> 3 | xmc[45] << 13; sr = sr >> 3 | xmc[46] << 13; *c++ = sr >> 7; sr = sr >> 3 | xmc[47] << 13; sr = sr >> 3 | xmc[48] << 13; sr = sr >> 3 | xmc[49] << 13; *c++ = sr >> 6; sr = sr >> 3 | xmc[50] << 13; sr = sr >> 3 | xmc[51] << 13; *c++ = sr >> 8; } } else #endif /* WAV49 */ { *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ | ((LARc[0] >> 2) & 0xF); *c++ = ((LARc[0] & 0x3) << 6) | (LARc[1] & 0x3F); *c++ = ((LARc[2] & 0x1F) << 3) | ((LARc[3] >> 2) & 0x7); *c++ = ((LARc[3] & 0x3) << 6) | ((LARc[4] & 0xF) << 2) | ((LARc[5] >> 2) & 0x3); *c++ = ((LARc[5] & 0x3) << 6) | ((LARc[6] & 0x7) << 3) | (LARc[7] & 0x7); *c++ = ((Nc[0] & 0x7F) << 1) | ((bc[0] >> 1) & 0x1); *c++ = ((bc[0] & 0x1) << 7) | ((Mc[0] & 0x3) << 5) | ((xmaxc[0] >> 1) & 0x1F); *c++ = ((xmaxc[0] & 0x1) << 7) | ((xmc[0] & 0x7) << 4) | ((xmc[1] & 0x7) << 1) | ((xmc[2] >> 2) & 0x1); *c++ = ((xmc[2] & 0x3) << 6) | ((xmc[3] & 0x7) << 3) | (xmc[4] & 0x7); *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ | ((xmc[6] & 0x7) << 2) | ((xmc[7] >> 1) & 0x3); *c++ = ((xmc[7] & 0x1) << 7) | ((xmc[8] & 0x7) << 4) | ((xmc[9] & 0x7) << 1) | ((xmc[10] >> 2) & 0x1); *c++ = ((xmc[10] & 0x3) << 6) | ((xmc[11] & 0x7) << 3) | (xmc[12] & 0x7); *c++ = ((Nc[1] & 0x7F) << 1) | ((bc[1] >> 1) & 0x1); *c++ = ((bc[1] & 0x1) << 7) | ((Mc[1] & 0x3) << 5) | ((xmaxc[1] >> 1) & 0x1F); *c++ = ((xmaxc[1] & 0x1) << 7) | ((xmc[13] & 0x7) << 4) | ((xmc[14] & 0x7) << 1) | ((xmc[15] >> 2) & 0x1); *c++ = ((xmc[15] & 0x3) << 6) | ((xmc[16] & 0x7) << 3) | (xmc[17] & 0x7); *c++ = ((xmc[18] & 0x7) << 5) | ((xmc[19] & 0x7) << 2) | ((xmc[20] >> 1) & 0x3); *c++ = ((xmc[20] & 0x1) << 7) | ((xmc[21] & 0x7) << 4) | ((xmc[22] & 0x7) << 1) | ((xmc[23] >> 2) & 0x1); *c++ = ((xmc[23] & 0x3) << 6) | ((xmc[24] & 0x7) << 3) | (xmc[25] & 0x7); *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ | ((bc[2] >> 1) & 0x1); *c++ = ((bc[2] & 0x1) << 7) | ((Mc[2] & 0x3) << 5) | ((xmaxc[2] >> 1) & 0x1F); *c++ = ((xmaxc[2] & 0x1) << 7) | ((xmc[26] & 0x7) << 4) | ((xmc[27] & 0x7) << 1) | ((xmc[28] >> 2) & 0x1); *c++ = ((xmc[28] & 0x3) << 6) | ((xmc[29] & 0x7) << 3) | (xmc[30] & 0x7); *c++ = ((xmc[31] & 0x7) << 5) | ((xmc[32] & 0x7) << 2) | ((xmc[33] >> 1) & 0x3); *c++ = ((xmc[33] & 0x1) << 7) | ((xmc[34] & 0x7) << 4) | ((xmc[35] & 0x7) << 1) | ((xmc[36] >> 2) & 0x1); *c++ = ((xmc[36] & 0x3) << 6) | ((xmc[37] & 0x7) << 3) | (xmc[38] & 0x7); *c++ = ((Nc[3] & 0x7F) << 1) | ((bc[3] >> 1) & 0x1); *c++ = ((bc[3] & 0x1) << 7) | ((Mc[3] & 0x3) << 5) | ((xmaxc[3] >> 1) & 0x1F); *c++ = ((xmaxc[3] & 0x1) << 7) | ((xmc[39] & 0x7) << 4) | ((xmc[40] & 0x7) << 1) | ((xmc[41] >> 2) & 0x1); *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ | ((xmc[42] & 0x7) << 3) | (xmc[43] & 0x7); *c++ = ((xmc[44] & 0x7) << 5) | ((xmc[45] & 0x7) << 2) | ((xmc[46] >> 1) & 0x3); *c++ = ((xmc[46] & 0x1) << 7) | ((xmc[47] & 0x7) << 4) | ((xmc[48] & 0x7) << 1) | ((xmc[49] >> 2) & 0x1); *c++ = ((xmc[49] & 0x3) << 6) | ((xmc[50] & 0x7) << 3) | (xmc[51] & 0x7); } } twinkle-1.4.2/src/audio/gsm/src/add.cpp0000644000175000001440000001267011127714054014621 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add.c,v 1.6 1996/07/02 09:57:33 jutta Exp $ */ /* * See private.h for the more commonly used macro versions. */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" #define saturate(x) \ ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) word gsm_add P2((a,b), word a, word b) { longword sum = (longword)a + (longword)b; return saturate(sum); } word gsm_sub P2((a,b), word a, word b) { longword diff = (longword)a - (longword)b; return saturate(diff); } word gsm_mult P2((a,b), word a, word b) { if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; else return SASR( (longword)a * (longword)b, 15 ); } word gsm_mult_r P2((a,b), word a, word b) { if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; else { longword prod = (longword)a * (longword)b + 16384; prod >>= 15; return prod & 0xFFFF; } } word gsm_abs P1((a), word a) { return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; } longword gsm_L_mult P2((a,b),word a, word b) { assert( a != MIN_WORD || b != MIN_WORD ); return ((longword)a * (longword)b) << 1; } longword gsm_L_add P2((a,b), longword a, longword b) { if (a < 0) { if (b >= 0) return a + b; else { ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; } } else if (b <= 0) return a + b; else { ulongword A = (ulongword)a + (ulongword)b; return A > MAX_LONGWORD ? MAX_LONGWORD : A; } } longword gsm_L_sub P2((a,b), longword a, longword b) { if (a >= 0) { if (b >= 0) return a - b; else { /* a>=0, b<0 */ ulongword A = (ulongword)a + -(b + 1); return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); } } else if (b <= 0) return a - b; else { /* a<0, b>0 */ ulongword A = (ulongword)-(a + 1) + b; return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; } } static unsigned char const bitoff[ 256 ] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; word gsm_norm P1((a), longword a ) /* * the number of left shifts needed to normalize the 32 bit * variable L_var1 for positive values on the interval * * with minimum of * minimum of 1073741824 (01000000000000000000000000000000) and * maximum of 2147483647 (01111111111111111111111111111111) * * * and for negative values on the interval with * minimum of -2147483648 (-10000000000000000000000000000000) and * maximum of -1073741824 ( -1000000000000000000000000000000). * * in order to normalize the result, the following * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); * * (That's 'ffs', only from the left, not the right..) */ { assert(a != 0); if (a < 0) { if (a <= -1073741824) return 0; a = ~a; } return a & 0xffff0000 ? ( a & 0xff000000 ? -1 + bitoff[ 0xFF & (a >> 24) ] : 7 + bitoff[ 0xFF & (a >> 16) ] ) : ( a & 0xff00 ? 15 + bitoff[ 0xFF & (a >> 8) ] : 23 + bitoff[ 0xFF & a ] ); } longword gsm_L_asl P2((a,n), longword a, int n) { if (n >= 32) return 0; if (n <= -32) return -(a < 0); if (n < 0) return gsm_L_asr(a, -n); return a << n; } word gsm_asl P2((a,n), word a, int n) { if (n >= 16) return 0; if (n <= -16) return -(a < 0); if (n < 0) return gsm_asr(a, -n); return a << n; } longword gsm_L_asr P2((a,n), longword a, int n) { if (n >= 32) return -(a < 0); if (n <= -32) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(longword)( -(ulongword)a >> n ); # endif } word gsm_asr P2((a,n), word a, int n) { if (n >= 16) return -(a < 0); if (n <= -16) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(word)( -(uword)a >> n ); # endif } /* * (From p. 46, end of section 4.2.5) * * NOTE: The following lines gives [sic] one correct implementation * of the div(num, denum) arithmetic operation. Compute div * which is the integer division of num by denum: with denum * >= num > 0 */ word gsm_div P2((num,denum), word num, word denum) { longword L_num = num; longword L_denum = denum; word div = 0; int k = 15; /* The parameter num sometimes becomes zero. * Although this is explicitly guarded against in 4.2.5, * we assume that the result should then be zero as well. */ /* assert(num != 0); */ assert(num >= 0 && denum >= num); if (num == 0) return 0; while (k--) { div <<= 1; L_num <<= 1; if (L_num >= L_denum) { L_num -= L_denum; div++; } } return div; } twinkle-1.4.2/src/audio/gsm/src/gsm_implode.cpp0000644000175000001440000003131511127714054016365 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_implode.c,v 1.2 1996/07/02 14:32:43 jutta Exp jutta $ */ #include "private.h" #include "gsm.h" #include "proto.h" void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) { /* variable size index GSM_MAGIC 4 - LARc[0] 6 0 LARc[1] 6 1 LARc[2] 5 2 LARc[3] 5 3 LARc[4] 4 4 LARc[5] 4 5 LARc[6] 3 6 LARc[7] 3 7 Nc[0] 7 8 bc[0] 2 9 Mc[0] 2 10 xmaxc[0] 6 11 xmc[0] 3 12 xmc[1] 3 13 xmc[2] 3 14 xmc[3] 3 15 xmc[4] 3 16 xmc[5] 3 17 xmc[6] 3 18 xmc[7] 3 19 xmc[8] 3 20 xmc[9] 3 21 xmc[10] 3 22 xmc[11] 3 23 xmc[12] 3 24 Nc[1] 7 25 bc[1] 2 26 Mc[1] 2 27 xmaxc[1] 6 28 xmc[13] 3 29 xmc[14] 3 30 xmc[15] 3 31 xmc[16] 3 32 xmc[17] 3 33 xmc[18] 3 34 xmc[19] 3 35 xmc[20] 3 36 xmc[21] 3 37 xmc[22] 3 38 xmc[23] 3 39 xmc[24] 3 40 xmc[25] 3 41 Nc[2] 7 42 bc[2] 2 43 Mc[2] 2 44 xmaxc[2] 6 45 xmc[26] 3 46 xmc[27] 3 47 xmc[28] 3 48 xmc[29] 3 49 xmc[30] 3 50 xmc[31] 3 51 xmc[32] 3 52 xmc[33] 3 53 xmc[34] 3 54 xmc[35] 3 55 xmc[36] 3 56 xmc[37] 3 57 xmc[38] 3 58 Nc[3] 7 59 bc[3] 2 60 Mc[3] 2 61 xmaxc[3] 6 62 xmc[39] 3 63 xmc[40] 3 64 xmc[41] 3 65 xmc[42] 3 66 xmc[43] 3 67 xmc[44] 3 68 xmc[45] 3 69 xmc[46] 3 70 xmc[47] 3 71 xmc[48] 3 72 xmc[49] 3 73 xmc[50] 3 74 xmc[51] 3 75 */ /* There are 76 parameters per frame. The first eight are * unique. The remaining 68 are four identical subframes of * 17 parameters each. gsm_implode converts from a representation * of these parameters as values in one array of signed words * to the "packed" version of a GSM frame. */ # define LARc source # define Nc *((gsm_signal (*) [17])(source + 8)) # define bc *((gsm_signal (*) [17])(source + 9)) # define Mc *((gsm_signal (*) [17])(source + 10)) # define xmaxc *((gsm_signal (*) [17])(source + 11)) #ifdef WAV49 if (s->wav_fmt) { uword sr = 0; if (s->frame_index == 0) { sr = *c++; LARc[0] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 2; LARc[1] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 4; LARc[2] = sr & 0x1f; sr >>= 5; LARc[3] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 2; LARc[4] = sr & 0xf; sr >>= 4; LARc[5] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; /* 5 */ LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[0] = sr & 0x7f; sr >>= 7; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[0] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 12) xmc[0] = sr & 0x7; sr >>= 3; sr = *c++; xmc[1] = sr & 0x7; sr >>= 3; xmc[2] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; xmc[5] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 10 */ xmc[6] = sr & 0x7; sr >>= 3; xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; sr = *c++; xmc[9] = sr & 0x7; sr >>= 3; xmc[10] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[1] = sr & 0x7f; sr >>= 7; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[1] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 29 - 13) xmc[13] = sr & 0x7; sr >>= 3; sr = *c++; /* 15 */ xmc[14] = sr & 0x7; sr >>= 3; xmc[15] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; xmc[18] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[19] = sr & 0x7; sr >>= 3; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; sr = *c++; xmc[22] = sr & 0x7; sr >>= 3; xmc[23] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; /* 20 */ Nc[2] = sr & 0x7f; sr >>= 7; bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[2] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 46 - 26) xmc[26] = sr & 0x7; sr >>= 3; sr = *c++; xmc[27] = sr & 0x7; sr >>= 3; xmc[28] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; xmc[31] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[32] = sr & 0x7; sr >>= 3; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; sr = *c++; /* 25 */ xmc[35] = sr & 0x7; sr >>= 3; xmc[36] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[3] = sr & 0x7f; sr >>= 7; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[3] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 63 - 39) xmc[39] = sr & 0x7; sr >>= 3; sr = *c++; xmc[40] = sr & 0x7; sr >>= 3; xmc[41] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 30 */ xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; xmc[44] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[45] = sr & 0x7; sr >>= 3; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; sr = *c++; xmc[48] = sr & 0x7; sr >>= 3; xmc[49] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; s->frame_chain = sr & 0xf; } else { sr = s->frame_chain; sr |= (uword)*c++ << 4; /* 1 */ LARc[0] = sr & 0x3f; sr >>= 6; LARc[1] = sr & 0x3f; sr >>= 6; sr = *c++; LARc[2] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 3; LARc[3] = sr & 0x1f; sr >>= 5; LARc[4] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; LARc[5] = sr & 0xf; sr >>= 4; LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr = *c++; /* 5 */ Nc[0] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[0] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 12) xmc[0] = sr & 0x7; sr >>= 3; xmc[1] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[2] = sr & 0x7; sr >>= 3; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; sr = *c++; xmc[5] = sr & 0x7; sr >>= 3; xmc[6] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 10 */ xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; xmc[9] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[10] = sr & 0x7; sr >>= 3; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr = *c++; Nc[1] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[1] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 29 - 13) xmc[13] = sr & 0x7; sr >>= 3; xmc[14] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 15 */ xmc[15] = sr & 0x7; sr >>= 3; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; sr = *c++; xmc[18] = sr & 0x7; sr >>= 3; xmc[19] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; xmc[22] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[23] = sr & 0x7; sr >>= 3; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr = *c++; Nc[2] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; /* 20 */ bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[2] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 46 - 26) xmc[26] = sr & 0x7; sr >>= 3; xmc[27] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[28] = sr & 0x7; sr >>= 3; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; sr = *c++; xmc[31] = sr & 0x7; sr >>= 3; xmc[32] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; xmc[35] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 25 */ xmc[36] = sr & 0x7; sr >>= 3; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr = *c++; Nc[3] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[3] = sr & 0x3f; sr >>= 6; #undef xmc #define xmc (source + 63 - 39) xmc[39] = sr & 0x7; sr >>= 3; xmc[40] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[41] = sr & 0x7; sr >>= 3; xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; sr = *c++; /* 30 */ xmc[44] = sr & 0x7; sr >>= 3; xmc[45] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; xmc[48] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[49] = sr & 0x7; sr >>= 3; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; } } else #endif { *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ | ((LARc[0] >> 2) & 0xF); *c++ = ((LARc[0] & 0x3) << 6) | (LARc[1] & 0x3F); *c++ = ((LARc[2] & 0x1F) << 3) | ((LARc[3] >> 2) & 0x7); *c++ = ((LARc[3] & 0x3) << 6) | ((LARc[4] & 0xF) << 2) | ((LARc[5] >> 2) & 0x3); *c++ = ((LARc[5] & 0x3) << 6) | ((LARc[6] & 0x7) << 3) | (LARc[7] & 0x7); *c++ = ((Nc[0] & 0x7F) << 1) | ((bc[0] >> 1) & 0x1); *c++ = ((bc[0] & 0x1) << 7) | ((Mc[0] & 0x3) << 5) | ((xmaxc[0] >> 1) & 0x1F); *c++ = ((xmaxc[0] & 0x1) << 7) #undef xmc #define xmc (source + 12) | ((xmc[0] & 0x7) << 4) | ((xmc[1] & 0x7) << 1) | ((xmc[2] >> 2) & 0x1); *c++ = ((xmc[2] & 0x3) << 6) | ((xmc[3] & 0x7) << 3) | (xmc[4] & 0x7); *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ | ((xmc[6] & 0x7) << 2) | ((xmc[7] >> 1) & 0x3); *c++ = ((xmc[7] & 0x1) << 7) | ((xmc[8] & 0x7) << 4) | ((xmc[9] & 0x7) << 1) | ((xmc[10] >> 2) & 0x1); *c++ = ((xmc[10] & 0x3) << 6) | ((xmc[11] & 0x7) << 3) | (xmc[12] & 0x7); *c++ = ((Nc[1] & 0x7F) << 1) | ((bc[1] >> 1) & 0x1); *c++ = ((bc[1] & 0x1) << 7) | ((Mc[1] & 0x3) << 5) | ((xmaxc[1] >> 1) & 0x1F); *c++ = ((xmaxc[1] & 0x1) << 7) #undef xmc #define xmc (source + 29 - 13) | ((xmc[13] & 0x7) << 4) | ((xmc[14] & 0x7) << 1) | ((xmc[15] >> 2) & 0x1); *c++ = ((xmc[15] & 0x3) << 6) | ((xmc[16] & 0x7) << 3) | (xmc[17] & 0x7); *c++ = ((xmc[18] & 0x7) << 5) | ((xmc[19] & 0x7) << 2) | ((xmc[20] >> 1) & 0x3); *c++ = ((xmc[20] & 0x1) << 7) | ((xmc[21] & 0x7) << 4) | ((xmc[22] & 0x7) << 1) | ((xmc[23] >> 2) & 0x1); *c++ = ((xmc[23] & 0x3) << 6) | ((xmc[24] & 0x7) << 3) | (xmc[25] & 0x7); *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ | ((bc[2] >> 1) & 0x1); *c++ = ((bc[2] & 0x1) << 7) | ((Mc[2] & 0x3) << 5) | ((xmaxc[2] >> 1) & 0x1F); *c++ = ((xmaxc[2] & 0x1) << 7) #undef xmc #define xmc (source + 46 - 26) | ((xmc[26] & 0x7) << 4) | ((xmc[27] & 0x7) << 1) | ((xmc[28] >> 2) & 0x1); *c++ = ((xmc[28] & 0x3) << 6) | ((xmc[29] & 0x7) << 3) | (xmc[30] & 0x7); *c++ = ((xmc[31] & 0x7) << 5) | ((xmc[32] & 0x7) << 2) | ((xmc[33] >> 1) & 0x3); *c++ = ((xmc[33] & 0x1) << 7) | ((xmc[34] & 0x7) << 4) | ((xmc[35] & 0x7) << 1) | ((xmc[36] >> 2) & 0x1); *c++ = ((xmc[36] & 0x3) << 6) | ((xmc[37] & 0x7) << 3) | (xmc[38] & 0x7); *c++ = ((Nc[3] & 0x7F) << 1) | ((bc[3] >> 1) & 0x1); *c++ = ((bc[3] & 0x1) << 7) | ((Mc[3] & 0x3) << 5) | ((xmaxc[3] >> 1) & 0x1F); *c++ = ((xmaxc[3] & 0x1) << 7) #undef xmc #define xmc (source + 63 - 39) | ((xmc[39] & 0x7) << 4) | ((xmc[40] & 0x7) << 1) | ((xmc[41] >> 2) & 0x1); *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ | ((xmc[42] & 0x7) << 3) | (xmc[43] & 0x7); *c++ = ((xmc[44] & 0x7) << 5) | ((xmc[45] & 0x7) << 2) | ((xmc[46] >> 1) & 0x3); *c++ = ((xmc[46] & 0x1) << 7) | ((xmc[47] & 0x7) << 4) | ((xmc[48] & 0x7) << 1) | ((xmc[49] >> 2) & 0x1); *c++ = ((xmc[49] & 0x3) << 6) | ((xmc[50] & 0x7) << 3) | (xmc[51] & 0x7); } } twinkle-1.4.2/src/audio/gsm/src/decode.cpp0000644000175000001440000000304611127714054015311 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/decode.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ #include #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */ static void Postprocessing P2((S,s), struct gsm_state * S, register word * s) { register int k; register word msr = S->msr; register longword ltmp; /* for GSM_ADD */ register word tmp; for (k = 160; k--; s++) { tmp = GSM_MULT_R( msr, 28180 ); msr = GSM_ADD(*s, tmp); /* Deemphasis */ *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ } S->msr = msr; } void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), struct gsm_state * S, word * LARcr, /* [0..7] IN */ word * Ncr, /* [0..3] IN */ word * bcr, /* [0..3] IN */ word * Mcr, /* [0..3] IN */ word * xmaxcr, /* [0..3] IN */ word * xMcr, /* [0..13*4] IN */ word * s) /* [0..159] OUT */ { int j, k; word erp[40], wt[160]; word * drp = S->dp0 + 120; for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; } Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); Postprocessing(S, s); } twinkle-1.4.2/src/audio/gsm/src/long_term.cpp0000644000175000001440000005604711127714054016065 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/long_term.c,v 1.6 1996/07/02 12:33:19 jutta Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION */ /* * This module computes the LTP gain (bc) and the LTP lag (Nc) * for the long term analysis filter. This is done by calculating a * maximum of the cross-correlation function between the current * sub-segment short term residual signal d[0..39] (output of * the short term analysis filter; for simplification the index * of this array begins at 0 and ends at 39 for each sub-segment of the * RPE-LTP analysis) and the previous reconstructed short term * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be * performed to avoid overflow. */ /* The next procedure exists in six versions. First two integer * version (if USE_FLOAT_MUL is not defined); then four floating * point versions, twice with proper scaling (USE_FLOAT_MUL defined), * once without (USE_FLOAT_MUL and FAST defined, and fast run-time * option used). Every pair has first a Cut version (see the -C * option to toast or the LTP_CUT option to gsm_option()), then the * uncut one. (For a detailed explanation of why this is altogether * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered * Harmful''.) */ #ifndef USE_FLOAT_MUL #ifdef LTP_CUT static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word wt[40]; longword L_result; longword L_max, L_power; word R, S, dmax, scal, best_k; word ltp_cut; register word temp, wt_k; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) { dmax = temp; best_k = k; } } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ wt_k = SASR(d[best_k], scal); for (lambda = 40; lambda <= 120; lambda++) { L_result = (longword)wt_k * dp[best_k - lambda]; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word wt[40]; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); /* Initialization of a working array wt */ for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda++) { # undef STEP # define STEP(k) (longword)wt[k] * dp[k - lambda] register longword L_result; L_result = STEP(0) ; L_result += STEP(1) ; L_result += STEP(2) ; L_result += STEP(3) ; L_result += STEP(4) ; L_result += STEP(5) ; L_result += STEP(6) ; L_result += STEP(7) ; L_result += STEP(8) ; L_result += STEP(9) ; L_result += STEP(10) ; L_result += STEP(11) ; L_result += STEP(12) ; L_result += STEP(13) ; L_result += STEP(14) ; L_result += STEP(15) ; L_result += STEP(16) ; L_result += STEP(17) ; L_result += STEP(18) ; L_result += STEP(19) ; L_result += STEP(20) ; L_result += STEP(21) ; L_result += STEP(22) ; L_result += STEP(23) ; L_result += STEP(24) ; L_result += STEP(25) ; L_result += STEP(26) ; L_result += STEP(27) ; L_result += STEP(28) ; L_result += STEP(29) ; L_result += STEP(30) ; L_result += STEP(31) ; L_result += STEP(32) ; L_result += STEP(33) ; L_result += STEP(34) ; L_result += STEP(35) ; L_result += STEP(36) ; L_result += STEP(37) ; L_result += STEP(38) ; L_result += STEP(39) ; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #else /* USE_FLOAT_MUL */ #ifdef LTP_CUT static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, /* IN */ register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word ltp_cut; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; /* Initialization of a working array wt */ for (k = 0; k < 40; k++) { register word w = SASR( d[k], scal ); if (w < 0 ? w > -ltp_cut : w < ltp_cut) { wt_float[k] = 0.0; } else { wt_float[k] = w; } } for (k = -120; k < 0; k++) dp_float[k] = dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ if ((W = wt_float[K]) != 0.0) { \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E; } else (a = lp[K]) # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); /* Initialization of a working array wt */ for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); for (k = -120; k < 0; k++) dp_float[k] = dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ W = wt_float[K]; \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #ifdef FAST #ifdef LTP_CUT static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, /* IN */ register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; register float wt_float; word Nc, bc; word wt_max, best_k, ltp_cut; float dp_float_base[120], * dp_float = dp_float_base + 120; register float L_result, L_max, L_power; wt_max = 0; for (k = 0; k < 40; ++k) { if ( d[k] > wt_max) wt_max = d[best_k = k]; else if (-d[k] > wt_max) wt_max = -d[best_k = k]; } assert(wt_max >= 0); wt_float = (float)wt_max; for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda++) { L_result = wt_float * dp_float[best_k - lambda]; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; if (L_max <= 0.) { *bc_out = 0; return; } /* Compute the power of the reconstructed short term residual * signal dp[..] */ dp_float -= Nc; L_power = 0; for (k = 0; k < 40; ++k) { register float f = dp_float[k]; L_power += f * f; } if (L_max >= L_power) { *bc_out = 3; return; } /* Coding of the LTP gain * Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ lambda = L_max / L_power * 32768.; for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; register float L_max, L_power; for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ W = wt_float[K]; \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; if (L_max <= 0.) { *bc_out = 0; return; } /* Compute the power of the reconstructed short term residual * signal dp[..] */ dp_float -= Nc; L_power = 0; for (k = 0; k < 40; ++k) { register float f = dp_float[k]; L_power += f * f; } if (L_max >= L_power) { *bc_out = 3; return; } /* Coding of the LTP gain * Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ lambda = L_max / L_power * 32768.; for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; *bc_out = bc; } #endif /* FAST */ #endif /* USE_FLOAT_MUL */ /* 4.2.12 */ static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), word bc, /* IN */ word Nc, /* IN */ register word * dp, /* previous d [-120..-1] IN */ register word * d, /* d [0..39] IN */ register word * dpp, /* estimate [0..39] OUT */ register word * e /* long term res. signal [0..39] OUT */ ) /* * In this part, we have to decode the bc parameter to compute * the samples of the estimate dpp[0..39]. The decoding of bc needs the * use of table 4.3b. The long term residual signal e[0..39] * is then calculated to be fed to the RPE encoding section. */ { register int k; register longword ltmp; # undef STEP # define STEP(BP) \ for (k = 0; k <= 39; k++) { \ dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ e[k] = GSM_SUB( d[k], dpp[k] ); \ } switch (bc) { case 0: STEP( 3277 ); break; case 1: STEP( 11469 ); break; case 2: STEP( 21299 ); break; case 3: STEP( 32767 ); break; } } void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ struct gsm_state * S, word * d, /* [0..39] residual signal IN */ word * dp, /* [-120..-1] d' IN */ word * e, /* [0..39] OUT */ word * dpp, /* [0..39] OUT */ word * Nc, /* correlation lag OUT */ word * bc /* gain factor OUT */ ) { assert( d ); assert( dp ); assert( e ); assert( dpp); assert( Nc ); assert( bc ); #if defined(FAST) && defined(USE_FLOAT_MUL) if (S->fast) #if defined (LTP_CUT) if (S->ltp_cut) Cut_Fast_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); else #endif /* LTP_CUT */ Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); else #endif /* FAST & USE_FLOAT_MUL */ #ifdef LTP_CUT if (S->ltp_cut) Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); else #endif Calculation_of_the_LTP_parameters(d, dp, bc, Nc); Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); } /* 4.3.2 */ void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), struct gsm_state * S, word Ncr, word bcr, register word * erp, /* [0..39] IN */ register word * drp /* [-120..-1] IN, [-120..40] OUT */ ) /* * This procedure uses the bcr and Ncr parameter to realize the * long term synthesis filtering. The decoding of bcr needs * table 4.3b. */ { register longword ltmp; /* for ADD */ register int k; word brp, drpp, Nr; /* Check the limits of Nr. */ Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; S->nrp = Nr; assert(Nr >= 40 && Nr <= 120); /* Decoding of the LTP gain bcr */ brp = gsm_QLB[ bcr ]; /* Computation of the reconstructed short term residual * signal drp[0..39] */ assert(brp != MIN_WORD); for (k = 0; k <= 39; k++) { drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); drp[k] = GSM_ADD( erp[k], drpp ); } /* * Update of the reconstructed short term residual signal * drp[ -1..-120 ] */ for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; } twinkle-1.4.2/src/audio/gsm/src/short_term.cpp0000644000175000001440000002424611127714054016261 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/short_term.c,v 1.2 1994/05/10 20:18:47 jutta Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* * SHORT TERM ANALYSIS FILTERING SECTION */ /* 4.2.8 */ static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), word * LARc, /* coded log area ratio [0..7] IN */ word * LARpp) /* out: decoded .. */ { register word temp1 /* , temp2 */; register long ltmp; /* for GSM_ADD */ /* This procedure requires for efficient implementation * two tables. * * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) * MIC[1..8] = minimum value of the LARc[1..8] */ /* Compute the LARpp[1..8] */ /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { * * temp1 = GSM_ADD( *LARc, *MIC ) << 10; * temp2 = *B << 1; * temp1 = GSM_SUB( temp1, temp2 ); * * assert(*INVA != MIN_WORD); * * temp1 = GSM_MULT_R( *INVA, temp1 ); * *LARpp = GSM_ADD( temp1, temp1 ); * } */ #undef STEP #define STEP( B, MIC, INVA ) \ temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ temp1 = GSM_SUB( temp1, B << 1 ); \ temp1 = GSM_MULT_R( INVA, temp1 ); \ *LARpp++ = GSM_ADD( temp1, temp1 ); STEP( 0, -32, 13107 ); STEP( 0, -32, 13107 ); STEP( 2048, -16, 13107 ); STEP( -2560, -16, 13107 ); STEP( 94, -8, 19223 ); STEP( -1792, -8, 17476 ); STEP( -341, -4, 31454 ); STEP( -1144, -4, 29708 ); /* NOTE: the addition of *MIC is used to restore * the sign of *LARc. */ } /* 4.2.9 */ /* Computation of the quantized reflection coefficients */ /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] */ /* * Within each frame of 160 analyzed speech samples the short term * analysis and synthesis filters operate with four different sets of * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) * and the actual set of decoded LARs (LARpp(j)) * * (Initial value: LARpp(j-1)[1..8] = 0.) */ static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); } } static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); } } static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); } } static void Coefficients_40_159 P2((LARpp_j, LARp), register word * LARpp_j, register word * LARp) { register int i; for (i = 1; i <= 8; i++, LARp++, LARpp_j++) *LARp = *LARpp_j; } /* 4.2.9.2 */ static void LARp_to_rp P1((LARp), register word * LARp) /* [0..7] IN/OUT */ /* * The input of this procedure is the interpolated LARp[0..7] array. * The reflection coefficients, rp[i], are used in the analysis * filter and in the synthesis filter. */ { register int i; register word temp; register longword ltmp; for (i = 1; i <= 8; i++, LARp++) { /* temp = GSM_ABS( *LARp ); * * if (temp < 11059) temp <<= 1; * else if (temp < 20070) temp += 11059; * else temp = GSM_ADD( temp >> 2, 26112 ); * * *LARp = *LARp < 0 ? -temp : temp; */ if (*LARp < 0) { temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); *LARp = - ((temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 ))); } else { temp = *LARp; *LARp = (temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 )); } } } /* 4.2.10 */ static void Short_term_analysis_filtering P4((S,rp,k_n,s), struct gsm_state * S, register word * rp, /* [0..7] IN */ register int k_n, /* k_end - k_start */ register word * s /* [0..n-1] IN/OUT */ ) /* * This procedure computes the short term residual signal d[..] to be fed * to the RPE-LTP loop from the s[..] signal and from the local rp[..] * array (quantized reflection coefficients). As the call of this * procedure can be done in many ways (see the interpolation of the LAR * coefficient), it is assumed that the computation begins with index * k_start (for arrays d[..] and s[..]) and stops with index k_end * (k_start and k_end are defined in 4.2.9.1). This procedure also * needs to keep the array u[0..7] in memory for each call. */ { register word * u = S->u; register int i; register word di, zzz, ui, sav, rpi; register longword ltmp; for (; k_n--; s++) { di = sav = *s; for (i = 0; i < 8; i++) { /* YYY */ ui = u[i]; rpi = rp[i]; u[i] = sav; zzz = GSM_MULT_R(rpi, di); sav = GSM_ADD( ui, zzz); zzz = GSM_MULT_R(rpi, ui); di = GSM_ADD( di, zzz ); } *s = di; } } #if defined(USE_FLOAT_MUL) && defined(FAST) static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), struct gsm_state * S, register word * rp, /* [0..7] IN */ register int k_n, /* k_end - k_start */ register word * s /* [0..n-1] IN/OUT */ ) { register word * u = S->u; register int i; float uf[8], rpf[8]; register float scalef = 3.0517578125e-5; register float sav, di, temp; for (i = 0; i < 8; ++i) { uf[i] = u[i]; rpf[i] = rp[i] * scalef; } for (; k_n--; s++) { sav = di = *s; for (i = 0; i < 8; ++i) { register float rpfi = rpf[i]; register float ufi = uf[i]; uf[i] = sav; temp = rpfi * di + ufi; di += rpfi * ufi; sav = temp; } *s = di; } for (i = 0; i < 8; ++i) u[i] = uf[i]; } #endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), struct gsm_state * S, register word * rrp, /* [0..7] IN */ register int k, /* k_end - k_start */ register word * wt, /* [0..k-1] IN */ register word * sr /* [0..k-1] OUT */ ) { register word * v = S->v; register int i; register word sri, tmp1, tmp2; register longword ltmp; /* for GSM_ADD & GSM_SUB */ while (k--) { sri = *wt++; for (i = 8; i--;) { /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); */ tmp1 = rrp[i]; tmp2 = v[i]; tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + 16384) >> 15)) ; sri = GSM_SUB( sri, tmp2 ); /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); */ tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)sri + 16384) >> 15)) ; v[i+1] = GSM_ADD( v[i], tmp1); } *sr++ = v[0] = sri; } } #if defined(FAST) && defined(USE_FLOAT_MUL) static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), struct gsm_state * S, register word * rrp, /* [0..7] IN */ register int k, /* k_end - k_start */ register word * wt, /* [0..k-1] IN */ register word * sr /* [0..k-1] OUT */ ) { register word * v = S->v; register int i; float va[9], rrpa[8]; register float scalef = 3.0517578125e-5, temp; for (i = 0; i < 8; ++i) { va[i] = v[i]; rrpa[i] = (float)rrp[i] * scalef; } while (k--) { register float sri = *wt++; for (i = 8; i--;) { sri -= rrpa[i] * va[i]; if (sri < -32768.) sri = -32768.; else if (sri > 32767.) sri = 32767.; temp = va[i] + rrpa[i] * sri; if (temp < -32768.) temp = -32768.; else if (temp > 32767.) temp = 32767.; va[i+1] = temp; } *sr++ = va[0] = sri; } for (i = 0; i < 9; ++i) v[i] = va[i]; } #endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), struct gsm_state * S, word * LARc, /* coded log area ratio [0..7] IN */ word * s /* signal [0..159] IN/OUT */ ) { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_analysis_filtering \ : Short_term_analysis_filtering )) #else # define FILTER Short_term_analysis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, s); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, s + 13); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, s + 27); Coefficients_40_159( LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 120, s + 40); } void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), struct gsm_state * S, word * LARcr, /* received log area ratios [0..7] IN */ word * wt, /* received d [0..159] IN */ word * s /* signal s [0..159] OUT */ ) { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_synthesis_filtering \ : Short_term_synthesis_filtering )) #else # define FILTER Short_term_synthesis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt, s ); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, wt + 13, s + 13 ); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt + 27, s + 27 ); Coefficients_40_159( LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER(S, LARp, 120, wt + 40, s + 40); } twinkle-1.4.2/src/audio/gsm/src/preprocess.cpp0000644000175000001440000000472511127714054016260 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/preprocess.c,v 1.2 1994/05/10 20:18:45 jutta Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* 4.2.0 .. 4.2.3 PREPROCESSING SECTION * * After A-law to linear conversion (or directly from the * Ato D converter) the following scaling is assumed for * input to the RPE-LTP algorithm: * * in: 0.1.....................12 * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* * * Where S is the sign bit, v a valid bit, and * a "don't care" bit. * The original signal is called sop[..] * * out: 0.1................... 12 * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 */ void Gsm_Preprocess P3((S, s, so), struct gsm_state * S, word * s, word * so ) /* [0..159] IN/OUT */ { word z1 = S->z1; longword L_z2 = S->L_z2; word mp = S->mp; word s1; longword L_s2; longword L_temp; word msp, lsp; word SO; longword ltmp; /* for ADD */ ulongword utmp; /* for L_ADD */ register int k = 160; while (k--) { /* 4.2.1 Downscaling of the input signal */ SO = SASR( *s, 3 ) << 2; s++; assert (SO >= -0x4000); /* downscaled by */ assert (SO <= 0x3FFC); /* previous routine. */ /* 4.2.2 Offset compensation * * This part implements a high-pass filter and requires extended * arithmetic precision for the recursive part of this filter. * The input of this procedure is the array so[0...159] and the * output the array sof[ 0...159 ]. */ /* Compute the non-recursive part */ s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */ z1 = SO; assert(s1 != MIN_WORD); /* Compute the recursive part */ L_s2 = s1; L_s2 <<= 15; /* Execution of a 31 bv 16 bits multiplication */ msp = SASR( L_z2, 15 ); lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */ L_s2 += GSM_MULT_R( lsp, 32735 ); L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ L_z2 = GSM_L_ADD( L_temp, L_s2 ); /* Compute sof[k] with rounding */ L_temp = GSM_L_ADD( L_z2, 16384 ); /* 4.2.3 Preemphasis */ msp = GSM_MULT_R( mp, -28180 ); mp = SASR( L_temp, 15 ); *so++ = GSM_ADD( mp, msp ); } S->z1 = z1; S->L_z2 = L_z2; S->mp = mp; } twinkle-1.4.2/src/audio/gsm/src/gsm_print.cpp0000644000175000001440000001150711127714054016071 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_print.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ #include #include "private.h" #include "gsm.h" #include "proto.h" int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; Nc[0] = (*c >> 1) & 0x7F; bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; Mc[0] = (*c >> 5) & 0x3; xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; Nc[1] = (*c >> 1) & 0x7F; bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; Mc[1] = (*c >> 5) & 0x3; xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; Nc[2] = (*c >> 1) & 0x7F; bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; Mc[2] = (*c >> 5) & 0x3; xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; Nc[3] = (*c >> 1) & 0x7F; bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; Mc[3] = (*c >> 5) & 0x3; xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ fprintf(f, "LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n", LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]); fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[0], bc[0], Mc[0], xmaxc[0]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6], xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] ); fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[1], bc[1], Mc[1], xmaxc[1]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5], xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11], xmc[13+12] ); fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[2], bc[2], Mc[2], xmaxc[2]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5], xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11], xmc[26+12] ); fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[3], bc[3], Mc[3], xmaxc[3]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5], xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11], xmc[39+12] ); return 0; } twinkle-1.4.2/src/audio/gsm/src/gsm_create.cpp0000644000175000001440000000153411127714054016177 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ static char const ident[] = "$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $"; #include "config.h" #ifdef HAS_STRING_H #include #else # include "proto.h" extern char * memset P((char *, int, int)); #endif #ifdef HAS_STDLIB_H # include #else # ifdef HAS_MALLOC_H # include # else extern char * malloc(); # endif #endif #include #include "gsm.h" #include "private.h" #include "proto.h" gsm gsm_create P0() { gsm r; r = (gsm)malloc(sizeof(struct gsm_state)); if (!r) return r; memset((char *)r, 0, sizeof(*r)); r->nrp = 40; return r; } twinkle-1.4.2/src/audio/gsm/src/gsm_option.cpp0000644000175000001440000000227111127714054016243 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_option.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_option P3((r, opt, val), gsm r, int opt, int * val) { int result = -1; switch (opt) { case GSM_OPT_LTP_CUT: #ifdef LTP_CUT result = r->ltp_cut; if (val) r->ltp_cut = *val; #endif break; case GSM_OPT_VERBOSE: #ifndef NDEBUG result = r->verbose; if (val) r->verbose = *val; #endif break; case GSM_OPT_FAST: #if defined(FAST) && defined(USE_FLOAT_MUL) result = r->fast; if (val) r->fast = !!*val; #endif break; case GSM_OPT_FRAME_CHAIN: #ifdef WAV49 result = r->frame_chain; if (val) r->frame_chain = *val; #endif break; case GSM_OPT_FRAME_INDEX: #ifdef WAV49 result = r->frame_index; if (val) r->frame_index = *val; #endif break; case GSM_OPT_WAV49: #ifdef WAV49 result = r->wav_fmt; if (val) r->wav_fmt = !!*val; #endif break; default: break; } return result; } twinkle-1.4.2/src/audio/gsm/src/table.cpp0000644000175000001440000000414711127714054015160 00000000000000/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/table.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ /* Most of these tables are inlined at their point of use. */ /* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP * CODER AND DECODER * * (Most of them inlined, so watch out.) */ #define GSM_TABLE_C #include "private.h" #include "gsm.h" /* Table 4.1 Quantization of the Log.-Area Ratios */ /* i 1 2 3 4 5 6 7 8 */ word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 }; word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 }; /* Table 4.2 Tabulation of 1/A[1..8] */ word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; /* Table 4.3a Decision level of the LTP gain quantizer */ /* bc 0 1 2 3 */ word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; /* Table 4.3b Quantization levels of the LTP gain quantizer */ /* bc 0 1 2 3 */ word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; /* Table 4.4 Coefficients of the weighting filter */ /* i 0 1 2 3 4 5 6 7 8 9 10 */ word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; /* Table 4.5 Normalized inverse mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; /* Table 4.6 Normalized direct mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; twinkle-1.4.2/src/audio/gsm/README0000644000175000001440000000320710503576706013461 00000000000000 GSM 06.10 13 kbit/s RPE/LTP speech compression available -------------------------------------------------------- The Communications and Operating Systems Research Group (KBS) at the Technische Universitaet Berlin is currently working on a set of UNIX-based tools for computer-mediated telecooperation that will be made freely available. As part of this effort we are publishing an implementation of the European GSM 06.10 provisional standard for full-rate speech transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse excitation/long term prediction) coding at 13 kbit/s. GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility with typical UNIX applications, our implementation turns frames of 160 16-bit linear samples into 33-byte frames (1650 Bytes/s). The quality of the algorithm is good enough for reliable speaker recognition; even music often survives transcoding in recognizable form (given the bandwidth limitations of 8 kHz sampling rate). The interfaces offered are a front end modelled after compress(1), and a library API. Compression and decompression run faster than realtime on most SPARCstations. The implementation has been verified against the ETSI standard test patterns. Jutta Degener (jutta@cs.tu-berlin.de) Carsten Bormann (cabo@cs.tu-berlin.de) Communications and Operating Systems Research Group, TU Berlin Fax: +49.30.31425156, Phone: +49.30.31424315 -- Copyright 1992 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. twinkle-1.4.2/src/audio/gsm/Makefile.am0000644000175000001440000000106310652176325014631 00000000000000AM_CPPFLAGS = \ -I$(srcdir)/inc \ -DSASR -DNeedFunctionPrototypes=1 noinst_LIBRARIES = libgsm.a libgsm_a_SOURCES =\ src/add.cpp\ src/code.cpp\ src/debug.cpp\ src/decode.cpp\ src/long_term.cpp\ src/lpc.cpp\ src/preprocess.cpp\ src/rpe.cpp\ src/gsm_destroy.cpp\ src/gsm_decode.cpp\ src/gsm_encode.cpp\ src/gsm_explode.cpp\ src/gsm_implode.cpp\ src/gsm_create.cpp\ src/gsm_print.cpp\ src/gsm_option.cpp\ src/short_term.cpp\ src/table.cpp\ inc/gsm.h\ inc/proto.h\ inc/config.h\ inc/private.h\ inc/unproto.h EXTRA_DIST = COPYRIGHT MACHINES twinkle-1.4.2/src/audio/gsm/Makefile.in0000644000175000001440000014162311151323406014636 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/audio/gsm DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ ChangeLog INSTALL ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libgsm_a_AR = $(AR) $(ARFLAGS) libgsm_a_LIBADD = am_libgsm_a_OBJECTS = add.$(OBJEXT) code.$(OBJEXT) debug.$(OBJEXT) \ decode.$(OBJEXT) long_term.$(OBJEXT) lpc.$(OBJEXT) \ preprocess.$(OBJEXT) rpe.$(OBJEXT) gsm_destroy.$(OBJEXT) \ gsm_decode.$(OBJEXT) gsm_encode.$(OBJEXT) \ gsm_explode.$(OBJEXT) gsm_implode.$(OBJEXT) \ gsm_create.$(OBJEXT) gsm_print.$(OBJEXT) gsm_option.$(OBJEXT) \ short_term.$(OBJEXT) table.$(OBJEXT) libgsm_a_OBJECTS = $(am_libgsm_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libgsm_a_SOURCES) DIST_SOURCES = $(libgsm_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -I$(srcdir)/inc \ -DSASR -DNeedFunctionPrototypes=1 noinst_LIBRARIES = libgsm.a libgsm_a_SOURCES = \ src/add.cpp\ src/code.cpp\ src/debug.cpp\ src/decode.cpp\ src/long_term.cpp\ src/lpc.cpp\ src/preprocess.cpp\ src/rpe.cpp\ src/gsm_destroy.cpp\ src/gsm_decode.cpp\ src/gsm_encode.cpp\ src/gsm_explode.cpp\ src/gsm_implode.cpp\ src/gsm_create.cpp\ src/gsm_print.cpp\ src/gsm_option.cpp\ src/short_term.cpp\ src/table.cpp\ inc/gsm.h\ inc/proto.h\ inc/config.h\ inc/private.h\ inc/unproto.h EXTRA_DIST = COPYRIGHT MACHINES all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/audio/gsm/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/audio/gsm/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgsm.a: $(libgsm_a_OBJECTS) $(libgsm_a_DEPENDENCIES) -rm -f libgsm.a $(libgsm_a_AR) libgsm.a $(libgsm_a_OBJECTS) $(libgsm_a_LIBADD) $(RANLIB) libgsm.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/code.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_create.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_decode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_destroy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_encode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_explode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_implode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_option.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_print.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/long_term.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preprocess.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/short_term.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` add.o: src/add.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT add.o -MD -MP -MF "$(DEPDIR)/add.Tpo" -c -o add.o `test -f 'src/add.cpp' || echo '$(srcdir)/'`src/add.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/add.Tpo" "$(DEPDIR)/add.Po"; else rm -f "$(DEPDIR)/add.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/add.cpp' object='add.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o add.o `test -f 'src/add.cpp' || echo '$(srcdir)/'`src/add.cpp add.obj: src/add.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT add.obj -MD -MP -MF "$(DEPDIR)/add.Tpo" -c -o add.obj `if test -f 'src/add.cpp'; then $(CYGPATH_W) 'src/add.cpp'; else $(CYGPATH_W) '$(srcdir)/src/add.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/add.Tpo" "$(DEPDIR)/add.Po"; else rm -f "$(DEPDIR)/add.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/add.cpp' object='add.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o add.obj `if test -f 'src/add.cpp'; then $(CYGPATH_W) 'src/add.cpp'; else $(CYGPATH_W) '$(srcdir)/src/add.cpp'; fi` code.o: src/code.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT code.o -MD -MP -MF "$(DEPDIR)/code.Tpo" -c -o code.o `test -f 'src/code.cpp' || echo '$(srcdir)/'`src/code.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/code.Tpo" "$(DEPDIR)/code.Po"; else rm -f "$(DEPDIR)/code.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/code.cpp' object='code.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o code.o `test -f 'src/code.cpp' || echo '$(srcdir)/'`src/code.cpp code.obj: src/code.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT code.obj -MD -MP -MF "$(DEPDIR)/code.Tpo" -c -o code.obj `if test -f 'src/code.cpp'; then $(CYGPATH_W) 'src/code.cpp'; else $(CYGPATH_W) '$(srcdir)/src/code.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/code.Tpo" "$(DEPDIR)/code.Po"; else rm -f "$(DEPDIR)/code.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/code.cpp' object='code.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o code.obj `if test -f 'src/code.cpp'; then $(CYGPATH_W) 'src/code.cpp'; else $(CYGPATH_W) '$(srcdir)/src/code.cpp'; fi` debug.o: src/debug.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT debug.o -MD -MP -MF "$(DEPDIR)/debug.Tpo" -c -o debug.o `test -f 'src/debug.cpp' || echo '$(srcdir)/'`src/debug.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/debug.Tpo" "$(DEPDIR)/debug.Po"; else rm -f "$(DEPDIR)/debug.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/debug.cpp' object='debug.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o debug.o `test -f 'src/debug.cpp' || echo '$(srcdir)/'`src/debug.cpp debug.obj: src/debug.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT debug.obj -MD -MP -MF "$(DEPDIR)/debug.Tpo" -c -o debug.obj `if test -f 'src/debug.cpp'; then $(CYGPATH_W) 'src/debug.cpp'; else $(CYGPATH_W) '$(srcdir)/src/debug.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/debug.Tpo" "$(DEPDIR)/debug.Po"; else rm -f "$(DEPDIR)/debug.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/debug.cpp' object='debug.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o debug.obj `if test -f 'src/debug.cpp'; then $(CYGPATH_W) 'src/debug.cpp'; else $(CYGPATH_W) '$(srcdir)/src/debug.cpp'; fi` decode.o: src/decode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT decode.o -MD -MP -MF "$(DEPDIR)/decode.Tpo" -c -o decode.o `test -f 'src/decode.cpp' || echo '$(srcdir)/'`src/decode.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/decode.Tpo" "$(DEPDIR)/decode.Po"; else rm -f "$(DEPDIR)/decode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/decode.cpp' object='decode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o decode.o `test -f 'src/decode.cpp' || echo '$(srcdir)/'`src/decode.cpp decode.obj: src/decode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT decode.obj -MD -MP -MF "$(DEPDIR)/decode.Tpo" -c -o decode.obj `if test -f 'src/decode.cpp'; then $(CYGPATH_W) 'src/decode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/decode.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/decode.Tpo" "$(DEPDIR)/decode.Po"; else rm -f "$(DEPDIR)/decode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/decode.cpp' object='decode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o decode.obj `if test -f 'src/decode.cpp'; then $(CYGPATH_W) 'src/decode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/decode.cpp'; fi` long_term.o: src/long_term.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT long_term.o -MD -MP -MF "$(DEPDIR)/long_term.Tpo" -c -o long_term.o `test -f 'src/long_term.cpp' || echo '$(srcdir)/'`src/long_term.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/long_term.Tpo" "$(DEPDIR)/long_term.Po"; else rm -f "$(DEPDIR)/long_term.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/long_term.cpp' object='long_term.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o long_term.o `test -f 'src/long_term.cpp' || echo '$(srcdir)/'`src/long_term.cpp long_term.obj: src/long_term.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT long_term.obj -MD -MP -MF "$(DEPDIR)/long_term.Tpo" -c -o long_term.obj `if test -f 'src/long_term.cpp'; then $(CYGPATH_W) 'src/long_term.cpp'; else $(CYGPATH_W) '$(srcdir)/src/long_term.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/long_term.Tpo" "$(DEPDIR)/long_term.Po"; else rm -f "$(DEPDIR)/long_term.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/long_term.cpp' object='long_term.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o long_term.obj `if test -f 'src/long_term.cpp'; then $(CYGPATH_W) 'src/long_term.cpp'; else $(CYGPATH_W) '$(srcdir)/src/long_term.cpp'; fi` lpc.o: src/lpc.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lpc.o -MD -MP -MF "$(DEPDIR)/lpc.Tpo" -c -o lpc.o `test -f 'src/lpc.cpp' || echo '$(srcdir)/'`src/lpc.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/lpc.Tpo" "$(DEPDIR)/lpc.Po"; else rm -f "$(DEPDIR)/lpc.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/lpc.cpp' object='lpc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lpc.o `test -f 'src/lpc.cpp' || echo '$(srcdir)/'`src/lpc.cpp lpc.obj: src/lpc.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lpc.obj -MD -MP -MF "$(DEPDIR)/lpc.Tpo" -c -o lpc.obj `if test -f 'src/lpc.cpp'; then $(CYGPATH_W) 'src/lpc.cpp'; else $(CYGPATH_W) '$(srcdir)/src/lpc.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/lpc.Tpo" "$(DEPDIR)/lpc.Po"; else rm -f "$(DEPDIR)/lpc.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/lpc.cpp' object='lpc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lpc.obj `if test -f 'src/lpc.cpp'; then $(CYGPATH_W) 'src/lpc.cpp'; else $(CYGPATH_W) '$(srcdir)/src/lpc.cpp'; fi` preprocess.o: src/preprocess.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT preprocess.o -MD -MP -MF "$(DEPDIR)/preprocess.Tpo" -c -o preprocess.o `test -f 'src/preprocess.cpp' || echo '$(srcdir)/'`src/preprocess.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/preprocess.Tpo" "$(DEPDIR)/preprocess.Po"; else rm -f "$(DEPDIR)/preprocess.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/preprocess.cpp' object='preprocess.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o preprocess.o `test -f 'src/preprocess.cpp' || echo '$(srcdir)/'`src/preprocess.cpp preprocess.obj: src/preprocess.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT preprocess.obj -MD -MP -MF "$(DEPDIR)/preprocess.Tpo" -c -o preprocess.obj `if test -f 'src/preprocess.cpp'; then $(CYGPATH_W) 'src/preprocess.cpp'; else $(CYGPATH_W) '$(srcdir)/src/preprocess.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/preprocess.Tpo" "$(DEPDIR)/preprocess.Po"; else rm -f "$(DEPDIR)/preprocess.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/preprocess.cpp' object='preprocess.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o preprocess.obj `if test -f 'src/preprocess.cpp'; then $(CYGPATH_W) 'src/preprocess.cpp'; else $(CYGPATH_W) '$(srcdir)/src/preprocess.cpp'; fi` rpe.o: src/rpe.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT rpe.o -MD -MP -MF "$(DEPDIR)/rpe.Tpo" -c -o rpe.o `test -f 'src/rpe.cpp' || echo '$(srcdir)/'`src/rpe.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/rpe.Tpo" "$(DEPDIR)/rpe.Po"; else rm -f "$(DEPDIR)/rpe.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/rpe.cpp' object='rpe.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o rpe.o `test -f 'src/rpe.cpp' || echo '$(srcdir)/'`src/rpe.cpp rpe.obj: src/rpe.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT rpe.obj -MD -MP -MF "$(DEPDIR)/rpe.Tpo" -c -o rpe.obj `if test -f 'src/rpe.cpp'; then $(CYGPATH_W) 'src/rpe.cpp'; else $(CYGPATH_W) '$(srcdir)/src/rpe.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/rpe.Tpo" "$(DEPDIR)/rpe.Po"; else rm -f "$(DEPDIR)/rpe.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/rpe.cpp' object='rpe.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o rpe.obj `if test -f 'src/rpe.cpp'; then $(CYGPATH_W) 'src/rpe.cpp'; else $(CYGPATH_W) '$(srcdir)/src/rpe.cpp'; fi` gsm_destroy.o: src/gsm_destroy.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_destroy.o -MD -MP -MF "$(DEPDIR)/gsm_destroy.Tpo" -c -o gsm_destroy.o `test -f 'src/gsm_destroy.cpp' || echo '$(srcdir)/'`src/gsm_destroy.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_destroy.Tpo" "$(DEPDIR)/gsm_destroy.Po"; else rm -f "$(DEPDIR)/gsm_destroy.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_destroy.cpp' object='gsm_destroy.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_destroy.o `test -f 'src/gsm_destroy.cpp' || echo '$(srcdir)/'`src/gsm_destroy.cpp gsm_destroy.obj: src/gsm_destroy.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_destroy.obj -MD -MP -MF "$(DEPDIR)/gsm_destroy.Tpo" -c -o gsm_destroy.obj `if test -f 'src/gsm_destroy.cpp'; then $(CYGPATH_W) 'src/gsm_destroy.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_destroy.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_destroy.Tpo" "$(DEPDIR)/gsm_destroy.Po"; else rm -f "$(DEPDIR)/gsm_destroy.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_destroy.cpp' object='gsm_destroy.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_destroy.obj `if test -f 'src/gsm_destroy.cpp'; then $(CYGPATH_W) 'src/gsm_destroy.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_destroy.cpp'; fi` gsm_decode.o: src/gsm_decode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_decode.o -MD -MP -MF "$(DEPDIR)/gsm_decode.Tpo" -c -o gsm_decode.o `test -f 'src/gsm_decode.cpp' || echo '$(srcdir)/'`src/gsm_decode.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_decode.Tpo" "$(DEPDIR)/gsm_decode.Po"; else rm -f "$(DEPDIR)/gsm_decode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_decode.cpp' object='gsm_decode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_decode.o `test -f 'src/gsm_decode.cpp' || echo '$(srcdir)/'`src/gsm_decode.cpp gsm_decode.obj: src/gsm_decode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_decode.obj -MD -MP -MF "$(DEPDIR)/gsm_decode.Tpo" -c -o gsm_decode.obj `if test -f 'src/gsm_decode.cpp'; then $(CYGPATH_W) 'src/gsm_decode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_decode.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_decode.Tpo" "$(DEPDIR)/gsm_decode.Po"; else rm -f "$(DEPDIR)/gsm_decode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_decode.cpp' object='gsm_decode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_decode.obj `if test -f 'src/gsm_decode.cpp'; then $(CYGPATH_W) 'src/gsm_decode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_decode.cpp'; fi` gsm_encode.o: src/gsm_encode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_encode.o -MD -MP -MF "$(DEPDIR)/gsm_encode.Tpo" -c -o gsm_encode.o `test -f 'src/gsm_encode.cpp' || echo '$(srcdir)/'`src/gsm_encode.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_encode.Tpo" "$(DEPDIR)/gsm_encode.Po"; else rm -f "$(DEPDIR)/gsm_encode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_encode.cpp' object='gsm_encode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_encode.o `test -f 'src/gsm_encode.cpp' || echo '$(srcdir)/'`src/gsm_encode.cpp gsm_encode.obj: src/gsm_encode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_encode.obj -MD -MP -MF "$(DEPDIR)/gsm_encode.Tpo" -c -o gsm_encode.obj `if test -f 'src/gsm_encode.cpp'; then $(CYGPATH_W) 'src/gsm_encode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_encode.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_encode.Tpo" "$(DEPDIR)/gsm_encode.Po"; else rm -f "$(DEPDIR)/gsm_encode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_encode.cpp' object='gsm_encode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_encode.obj `if test -f 'src/gsm_encode.cpp'; then $(CYGPATH_W) 'src/gsm_encode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_encode.cpp'; fi` gsm_explode.o: src/gsm_explode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_explode.o -MD -MP -MF "$(DEPDIR)/gsm_explode.Tpo" -c -o gsm_explode.o `test -f 'src/gsm_explode.cpp' || echo '$(srcdir)/'`src/gsm_explode.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_explode.Tpo" "$(DEPDIR)/gsm_explode.Po"; else rm -f "$(DEPDIR)/gsm_explode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_explode.cpp' object='gsm_explode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_explode.o `test -f 'src/gsm_explode.cpp' || echo '$(srcdir)/'`src/gsm_explode.cpp gsm_explode.obj: src/gsm_explode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_explode.obj -MD -MP -MF "$(DEPDIR)/gsm_explode.Tpo" -c -o gsm_explode.obj `if test -f 'src/gsm_explode.cpp'; then $(CYGPATH_W) 'src/gsm_explode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_explode.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_explode.Tpo" "$(DEPDIR)/gsm_explode.Po"; else rm -f "$(DEPDIR)/gsm_explode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_explode.cpp' object='gsm_explode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_explode.obj `if test -f 'src/gsm_explode.cpp'; then $(CYGPATH_W) 'src/gsm_explode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_explode.cpp'; fi` gsm_implode.o: src/gsm_implode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_implode.o -MD -MP -MF "$(DEPDIR)/gsm_implode.Tpo" -c -o gsm_implode.o `test -f 'src/gsm_implode.cpp' || echo '$(srcdir)/'`src/gsm_implode.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_implode.Tpo" "$(DEPDIR)/gsm_implode.Po"; else rm -f "$(DEPDIR)/gsm_implode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_implode.cpp' object='gsm_implode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_implode.o `test -f 'src/gsm_implode.cpp' || echo '$(srcdir)/'`src/gsm_implode.cpp gsm_implode.obj: src/gsm_implode.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_implode.obj -MD -MP -MF "$(DEPDIR)/gsm_implode.Tpo" -c -o gsm_implode.obj `if test -f 'src/gsm_implode.cpp'; then $(CYGPATH_W) 'src/gsm_implode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_implode.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_implode.Tpo" "$(DEPDIR)/gsm_implode.Po"; else rm -f "$(DEPDIR)/gsm_implode.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_implode.cpp' object='gsm_implode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_implode.obj `if test -f 'src/gsm_implode.cpp'; then $(CYGPATH_W) 'src/gsm_implode.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_implode.cpp'; fi` gsm_create.o: src/gsm_create.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_create.o -MD -MP -MF "$(DEPDIR)/gsm_create.Tpo" -c -o gsm_create.o `test -f 'src/gsm_create.cpp' || echo '$(srcdir)/'`src/gsm_create.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_create.Tpo" "$(DEPDIR)/gsm_create.Po"; else rm -f "$(DEPDIR)/gsm_create.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_create.cpp' object='gsm_create.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_create.o `test -f 'src/gsm_create.cpp' || echo '$(srcdir)/'`src/gsm_create.cpp gsm_create.obj: src/gsm_create.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_create.obj -MD -MP -MF "$(DEPDIR)/gsm_create.Tpo" -c -o gsm_create.obj `if test -f 'src/gsm_create.cpp'; then $(CYGPATH_W) 'src/gsm_create.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_create.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_create.Tpo" "$(DEPDIR)/gsm_create.Po"; else rm -f "$(DEPDIR)/gsm_create.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_create.cpp' object='gsm_create.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_create.obj `if test -f 'src/gsm_create.cpp'; then $(CYGPATH_W) 'src/gsm_create.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_create.cpp'; fi` gsm_print.o: src/gsm_print.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_print.o -MD -MP -MF "$(DEPDIR)/gsm_print.Tpo" -c -o gsm_print.o `test -f 'src/gsm_print.cpp' || echo '$(srcdir)/'`src/gsm_print.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_print.Tpo" "$(DEPDIR)/gsm_print.Po"; else rm -f "$(DEPDIR)/gsm_print.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_print.cpp' object='gsm_print.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_print.o `test -f 'src/gsm_print.cpp' || echo '$(srcdir)/'`src/gsm_print.cpp gsm_print.obj: src/gsm_print.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_print.obj -MD -MP -MF "$(DEPDIR)/gsm_print.Tpo" -c -o gsm_print.obj `if test -f 'src/gsm_print.cpp'; then $(CYGPATH_W) 'src/gsm_print.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_print.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_print.Tpo" "$(DEPDIR)/gsm_print.Po"; else rm -f "$(DEPDIR)/gsm_print.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_print.cpp' object='gsm_print.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_print.obj `if test -f 'src/gsm_print.cpp'; then $(CYGPATH_W) 'src/gsm_print.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_print.cpp'; fi` gsm_option.o: src/gsm_option.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_option.o -MD -MP -MF "$(DEPDIR)/gsm_option.Tpo" -c -o gsm_option.o `test -f 'src/gsm_option.cpp' || echo '$(srcdir)/'`src/gsm_option.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_option.Tpo" "$(DEPDIR)/gsm_option.Po"; else rm -f "$(DEPDIR)/gsm_option.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_option.cpp' object='gsm_option.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_option.o `test -f 'src/gsm_option.cpp' || echo '$(srcdir)/'`src/gsm_option.cpp gsm_option.obj: src/gsm_option.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gsm_option.obj -MD -MP -MF "$(DEPDIR)/gsm_option.Tpo" -c -o gsm_option.obj `if test -f 'src/gsm_option.cpp'; then $(CYGPATH_W) 'src/gsm_option.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_option.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/gsm_option.Tpo" "$(DEPDIR)/gsm_option.Po"; else rm -f "$(DEPDIR)/gsm_option.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gsm_option.cpp' object='gsm_option.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gsm_option.obj `if test -f 'src/gsm_option.cpp'; then $(CYGPATH_W) 'src/gsm_option.cpp'; else $(CYGPATH_W) '$(srcdir)/src/gsm_option.cpp'; fi` short_term.o: src/short_term.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT short_term.o -MD -MP -MF "$(DEPDIR)/short_term.Tpo" -c -o short_term.o `test -f 'src/short_term.cpp' || echo '$(srcdir)/'`src/short_term.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/short_term.Tpo" "$(DEPDIR)/short_term.Po"; else rm -f "$(DEPDIR)/short_term.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/short_term.cpp' object='short_term.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o short_term.o `test -f 'src/short_term.cpp' || echo '$(srcdir)/'`src/short_term.cpp short_term.obj: src/short_term.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT short_term.obj -MD -MP -MF "$(DEPDIR)/short_term.Tpo" -c -o short_term.obj `if test -f 'src/short_term.cpp'; then $(CYGPATH_W) 'src/short_term.cpp'; else $(CYGPATH_W) '$(srcdir)/src/short_term.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/short_term.Tpo" "$(DEPDIR)/short_term.Po"; else rm -f "$(DEPDIR)/short_term.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/short_term.cpp' object='short_term.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o short_term.obj `if test -f 'src/short_term.cpp'; then $(CYGPATH_W) 'src/short_term.cpp'; else $(CYGPATH_W) '$(srcdir)/src/short_term.cpp'; fi` table.o: src/table.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT table.o -MD -MP -MF "$(DEPDIR)/table.Tpo" -c -o table.o `test -f 'src/table.cpp' || echo '$(srcdir)/'`src/table.cpp; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/table.Tpo" "$(DEPDIR)/table.Po"; else rm -f "$(DEPDIR)/table.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/table.cpp' object='table.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o table.o `test -f 'src/table.cpp' || echo '$(srcdir)/'`src/table.cpp table.obj: src/table.cpp @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT table.obj -MD -MP -MF "$(DEPDIR)/table.Tpo" -c -o table.obj `if test -f 'src/table.cpp'; then $(CYGPATH_W) 'src/table.cpp'; else $(CYGPATH_W) '$(srcdir)/src/table.cpp'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/table.Tpo" "$(DEPDIR)/table.Po"; else rm -f "$(DEPDIR)/table.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/table.cpp' object='table.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o table.obj `if test -f 'src/table.cpp'; then $(CYGPATH_W) 'src/table.cpp'; else $(CYGPATH_W) '$(srcdir)/src/table.cpp'; fi` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/audio/gsm/INSTALL0000644000175000001440000000610710503576706013634 00000000000000How to get started: Edit the Makefile. You should configure a few machine-dependencies and what compiler you want to use. The code works both with ANSI and K&R-C. Use -DNeedFunctionPrototypes to compile with, or -UNeedFunctionPrototypes to compile without, function prototypes in the header files. Make addtst The "add" program that will be compiled and run checks whether the basic math functions of the gsm library work with your compiler. If it prints anything to stderr, complain (to us). Edit inc/config.h. Make Local versions of the gsm library and the "compress"-like filters toast, untoast and tcat will be generated. If the compilation aborts because of a missing function, declaration, or header file, see if there's something in inc/config.h to work around it. If not, complain. Try it Grab an audio file from somewhere (raw u-law or Sun .au is fine, linear 16-bit in host byte order will do), copy it, toast it, untoast it, and listen to the result. The GSM-encoded and -decoded audio should have the quality of a good phone line. If the resulting audio is noisier than your original, or if you hear compression artifacts, complain; that's a bug in our software, not a bug in the GSM encoding standard itself. Installation You can install the gsm library interface, or the toast binaries, or both. Edit the Makefile Fill in the directories where you want to install the library, header files, manual pages, and binaries. Turn off the installation of one half of the distribution (i.e., gsm library or toast binaries) by not setting the corresponding directory root Makefile macro. make install will install the programs "toast" with two links named "tcat" and "untoast", and the gsm library "libgsm.a" with a "gsm.h" header file, and their respective manual pages. Optimizing This code was developed on a machine without an integer multiplication instruction, where we obtained the fastest result by replacing some of the integer multiplications with floating point multiplications. If your machine does multiply integers fast enough, leave USE_FLOAT_MUL undefined. The results should be the same in both cases. On machines with fast floating point arithmetic, defining both USE_FLOAT_MUL and FAST makes a run-time library option available that will (in a few crucial places) use ``native'' floating point operations rather than the bit-by-bit defined ones of the GSM standard. If you use this fast option, the outcome will not be bitwise identical to the results prescribed by the standard, but it is compatible with the standard encoding, and a user is unlikely to notice a difference. Bug Reports Please direct bug reports, questions, and comments to jutta@cs.tu-berlin.de and cabo@informatik.uni-bremen.de. Good luck, Jutta Degener, Carsten Bormann -- Copyright 1992, 1993, 1994, by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. twinkle-1.4.2/src/audio/gsm/MACHINES0000644000175000001440000000067010503576706013714 00000000000000The gsm library has been tested successfully on the following platforms: - Various Sun4's running SunOS 4.1.2 - SPARC1 (SunOS 4.1.1) - Integrated Solutions 68k Optimum running 4.3BSD UNIX with a Green Hills cc - NeXTstation running NeXT-OS/Mach 3.0 - No-name AT/386 with Xenix 2.3.2 (using -DSTUPID_COMPILER) - RS/6000-350 running AIX 3.2.0 - RS/6000-320 running AIX 3.1.5 - Alliant FX80 (Concentrix 5.7) - SGI Indigo XS4000 (IRIX 4.0.5F) twinkle-1.4.2/src/audio/gsm/ChangeLog0000644000175000001440000000620610503576706014355 00000000000000 Fri Jul 5 19:26:37 1996 Jutta Degener (jutta@cs.tu-berlin.de) * Release 1.0 Patchlevel 10 src/toast_alaw.c: exchanged A-law tables for something slightly more A-law. Tue Jul 2 12:18:20 1996 Jutta Degener (jutta@cs.tu-berlin.de) * Release 1.0 Patchlevel 9 src/long_term.c: in FLOAT_MUL mode, an array was accessed past its end src/gsm_option.c: three options related to WAV #49 packing src/gsm_encode.c: support WAV #49-style encoding. src/gsm_decode.c: support WAV #49-style decoding. tls/sour.c: generate the WAV bit shifting code, encode tls/ginger.c: generate the WAV bit shifting code, decode The WAV code goes back to an inofficial patch #8 that Jeff Chilton sent us (hence the jump from 7 to 9). src/toast.c: add _fsetmode() calls to set stdin/stdout to binary (from an OS/2 port by Arnd Gronenberg.) Tue Mar 7 01:55:10 1995 Jutta Degener (jutta@cs.tu-berlin.de) * Release 1.0 Patchlevel 7 src/long_term.c: Yet another 16-bit overflow src/toast.c: -C option to toast, cuts LPC time src/gsm_option.c: corresponding LPC_CUT option to GSM library Fri Dec 30 23:33:50 1994 Jutta Degener (jutta@cs.tu-berlin.de) * Release 1.0 Patchlevel 6 src/lpc.c: fixed 16-bit addition overflow in Autocorrelation code src/add.c: gsm_L_asl should fall back on gsm_L_asr, not gsm_asr Mon Nov 28 20:49:57 1994 Jutta Degener (jutta@cs.tu-berlin.de) * Release 1.0 Patchlevel 5 src/toast_audio.c: initialization should return -1 on error src/gsm_destroy.c: #include configuration header file src/add.c: gsm_sub should cast its parameters to longword man/*: bug reports to {jutta,cabo}@cs.tu-berlin.de, not to toast@tub inc/private.h: longword long by default, not int inc/toast.h: read/write fopen modes "rb" and "wb", not just "r" src/toast.c: better (or different, anyway) error handling in process() Tue May 10 19:41:34 1994 Jutta Degener (jutta at kugelbus) * Release 1.0 Patchlevel 4 inc/private.h: GSM_ADD should cast to ulongword, not to unsigned. src/long_term.c: missing cast to longword. add-test/add_test.c: Test macros too, not only functions, thanks to Simao Ferraz de Campos Neto, simao@dragon.cpqd.ansp.br General cleanup: remove unused variables, add function prototypes. Tue Jan 25 22:53:40 1994 Jutta Degener (jutta at kugelbus) * Release 1.0 Patchlevel 3 changed rpe.c's STEP macro to work with 16-bit integers, thanks to Dr Alex Lee (alexlee@solomon.technet.sg); removed non-fatal bugs from add-test.dta, private.h and toast_audio.c, thanks to P. Emanuelsson. Fri Jan 29 19:02:12 1993 Jutta Degener (jutta at kraftbus) * Release 1.0 Patchlevel 2 fixed L_add(0,-1) in src/add.c and inc/private.h, thanks to Raphael Trommer at AT&T Bell Laboratories; various other ANSI C compatibility details Fri Oct 30 17:58:54 1992 Jutta Degener (jutta at kraftbus) * Release 1.0 Patchlevel 1 Switched uid/gid in toast's [f]chown calls. Wed Oct 28 14:12:35 1992 Carsten Bormann (cabo at kubus) * Release 1.0: released Copyright 1992 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. twinkle-1.4.2/src/audio/gsm/COPYRIGHT0000644000175000001440000000126210503576706014073 00000000000000Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin Any use of this software is permitted provided that this notice is not removed and that neither the authors nor the Technische Universitaet Berlin are deemed to have made any representations as to the suitability of this software for any purpose nor are held responsible for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. As a matter of courtesy, the authors request to be informed about uses this software has found, about bugs in this software, and about any improvements that may be of general interest. Berlin, 28.11.1994 Jutta Degener Carsten Bormann twinkle-1.4.2/src/audio/audio_device.h0000644000175000001440000000775411127714046014611 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _AUDIO_DEVICE_H #define _AUDIO_DEVICE_H #include #include "twinkle_config.h" using namespace std; #ifndef _SYS_SETTINGS_H class t_audio_device; #endif enum t_audio_sampleformat { SAMPLEFORMAT_U8, SAMPLEFORMAT_S8, SAMPLEFORMAT_S16, SAMPLEFORMAT_U16 }; class t_audio_io { public: virtual ~t_audio_io(); virtual void enable(bool enable_playback, bool enable_recording) = 0; virtual void flush(bool playback_buffer, bool recording_buffer) = 0; // Returns the number of bytes that can be written/read without blocking virtual int get_buffer_space(bool is_recording_buffer) = 0; // Returns the size of the hardware buffer virtual int get_buffer_size(bool is_recording_buffer) = 0; /** Check if a play buffer underrun occurred. */ virtual bool play_buffer_underrun(void) = 0; virtual int read(unsigned char* buf, int len) = 0; virtual int write(const unsigned char* buf, int len) = 0; virtual int get_sample_rate(void) const; static t_audio_io* open(const t_audio_device& dev, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency); // Validate if an audio device can be opened. static bool validate(const t_audio_device& dev, bool playback, bool capture); protected: virtual bool open(const string& device, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency); private: int _sample_rate; }; class t_oss_io : public t_audio_io { public: t_oss_io(); virtual ~t_oss_io(); void enable(bool enable_playback, bool enable_recording); void flush(bool playback_buffer, bool recording_buffer); int get_buffer_space(bool is_recording_buffer); int get_buffer_size(bool is_recording_buffer); bool play_buffer_underrun(void); int read(unsigned char* buf, int len); int write(const unsigned char* buf, int len); protected: bool open(const string& device, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency); private: int fd; int play_buffersize, rec_buffersize; }; #ifdef HAVE_LIBASOUND class t_alsa_io : public t_audio_io { public: t_alsa_io(); virtual ~t_alsa_io(); void enable(bool enable_playback, bool enable_recording); void flush(bool playback_buffer, bool recording_buffer); int get_buffer_space(bool is_recording_buffer); int get_buffer_size(bool is_recording_buffer); bool play_buffer_underrun(void); int read(unsigned char* buf, int len); int write(const unsigned char* buf, int len); protected: bool open(const string& device, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency); private: struct _snd_pcm *pcm_play_ptr, *pcm_rec_ptr; int play_framesize, rec_framesize; int play_buffersize, rec_buffersize; int play_periods, rec_periods; bool short_latency; // snd_pcm_delay should return the number of bytes in the buffer. // For some reason however, if the capture device is a software mixer, // it returns inaccurate values. // This flag if the functionality is broken. bool rec_delay_broken; // Indicates if snd_pcm_pause works for this device bool can_pause; }; #endif #endif twinkle-1.4.2/src/audio/g723_16.cpp0000644000175000001440000001237711127714055013511 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* 16kbps version created, used 24kbps code and changing as little as possible. * G.726 specs are available from ITU's gopher or WWW site (http://www.itu.ch) * If any errors are found, please contact me at mrand@tamu.edu * -Marc Randolph */ /* * g723_16.c * * Description: * * g723_16_encoder(), g723_16_decoder() * * These routines comprise an implementation of the CCITT G.726 16 Kbps * ADPCM coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which take advantage * of workstation attributes, such as hardware 2's complement arithmetic. * */ #include "g72x.h" #include "g711.h" /* * Maps G.723_16 code word to reconstructed scale factor normalized log * magnitude values. Comes from Table 11/G.726 */ static short _dqlntab[4] = { 116, 365, 365, 116}; /* Maps G.723_16 code word to log of scale factor multiplier. * * _witab[4] is actually {-22 , 439, 439, -22}, but FILTD wants it * as WI << 5 (multiplied by 32), so we'll do that here */ static short _witab[4] = {-704, 14048, 14048, -704}; /* * Maps G.723_16 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ /* Comes from FUNCTF */ static short _fitab[4] = {0, 0xE00, 0xE00, 0}; /* Comes from quantizer decision level tables (Table 7/G.726) */ static short qtab_723_16[1] = {261}; /* * g723_16_encoder() * * Encodes a linear PCM, A-law or u-law input sample and returns its 2-bit code. * Returns -1 if invalid input coding value. */ int g723_16_encoder( int sl, int in_coding, struct g72x_state *state_ptr) { short sei, sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short y; /* MIX */ short sr; /* ADDB */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* sl of 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ d = sl - se; /* d = estimation diff. */ /* quantize prediction difference d */ y = step_size(state_ptr); /* quantizer step size */ i = quantize(d, y, qtab_723_16, 1); /* i = ADPCM code */ /* Since quantize() only produces a three level output * (1, 2, or 3), we must create the fourth one on our own */ if (i == 3) /* i code for the zero region */ if ((d & 0x8000) == 0) /* If d > 0, i=3 isn't right... */ i = 0; dq = reconstruct(i & 2, _dqlntab[i], y); /* quantized diff. */ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */ dqsez = sr + sez - se; /* pole prediction diff. */ update(2, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g723_16_decoder() * * Decodes a 2-bit CCITT G.723_16 ADPCM code and returns * the resulting 16-bit linear PCM, A-law or u-law sample value. * -1 is returned if the output coding is unknown. */ int g723_16_decoder( int i, int out_coding, struct g72x_state *state_ptr) { short sezi, sei, sez, se; /* ACCUM */ short y; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x03; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* adaptive quantizer step size */ dq = reconstruct(i & 0x02, _dqlntab[i], y); /* unquantize pred diff */ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(2, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 2, qtab_723_16)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 2, qtab_723_16)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was of 14-bit dynamic range */ default: return (-1); } } twinkle-1.4.2/src/audio/g723_24.cpp0000644000175000001440000001105711127714055013502 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g723_24.c * * Description: * * g723_24_encoder(), g723_24_decoder() * * These routines comprise an implementation of the CCITT G.723 24 Kbps * ADPCM coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which take advantage * of workstation attributes, such as hardware 2's complement arithmetic. * */ #include "g72x.h" #include "g711.h" /* * Maps G.723_24 code word to reconstructed scale factor normalized log * magnitude values. */ static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048}; /* Maps G.723_24 code word to log of scale factor multiplier. */ static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128}; /* * Maps G.723_24 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0}; static short qtab_723_24[3] = {8, 218, 331}; /* * g723_24_encoder() * * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. * Returns -1 if invalid input coding value. */ int g723_24_encoder( int sl, int in_coding, struct g72x_state *state_ptr) { short sei, sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short y; /* MIX */ short sr; /* ADDB */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* sl of 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ d = sl - se; /* d = estimation diff. */ /* quantize prediction difference d */ y = step_size(state_ptr); /* quantizer step size */ i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */ dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */ dqsez = sr + sez - se; /* pole prediction diff. */ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g723_24_decoder() * * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns * the resulting 16-bit linear PCM, A-law or u-law sample value. * -1 is returned if the output coding is unknown. */ int g723_24_decoder( int i, int out_coding, struct g72x_state *state_ptr) { short sezi, sei, sez, se; /* ACCUM */ short y; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x07; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* adaptive quantizer step size */ dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was of 14-bit dynamic range */ default: return (-1); } } twinkle-1.4.2/src/audio/freq_gen.h0000644000175000001440000000267011127714046013747 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Frequency generator // // This file contains definitions of the frequency generator. // The frequency generator generates tones build from a list of // frequencies. #ifndef _FREQ_GEN_H #define _FREQ_GEN_H #include #include using namespace std; class t_freq_gen { private: vector _frequencies; int16 _amplitude; public: t_freq_gen(vector frequencies, int8 db_level); t_freq_gen(uint8 dtmf, int8 db_level); // Get sound sample on a particular timestamp in us. int16 get_sample(uint32 ts_usec) const; void get_samples(int16 *sample_buf, uint16 buf_len, uint32 ts_start, double interval) const; }; #endif twinkle-1.4.2/src/audio/g723_40.cpp0000644000175000001440000001264611134631652013504 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g723_40.c * * Description: * * g723_40_encoder(), g723_40_decoder() * * These routines comprise an implementation of the CCITT G.723 40Kbps * ADPCM coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which * take advantage of workstation attributes, such as hardware 2's * complement arithmetic. * * The deviation from the bit level specification (lookup tables), * preserves the bit level performance specifications. * * As outlined in the G.723 Recommendation, the algorithm is broken * down into modules. Each section of code below is preceded by * the name of the module which it is implementing. * */ #include "g72x.h" #include "g711.h" /* * Maps G.723_40 code word to ructeconstructed scale factor normalized log * magnitude values. */ static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318, 358, 395, 429, 459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358, 318, 274, 224, 169, 104, 28, -66, -2048}; /* Maps G.723_40 code word to log of scale factor multiplier. */ static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200, 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, 3200, 1856, 1312, 1280, 1248, 768, 448, 448}; /* * Maps G.723_40 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200, 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, 0x200, 0x200, 0x200, 0, 0, 0, 0, 0}; static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339, 378, 413, 445, 475, 502, 528, 553}; /* * g723_40_encoder() * * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens * the resulting 5-bit CCITT G.723 40Kbps code. * Returns -1 if the input coding value is invalid. */ int g723_40_encoder( int sl, int in_coding, struct g72x_state *state_ptr) { short sei, sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short y; /* MIX */ short sr; /* ADDB */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* sl of 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ d = sl - se; /* d = estimation difference */ /* quantize prediction difference */ y = step_size(state_ptr); /* adaptive quantizer step size */ i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */ sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */ dqsez = sr + sez - se; /* dqsez = pole prediction diff. */ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g723_40_decoder() * * Decodes a 5-bit CCITT G.723 40Kbps code and returns * the resulting 16-bit linear PCM, A-law or u-law sample value. * -1 is returned if the output coding is unknown. */ int g723_40_decoder( int i, int out_coding, struct g72x_state *state_ptr) { short sezi, sei, sez, se; /* ACCUM */ short y; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x1f; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* adaptive quantizer step size */ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */ sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was of 14-bit dynamic range */ default: return (-1); } } twinkle-1.4.2/src/audio/audio_encoder.cpp0000644000175000001440000002610311134634432015307 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "audio_encoder.h" #ifdef HAVE_ILBC #ifndef HAVE_ILBC_CPP extern "C" { #endif #include #ifndef HAVE_ILBC_CPP } #endif #endif ////////////////////////////////////////// // class t_audio_encoder ////////////////////////////////////////// t_audio_encoder::t_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config) : _payload_id(payload_id), _ptime(ptime), _user_config(user_config) {} t_audio_codec t_audio_encoder::get_codec(void) const { return _codec; } uint16 t_audio_encoder::get_payload_id(void) const { return _payload_id; } uint16 t_audio_encoder::get_ptime(void) const { return _ptime; } uint16 t_audio_encoder::get_sample_rate(void) const { return audio_sample_rate(_codec); } uint16 t_audio_encoder::get_max_payload_size(void) const { return _max_payload_size; } ////////////////////////////////////////// // class t_g711a_audio_encoder ////////////////////////////////////////// t_g711a_audio_encoder::t_g711a_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config) : t_audio_encoder(payload_id, ptime, user_config) { _codec = CODEC_G711_ALAW; if (ptime == 0) _ptime = PTIME_G711_ALAW; _max_payload_size = audio_sample_rate(_codec)/1000 * _ptime; } uint16 t_g711a_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { assert(nsamples <= payload_size); silence = false; for (int i = 0; i < nsamples; i++) { payload[i] = linear2alaw(sample_buf[i]); } return nsamples; } ////////////////////////////////////////// // class t_g711u_audio_encoder ////////////////////////////////////////// t_g711u_audio_encoder::t_g711u_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config) : t_audio_encoder(payload_id, ptime, user_config) { _codec = CODEC_G711_ULAW; if (ptime == 0) _ptime = PTIME_G711_ULAW; _max_payload_size = audio_sample_rate(_codec)/1000 * _ptime; } uint16 t_g711u_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { assert(nsamples <= payload_size); silence = false; for (int i = 0; i < nsamples; i++) { payload[i] = linear2ulaw(sample_buf[i]); } return nsamples; } ////////////////////////////////////////// // class t_gsm_audio_encoder ////////////////////////////////////////// t_gsm_audio_encoder::t_gsm_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config) : t_audio_encoder(payload_id, PTIME_GSM, user_config) { _codec = CODEC_GSM; _max_payload_size = 33; gsm_encoder = gsm_create(); } t_gsm_audio_encoder::~t_gsm_audio_encoder() { gsm_destroy(gsm_encoder); } uint16 t_gsm_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { assert(payload_size >= _max_payload_size); silence = false; gsm_encode(gsm_encoder, sample_buf, payload); return _max_payload_size; } #ifdef HAVE_SPEEX ////////////////////////////////////////// // class t_speex_audio_encoder ////////////////////////////////////////// t_speex_audio_encoder::t_speex_audio_encoder(uint16 payload_id, uint16 ptime, t_mode mode, t_user *user_config) : t_audio_encoder(payload_id, PTIME_SPEEX, user_config) { speex_bits_init(&speex_bits); _mode = mode; switch (mode) { case MODE_NB: _codec = CODEC_SPEEX_NB; speex_enc_state = speex_encoder_init(&speex_nb_mode); break; case MODE_WB: _codec = CODEC_SPEEX_WB; speex_enc_state = speex_encoder_init(&speex_wb_mode); break; case MODE_UWB: _codec = CODEC_SPEEX_UWB; speex_enc_state = speex_encoder_init(&speex_uwb_mode); break; default: assert(false); } int arg; // Bit rate type switch (_user_config->get_speex_bit_rate_type()) { case BIT_RATE_CBR: arg = 0; speex_encoder_ctl(speex_enc_state, SPEEX_SET_VBR, &arg); break; case BIT_RATE_VBR: arg = 1; speex_encoder_ctl(speex_enc_state, SPEEX_SET_VBR, &arg); break; case BIT_RATE_ABR: if (_codec == CODEC_SPEEX_NB) { arg = user_config->get_speex_abr_nb(); speex_encoder_ctl(speex_enc_state, SPEEX_SET_ABR, &arg); } else { arg = user_config->get_speex_abr_wb(); speex_encoder_ctl(speex_enc_state, SPEEX_SET_ABR, &arg); } break; default: assert(false); } _max_payload_size = 1500; /*** ENCODER OPTIONS ***/ // Discontinuos trasmission arg = (_user_config->get_speex_dtx() ? 1 : 0); speex_encoder_ctl(speex_enc_state, SPEEX_SET_DTX, &arg); // Quality arg = _user_config->get_speex_quality(); if (_user_config->get_speex_bit_rate_type() == BIT_RATE_VBR) speex_encoder_ctl(speex_enc_state, SPEEX_SET_VBR_QUALITY, &arg); else speex_encoder_ctl(speex_enc_state, SPEEX_SET_QUALITY, &arg); // Complexity arg = _user_config->get_speex_complexity(); speex_encoder_ctl(speex_enc_state, SPEEX_SET_COMPLEXITY, &arg); } t_speex_audio_encoder::~t_speex_audio_encoder() { speex_bits_destroy(&speex_bits); speex_encoder_destroy(speex_enc_state); } uint16 t_speex_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { assert(payload_size >= _max_payload_size); silence = false; speex_bits_reset(&speex_bits); if (speex_encode_int(speex_enc_state, sample_buf, &speex_bits) == 0) silence = true; return speex_bits_write(&speex_bits, (char *)payload, payload_size); } #endif #ifdef HAVE_ILBC ////////////////////////////////////////// // class t_ilbc_audio_encoder ////////////////////////////////////////// t_ilbc_audio_encoder::t_ilbc_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config) : t_audio_encoder(payload_id, (ptime < 25 ? 20 : 30), user_config) { _codec = CODEC_ILBC; _mode = _ptime; if (_mode == 20) { _max_payload_size = NO_OF_BYTES_20MS; } else { _max_payload_size = NO_OF_BYTES_30MS; } initEncode(&_ilbc_encoder, _mode); } uint16 t_ilbc_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { assert(payload_size >= _max_payload_size); assert(nsamples == _ilbc_encoder.blockl); silence = false; float block[nsamples]; for (int i = 0; i < nsamples; i++) { block[i] = static_cast(sample_buf[i]); } iLBC_encode((unsigned char*)payload, block, &_ilbc_encoder); return _ilbc_encoder.no_of_bytes; } #endif ////////////////////////////////////////// // class t_g726_encoder ////////////////////////////////////////// t_g726_audio_encoder::t_g726_audio_encoder(uint16 payload_id, uint16 ptime, t_bit_rate bit_rate, t_user *user_config) : t_audio_encoder(payload_id, ptime, user_config) { _bit_rate = bit_rate; switch (bit_rate) { case BIT_RATE_16: _codec = CODEC_G726_16; break; case BIT_RATE_24: _codec = CODEC_G726_24; break; case BIT_RATE_32: _codec = CODEC_G726_32; break; case BIT_RATE_40: _codec = CODEC_G726_40; break; default: assert(false); } if (ptime == 0) _ptime = PTIME_G726; _max_payload_size = audio_sample_rate(_codec)/1000 * _ptime; _packing = user_config->get_g726_packing(); g72x_init_state(&_state); } uint16 t_g726_audio_encoder::encode_16(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size) { assert(nsamples % 4 == 0); assert(nsamples / 4 <= payload_size); for (int i = 0; i < nsamples; i += 4) { payload[i >> 2] = 0; for (int j = 0; j < 4; j++) { uint8 v = static_cast(g723_16_encoder(sample_buf[i+j], AUDIO_ENCODING_LINEAR, &_state)); if (_packing == G726_PACK_RFC3551) { payload[i >> 2] |= v << (j * 2); } else { payload[i >> 2] |= v << ((3-j) * 2); } } } return nsamples >> 2; } uint16 t_g726_audio_encoder::encode_24(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size) { assert(nsamples % 8 == 0); assert(nsamples / 8 * 3 <= payload_size); for (int i = 0; i < nsamples; i += 8) { uint32 v = 0; for (int j = 0; j < 8; j++) { if (_packing == G726_PACK_RFC3551) { v |= static_cast(g723_24_encoder(sample_buf[i+j], AUDIO_ENCODING_LINEAR, &_state)) << (j * 3); } else { v |= static_cast(g723_24_encoder(sample_buf[i+j], AUDIO_ENCODING_LINEAR, &_state)) << ((7-j) * 3); } } payload[(i >> 3) * 3] = static_cast(v & 0xff); payload[(i >> 3) * 3 + 1] = static_cast((v >> 8) & 0xff); payload[(i >> 3) * 3 + 2] = static_cast((v >> 16) & 0xff); } return (nsamples >> 3) * 3; } uint16 t_g726_audio_encoder::encode_32(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size) { assert(nsamples % 2 == 0); assert(nsamples / 2 <= payload_size); for (int i = 0; i < nsamples; i += 2) { payload[i >> 1] = 0; for (int j = 0; j < 2; j++) { uint8 v = static_cast(g721_encoder(sample_buf[i+j], AUDIO_ENCODING_LINEAR, &_state)); if (_packing == G726_PACK_RFC3551) { payload[i >> 1] |= v << (j * 4); } else { payload[i >> 1] |= v << ((1-j) * 4); } } } return nsamples >> 1; } uint16 t_g726_audio_encoder::encode_40(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size) { assert(nsamples % 8 == 0); assert(nsamples / 8 * 5 <= payload_size); for (int i = 0; i < nsamples; i += 8) { uint64 v = 0; for (int j = 0; j < 8; j++) { if (_packing == G726_PACK_RFC3551) { v |= static_cast(g723_40_encoder(sample_buf[i+j], AUDIO_ENCODING_LINEAR, &_state)) << (j * 5); } else { v |= static_cast(g723_40_encoder(sample_buf[i+j], AUDIO_ENCODING_LINEAR, &_state)) << ((7-j) * 5); } } payload[(i >> 3) * 5] = static_cast(v & 0xff); payload[(i >> 3) * 5 + 1] = static_cast((v >> 8) & 0xff); payload[(i >> 3) * 5 + 2] = static_cast((v >> 16) & 0xff); payload[(i >> 3) * 5 + 3] = static_cast((v >> 24) & 0xff); payload[(i >> 3) * 5 + 4] = static_cast((v >> 32) & 0xff); } return (nsamples >> 3) * 5; } uint16 t_g726_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { silence = false; switch (_bit_rate) { case BIT_RATE_16: return encode_16(sample_buf, nsamples, payload, payload_size); case BIT_RATE_24: return encode_24(sample_buf, nsamples, payload, payload_size); case BIT_RATE_32: return encode_32(sample_buf, nsamples, payload, payload_size); case BIT_RATE_40: return encode_40(sample_buf, nsamples, payload, payload_size); default: assert(false); } return 0; } twinkle-1.4.2/src/audio/audio_decoder.cpp0000644000175000001440000003165111134630270015275 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "audio_decoder.h" #include "log.h" #ifdef HAVE_ILBC #ifndef HAVE_ILBC_CPP extern "C" { #endif #include #ifndef HAVE_ILBC_CPP } #endif #endif ////////////////////////////////////////// // class t_audio_decoder ////////////////////////////////////////// t_audio_decoder::t_audio_decoder(uint16 default_ptime, bool plc, t_user *user_config) : _default_ptime(default_ptime), _plc(plc), _user_config(user_config) {} t_audio_codec t_audio_decoder::get_codec(void) const { return _codec; } uint16 t_audio_decoder::get_default_ptime(void) const { return _default_ptime; } bool t_audio_decoder::has_plc(void) const { return _plc; } uint16 t_audio_decoder::conceal(int16 *pcm_buf, uint16 pcm_buf_size) { return 0; } ////////////////////////////////////////// // class t_g711a_audio_decoder ////////////////////////////////////////// t_g711a_audio_decoder::t_g711a_audio_decoder(uint16 default_ptime, t_user *user_config) : t_audio_decoder(default_ptime, false, user_config) { _codec = CODEC_G711_ALAW; if (default_ptime == 0) { _default_ptime = PTIME_G711_ALAW; } } uint16 t_g711a_audio_decoder::get_ptime(uint16 payload_size) const { return payload_size / (audio_sample_rate(_codec) / 1000); } uint16 t_g711a_audio_decoder::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(pcm_buf_size >= payload_size); for (int i = 0; i < payload_size; i++) { pcm_buf[i] = alaw2linear(payload[i]); } return payload_size; } bool t_g711a_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const { return payload_size <= sample_buf_size; } ////////////////////////////////////////// // class t_g711u_audio_decoder ////////////////////////////////////////// t_g711u_audio_decoder::t_g711u_audio_decoder(uint16 default_ptime, t_user *user_config) : t_audio_decoder(default_ptime, false, user_config) { _codec = CODEC_G711_ULAW; if (default_ptime == 0) { _default_ptime = PTIME_G711_ULAW; } } uint16 t_g711u_audio_decoder::get_ptime(uint16 payload_size) const { return payload_size / (audio_sample_rate(_codec) / 1000); } uint16 t_g711u_audio_decoder::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(pcm_buf_size >= payload_size); for (int i = 0; i < payload_size; i++) { pcm_buf[i] = ulaw2linear(payload[i]); } return payload_size; } bool t_g711u_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const { return payload_size <= sample_buf_size; } ////////////////////////////////////////// // class t_gsm_audio_decoder ////////////////////////////////////////// t_gsm_audio_decoder::t_gsm_audio_decoder(t_user *user_config) : t_audio_decoder(PTIME_GSM, false, user_config) { _codec = CODEC_GSM; gsm_decoder = gsm_create(); } t_gsm_audio_decoder::~t_gsm_audio_decoder() { gsm_destroy(gsm_decoder); } uint16 t_gsm_audio_decoder::get_ptime(uint16 payload_size) const { return get_default_ptime(); } uint16 t_gsm_audio_decoder::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(pcm_buf_size >= 160); gsm_decode(gsm_decoder, payload, pcm_buf); return 160; } bool t_gsm_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const { return payload_size == 33; } #ifdef HAVE_SPEEX ////////////////////////////////////////// // class t_speex_audio_decoder ////////////////////////////////////////// t_speex_audio_decoder::t_speex_audio_decoder(t_mode mode, t_user *user_config) : t_audio_decoder(0, true, user_config) { speex_bits_init(&speex_bits); _mode = mode; switch (mode) { case MODE_NB: _codec = CODEC_SPEEX_NB; speex_dec_state = speex_decoder_init(&speex_nb_mode); break; case MODE_WB: _codec = CODEC_SPEEX_WB; speex_dec_state = speex_decoder_init(&speex_wb_mode); break; case MODE_UWB: _codec = CODEC_SPEEX_UWB; speex_dec_state = speex_decoder_init(&speex_uwb_mode); break; default: assert(false); } int frame_size = 0; speex_decoder_ctl(speex_dec_state, SPEEX_GET_FRAME_SIZE, &frame_size); // Initialize decoder with user settings int arg = (user_config->get_speex_penh() ? 1 : 0); speex_decoder_ctl(speex_dec_state, SPEEX_SET_ENH, &arg); _default_ptime = frame_size / (audio_sample_rate(_codec) / 1000); } t_speex_audio_decoder::~t_speex_audio_decoder() { speex_bits_destroy(&speex_bits); speex_decoder_destroy(speex_dec_state); } uint16 t_speex_audio_decoder::get_ptime(uint16 payload_size) const { return get_default_ptime(); } uint16 t_speex_audio_decoder::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { int retval; int speex_frame_size; speex_decoder_ctl(speex_dec_state, SPEEX_GET_FRAME_SIZE, &speex_frame_size); assert(pcm_buf_size >= speex_frame_size); speex_bits_read_from(&speex_bits, reinterpret_cast(payload), payload_size); retval = speex_decode_int(speex_dec_state, &speex_bits, pcm_buf); if (retval < 0) { LOG_SPEEX_ERROR("t_speex_audio_decoder::decode", "speex_decode_int", retval); return 0; } return speex_frame_size; } uint16 t_speex_audio_decoder::conceal(int16 *pcm_buf, uint16 pcm_buf_size) { int retval; int speex_frame_size; speex_decoder_ctl(speex_dec_state, SPEEX_GET_FRAME_SIZE, &speex_frame_size); assert(pcm_buf_size >= speex_frame_size); retval = speex_decode_int(speex_dec_state, NULL, pcm_buf); if (retval < 0) { LOG_SPEEX_ERROR("t_speex_audio_decoder::conceal", "speex_decode_int", retval); return 0; } return speex_frame_size; } bool t_speex_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const { return true; } #endif #ifdef HAVE_ILBC ////////////////////////////////////////// // class t_ilbc_audio_decoder ////////////////////////////////////////// t_ilbc_audio_decoder::t_ilbc_audio_decoder(uint16 default_ptime, t_user *user_config) : t_audio_decoder(default_ptime, true, user_config) { _codec = CODEC_ILBC; _last_received_ptime = 0; initDecode(&_ilbc_decoder_20, 20, 1); initDecode(&_ilbc_decoder_30, 30, 1); } uint16 t_ilbc_audio_decoder::get_ptime(uint16 payload_size) const { if (payload_size == NO_OF_BYTES_20MS) { return 20; } else { return 30; } } uint16 t_ilbc_audio_decoder::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { float sample; float block[BLOCKL_MAX]; int block_len; if (get_ptime(payload_size) == 20) { block_len = BLOCKL_20MS; assert(pcm_buf_size >= block_len); iLBC_decode(block, (unsigned char*)payload, &_ilbc_decoder_20, 1); _last_received_ptime = 20; } else { block_len = BLOCKL_30MS; assert(pcm_buf_size >= block_len); iLBC_decode(block, (unsigned char*)payload, &_ilbc_decoder_30, 1); _last_received_ptime = 30; } for (int i = 0; i < block_len; i++) { sample = block[i]; if (sample < MIN_SAMPLE) sample = MIN_SAMPLE; if (sample > MAX_SAMPLE) sample = MAX_SAMPLE; pcm_buf[i] = static_cast(sample); } return block_len; } uint16 t_ilbc_audio_decoder::conceal(int16 *pcm_buf, uint16 pcm_buf_size) { float sample; float block[BLOCKL_MAX]; int block_len; if (_last_received_ptime == 0) return 0; if (_last_received_ptime == 20) { block_len = BLOCKL_20MS; assert(pcm_buf_size >= block_len); iLBC_decode(block, NULL, &_ilbc_decoder_20, 0); } else { block_len = BLOCKL_30MS; assert(pcm_buf_size >= block_len); iLBC_decode(block, NULL, &_ilbc_decoder_30, 0); } for (int i = 0; i < block_len; i++) { sample = block[i]; if (sample < MIN_SAMPLE) sample = MIN_SAMPLE; if (sample > MAX_SAMPLE) sample = MAX_SAMPLE; pcm_buf[i] = static_cast(sample); } return block_len; } bool t_ilbc_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const { return payload_size == NO_OF_BYTES_20MS || payload_size == NO_OF_BYTES_30MS; } #endif ////////////////////////////////////////// // class t_g726_audio_decoder ////////////////////////////////////////// t_g726_audio_decoder::t_g726_audio_decoder(t_bit_rate bit_rate, uint16 default_ptime, t_user *user_config) : t_audio_decoder(default_ptime, false, user_config) { _bit_rate = bit_rate; if (default_ptime == 0) { _default_ptime = PTIME_G726; } switch (_bit_rate) { case BIT_RATE_16: _codec = CODEC_G726_16; _bits_per_sample = 2; break; case BIT_RATE_24: _codec = CODEC_G726_24; _bits_per_sample = 3; break; case BIT_RATE_32: _codec = CODEC_G726_32; _bits_per_sample = 4; break; case BIT_RATE_40: _codec = CODEC_G726_40; _bits_per_sample = 5; break; default: assert(false); } _packing = user_config->get_g726_packing(); g72x_init_state(&_state); } uint16 t_g726_audio_decoder::get_ptime(uint16 payload_size) const { return (payload_size * 8 / _bits_per_sample) / (audio_sample_rate(_codec) / 1000); } uint16 t_g726_audio_decoder::decode_16(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(payload_size * 4 <= pcm_buf_size); for (int i = 0; i < payload_size; i++) { for (int j = 0; j < 4; j++) { uint8 w; if (_packing == G726_PACK_RFC3551) { w = (payload[i] >> (j*2)) & 0x3; } else { w = (payload[i] >> ((3-j)*2)) & 0x3; } pcm_buf[4*i+j] = g723_16_decoder( w, AUDIO_ENCODING_LINEAR, &_state); } } return payload_size * 4; } uint16 t_g726_audio_decoder::decode_24(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(payload_size % 3 == 0); assert(payload_size * 8 / 3 <= pcm_buf_size); for (int i = 0; i < payload_size; i += 3) { uint32 v = (static_cast(payload[i+2]) << 16) | (static_cast(payload[i+1]) << 8) | static_cast(payload[i]); for (int j = 0; j < 8; j++) { uint8 w; if (_packing == G726_PACK_RFC3551) { w = (v >> (j*3)) & 0x7; } else { w = (v >> ((7-j)*3)) & 0x7; } pcm_buf[8*(i/3)+j] = g723_24_decoder( w, AUDIO_ENCODING_LINEAR, &_state); } } return payload_size * 8 / 3; } uint16 t_g726_audio_decoder::decode_32(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(payload_size * 2 <= pcm_buf_size); for (int i = 0; i < payload_size; i++) { for (int j = 0; j < 2; j++) { uint8 w; if (_packing == G726_PACK_RFC3551) { w = (payload[i] >> (j*4)) & 0xf; } else { w = (payload[i] >> ((1-j)*4)) & 0xf; } pcm_buf[2*i+j] = g721_decoder( w, AUDIO_ENCODING_LINEAR, &_state); } } return payload_size * 2; } uint16 t_g726_audio_decoder::decode_40(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { assert(payload_size % 5 == 0); assert(payload_size * 8 / 5 <= pcm_buf_size); for (int i = 0; i < payload_size; i += 5) { uint64 v = (static_cast(payload[i+4]) << 32) | (static_cast(payload[i+3]) << 24) | (static_cast(payload[i+2]) << 16) | (static_cast(payload[i+1]) << 8) | static_cast(payload[i]); for (int j = 0; j < 8; j++) { uint8 w; if (_packing == G726_PACK_RFC3551) { w = (v >> (j*5)) & 0x1f; } else { w = (v >> ((7-j)*5)) & 0x1f; } pcm_buf[8*(i/5)+j] = g723_40_decoder( w, AUDIO_ENCODING_LINEAR, &_state); } } return payload_size * 8 / 5; } uint16 t_g726_audio_decoder::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) { switch (_bit_rate) { case BIT_RATE_16: return decode_16(payload, payload_size, pcm_buf, pcm_buf_size); break; case BIT_RATE_24: return decode_24(payload, payload_size, pcm_buf, pcm_buf_size); break; case BIT_RATE_32: return decode_32(payload, payload_size, pcm_buf, pcm_buf_size); break; case BIT_RATE_40: return decode_40(payload, payload_size, pcm_buf, pcm_buf_size); break; default: assert(false); } return 0; } bool t_g726_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const { switch (_bit_rate) { case BIT_RATE_24: // Payload size must be multiple of 3 if (payload_size % 3 != 0) return false; break; case BIT_RATE_40: // Payload size must be multiple of 5 if (payload_size % 5 != 0) return false; break; default: break; } return (payload_size * 8 / _bits_per_sample ) <= sample_buf_size; } twinkle-1.4.2/src/audio/dtmf_player.h0000644000175000001440000000604011127714046014462 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Classes to generate RTP payloads for DTMF tones. #ifndef _DTMF_PLAYER_H #define _DTMF_PLAYER_H #include #include "twinkle_config.h" #include "audio_encoder.h" #include "freq_gen.h" #include "user.h" // Forward declarations class t_audio_rx; // Abstract class defintion for DTMF player class t_dtmf_player { protected: // Audio receiver owning the DTMF player. t_audio_rx *_audio_rx; t_user *_user_config; t_audio_encoder *_audio_encoder; // Settings for current DTMF tone bool _dtmf_pause; // indicates if playing is in the pause phase bool _dtmf_stop; // indicates if DTMF should be stopped uint8 _dtmf_current; // Currently played DTMF tone uint32 _dtmf_timestamp; // RTP timestamp (start of tone) uint16 _dtmf_duration; // Duration of the tone currently played uint16 _nsamples; // number of samples taken per packet public: t_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp, uint16 nsamples); virtual ~t_dtmf_player() {}; // Get payload for the DTMF tone // rtp_timestamp will be set with the timestamp value to be put in the // RTP header // Returns the payload size virtual uint16 get_payload(uint8 *payload, uint16 payload_size, uint32 timestamp, uint32 &rtp_timestamp) = 0; uint32 get_timestamp(void); // Returns true when last payload has been delivered. bool finished(void); }; // DTMF player for RFC 2833 RTP telephone events class t_rtp_event_dtmf_player : public t_dtmf_player { public: t_rtp_event_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp, uint16 nsamples); virtual uint16 get_payload(uint8 *payload, uint16 payload_size, uint32 timestamp, uint32 &rtp_timestamp); }; // DTMF player for inband tones class t_inband_dtmf_player : public t_dtmf_player { private: // Frequency generator to generate the inband tones. t_freq_gen _freq_gen; public: t_inband_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp, uint16 nsamples); virtual uint16 get_payload(uint8 *payload, uint16 payload_size, uint32 timestamp, uint32 &rtp_timestamp); }; #endif twinkle-1.4.2/src/audio/dtmf_player.cpp0000644000175000001440000001321411134631574015020 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "dtmf_player.h" #include "audio_rx.h" #include "line.h" #include "rtp_telephone_event.h" #include "log.h" ///////////////////////////////////////// // class t_dtmf_player ///////////////////////////////////////// t_dtmf_player::t_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp, uint16 nsamples) : _audio_rx(audio_rx), _user_config(user_config), _audio_encoder(audio_encoder), _dtmf_pause(false), _dtmf_stop(false), _dtmf_current(dtmf_tone), _dtmf_timestamp(dtmf_timestamp), _dtmf_duration(0), _nsamples(nsamples) {} uint32 t_dtmf_player::get_timestamp(void) { return _dtmf_timestamp; } bool t_dtmf_player::finished(void) { return _dtmf_stop; } ///////////////////////////////////////// // class t_rtp_event_dtmf_player ///////////////////////////////////////// t_rtp_event_dtmf_player::t_rtp_event_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp, uint16 nsamples) : t_dtmf_player(audio_rx, audio_encoder, user_config, dtmf_tone, dtmf_timestamp, nsamples) { } uint16 t_rtp_event_dtmf_player::get_payload(uint8 *payload, uint16 payload_size, uint32 timestamp, uint32 &rtp_timestamp) { t_rtp_telephone_event *dtmf_payload = (t_rtp_telephone_event *)payload; assert(sizeof(t_rtp_telephone_event) <= payload_size); // RFC 2833 3.5, 3.6 dtmf_payload->set_event(_dtmf_current); dtmf_payload->set_reserved(false); dtmf_payload->set_volume(_user_config->get_dtmf_volume()); if (_dtmf_pause) { // Trailing pause phase of a DTMF tone // Repeat the last packet dtmf_payload->set_end(true); int pause_duration = timestamp - _dtmf_timestamp - _dtmf_duration + _nsamples; if (pause_duration / _nsamples * _audio_encoder->get_ptime() >= _user_config->get_dtmf_pause()) { // This is the last packet to be sent for the // current DTMF tone. _dtmf_stop = true; log_file->write_header("t_rtp_event_dtmf_player::get_payload", LOG_NORMAL); log_file->write_raw("Audio rx line "); log_file->write_raw(_audio_rx->get_line()->get_line_number()+1); log_file->write_raw(": finish DTMF event - "); log_file->write_raw(_dtmf_current); log_file->write_endl(); log_file->write_footer(); } } else { // Play phase of a DTMF tone // The duration counts from the start of the tone. _dtmf_duration = timestamp - _dtmf_timestamp + _nsamples; // Check if the tone must end if (_dtmf_duration / _nsamples * _audio_encoder->get_ptime() >= _user_config->get_dtmf_duration()) { dtmf_payload->set_end(true); _dtmf_pause = true; } else { dtmf_payload->set_end(false); } } dtmf_payload->set_duration(_dtmf_duration); rtp_timestamp = _dtmf_timestamp; return sizeof(t_rtp_telephone_event); } ///////////////////////////////////////// // class t_inband_dtmf_player ///////////////////////////////////////// t_inband_dtmf_player::t_inband_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp, uint16 nsamples) : t_dtmf_player(audio_rx, audio_encoder, user_config, dtmf_tone, dtmf_timestamp, nsamples), _freq_gen(dtmf_tone, -(user_config->get_dtmf_volume())) { } uint16 t_inband_dtmf_player::get_payload(uint8 *payload, uint16 payload_size, uint32 timestamp, uint32 &rtp_timestamp) { int16 sample_buf[_nsamples]; if (_dtmf_pause) { int pause_duration = timestamp - _dtmf_timestamp - _dtmf_duration + _nsamples; memset(sample_buf, 0, _nsamples * 2); if (pause_duration / _nsamples * _audio_encoder->get_ptime() >= _user_config->get_dtmf_pause()) { // This is the last packet to be sent for the // current DTMF tone. _dtmf_stop = true; log_file->write_header("t_inband_dtmf_player::get_payload", LOG_NORMAL); log_file->write_raw("Audio rx line "); log_file->write_raw(_audio_rx->get_line()->get_line_number()+1); log_file->write_raw(": finish DTMF event - "); log_file->write_raw(_dtmf_current); log_file->write_endl(); log_file->write_footer(); } } else { // Timestamp and interval for _freq_gen must be in usec uint32 ts_start = (timestamp - _dtmf_timestamp) * 1000000 / _audio_encoder->get_sample_rate(); _freq_gen.get_samples(sample_buf, _nsamples, ts_start, 1000000.0 / _audio_encoder->get_sample_rate()); // The duration counts from the start of the tone. _dtmf_duration = timestamp - _dtmf_timestamp + _nsamples; // Check if the tone must end if (_dtmf_duration / _nsamples * _audio_encoder->get_ptime() >= _user_config->get_dtmf_duration()) { _dtmf_pause = true; } } // Encode audio samples bool silence; rtp_timestamp = timestamp; return _audio_encoder->encode(sample_buf, _nsamples, payload, payload_size, silence); } twinkle-1.4.2/src/audio/g711.h0000644000175000001440000000063011127714046012632 00000000000000#ifndef _G711_H #define _G711_H // The linear PCM codes are signed 16 bit values // G.711 A-law unsigned char linear2alaw(short pcm_val); short alaw2linear(unsigned char a_val); // G.711 u-law unsigned char linear2ulaw(short pcm_val); short ulaw2linear(unsigned char u_val); // A-law <-> u-law conversions unsigned char alaw2ulaw(unsigned char aval); unsigned char ulaw2alaw(unsigned char uval); #endif twinkle-1.4.2/src/audio/g72x.h0000644000175000001440000001107411127714046012746 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g72x.h * * Header file for CCITT conversion routines. * */ #ifndef _G72X_H #define _G72X_H #define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */ #define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */ #define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */ /* * The following is the definition of the state structure * used by the G.721/G.723 encoder and decoder to preserve their internal * state between successive calls. The meanings of the majority * of the state structure fields are explained in detail in the * CCITT Recommendation G.721. The field names are essentially indentical * to variable names in the bit level description of the coding algorithm * included in this Recommendation. */ struct g72x_state { long yl; /* Locked or steady state step size multiplier. */ short yu; /* Unlocked or non-steady state step size multiplier. */ short dms; /* Short term energy estimate. */ short dml; /* Long term energy estimate. */ short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ short a[2]; /* Coefficients of pole portion of prediction filter. */ short b[6]; /* Coefficients of zero portion of prediction filter. */ short pk[2]; /* * Signs of previous two samples of a partially * reconstructed signal. */ short dq[6]; /* * Previous 6 samples of the quantized difference * signal represented in an internal floating point * format. */ short sr[2]; /* * Previous 2 samples of the quantized difference * signal represented in an internal floating point * format. */ char td; /* delayed tone detect, new in 1988 version */ }; int predictor_zero(struct g72x_state *state_ptr); int predictor_pole(struct g72x_state *state_ptr); int step_size(struct g72x_state *state_ptr); int quantize( int d, /* Raw difference signal sample */ int y, /* Step size multiplier */ short *table, /* quantization table */ int size); /* table size of short integers */ int reconstruct( int sign, /* 0 for non-negative value */ int dqln, /* G.72x codeword */ int y); /* Step size multiplier */ void update( int code_size, /* distinguish 723_40 with others */ int y, /* quantizer step size */ int wi, /* scale factor multiplier */ int fi, /* for long/short term energies */ int dq, /* quantized prediction difference */ int sr, /* reconstructed signal */ int dqsez, /* difference from 2-pole predictor */ struct g72x_state *state_ptr); int tandem_adjust_alaw( int sr, /* decoder output linear PCM sample */ int se, /* predictor estimate sample */ int y, /* quantizer step size */ int i, /* decoder input code */ int sign, short *qtab); int tandem_adjust_ulaw( int sr, /* decoder output linear PCM sample */ int se, /* predictor estimate sample */ int y, /* quantizer step size */ int i, /* decoder input code */ int sign, short *qtab); void g72x_init_state(struct g72x_state *); int g721_encoder( int sample, int in_coding, struct g72x_state *state_ptr); int g721_decoder( int code, int out_coding, struct g72x_state *state_ptr); int g723_16_encoder( int sample, int in_coding, struct g72x_state *state_ptr); int g723_16_decoder( int code, int out_coding, struct g72x_state *state_ptr); int g723_24_encoder( int sample, int in_coding, struct g72x_state *state_ptr); int g723_24_decoder( int code, int out_coding, struct g72x_state *state_ptr); int g723_40_encoder( int sample, int in_coding, struct g72x_state *state_ptr); int g723_40_decoder( int code, int out_coding, struct g72x_state *state_ptr); #endif /* !_G72X_H */ twinkle-1.4.2/src/audio/tone_gen.h0000644000175000001440000000400211127714046013746 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TONE_GEN_H #define _TONE_GEN_H #include #include #include #include #include "sys_settings.h" #include "threads/mutex.h" #include "threads/thread.h" #include "threads/sema.h" #ifndef _AUDIO_DEVICE_H class t_audio_io; #endif using namespace std; class t_tone_gen { private: string wav_filename; // name of wav file SNDFILE *wav_file; // SNDFILE pointer to wav file SF_INFO wav_info; // Information about format of the wav file t_audio_device dev_tone; // device to play tone t_audio_io* aio; // soundcard bool valid; // wav file is in a valid format bool stop_playing; // indicates if playing should stop t_thread *thr_play; // playing thread bool loop; // repeat playing int pause; // pause (ms) between repetitions short *data_buf; // buffer for reading sound samples t_semaphore sema_finished; // indicates if playing finished public: t_tone_gen(const string &filename, const t_audio_device &_dev_tone); ~t_tone_gen(); bool is_valid(void) const; // Play the wav file // loop = true -> repeat playing // pause is pause in ms between repetitions void start_play_thread(bool _loop, int _pause); void play(void); // Stop playing void stop(void); }; #endif twinkle-1.4.2/src/audio/media_buffer.h0000644000175000001440000000425611127714046014573 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MEDIA_BUFFER_H #define _MEDIA_BUFFER_H #include "threads/mutex.h" // A buffer for buffering media streams. // Used for conference calls to buffer one stream that needs to be // mixed with the main stream. class t_media_buffer { private: // The buffer. It is used as a ring buffer unsigned char *buffer; // Size of the buffer int buf_size; // Begin and end position of the buffer content. // pos_end points to the last byte of content. int pos_start; int pos_end; // Inidicates if buffer is empty bool empty; // Mutex to protect operations on the buffer t_recursive_mutex mtx; // Prevent this constructor from being used. t_media_buffer() {}; public: // Create a media buffer of size size. t_media_buffer(int size); ~t_media_buffer(); // Add data to buffer. If there is more data than buffer // space left, then old content will be removed from the // buffer. // - data is the data to be added // - len is the number of bytes to be added void add(unsigned char *data, int len); // Get data from the buffer. If there is not enough data // in the buffer, then no data is retrieved at all. // False is returned if data cannot be retrieved. // - data must point to a buffer of at least size len // - len is the amount of bytes to be retrieved bool get(unsigned char *data, int len); // Return the number of bytes contained by the buffer. int size_content(void); }; #endif twinkle-1.4.2/src/audio/Makefile.am0000644000175000001440000000174511134651055014044 00000000000000AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ $(CCRTP_CFLAGS) \ $(XML2_CFLAGS) noinst_LIBRARIES = libaudio.a libaudio_a_SOURCES =\ audio_device.cpp\ audio_decoder.cpp\ audio_encoder.cpp\ audio_codecs.cpp\ audio_rx.cpp\ audio_session.cpp\ audio_tx.cpp\ dtmf_player.cpp\ freq_gen.cpp\ g711.cpp\ g721.cpp\ g723_16.cpp\ g723_24.cpp\ g723_40.cpp\ g72x.cpp\ media_buffer.cpp\ rtp_telephone_event.cpp\ tone_gen.cpp\ twinkle_rtp_session.cpp\ twinkle_zrtp_ui.cpp\ audio_device.h\ audio_decoder.h\ audio_encoder.h\ audio_codecs.h\ audio_rx.h\ audio_session.h\ audio_tx.h\ dtmf_player.h\ freq_gen.h\ g711.h\ g72x.h\ media_buffer.h\ rtp_telephone_event.h\ tone_gen.h\ twinkle_rtp_session.h\ twinkle_zrtp_ui.h SUBDIRS = gsm EXTRA_DIST = README_G711 twinkle-1.4.2/src/audio/Makefile.in0000644000175000001440000005371011151323405014046 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/audio DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libaudio_a_AR = $(AR) $(ARFLAGS) libaudio_a_LIBADD = am_libaudio_a_OBJECTS = audio_device.$(OBJEXT) audio_decoder.$(OBJEXT) \ audio_encoder.$(OBJEXT) audio_codecs.$(OBJEXT) \ audio_rx.$(OBJEXT) audio_session.$(OBJEXT) audio_tx.$(OBJEXT) \ dtmf_player.$(OBJEXT) freq_gen.$(OBJEXT) g711.$(OBJEXT) \ g721.$(OBJEXT) g723_16.$(OBJEXT) g723_24.$(OBJEXT) \ g723_40.$(OBJEXT) g72x.$(OBJEXT) media_buffer.$(OBJEXT) \ rtp_telephone_event.$(OBJEXT) tone_gen.$(OBJEXT) \ twinkle_rtp_session.$(OBJEXT) twinkle_zrtp_ui.$(OBJEXT) libaudio_a_OBJECTS = $(am_libaudio_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libaudio_a_SOURCES) DIST_SOURCES = $(libaudio_a_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ $(CCRTP_CFLAGS) \ $(XML2_CFLAGS) noinst_LIBRARIES = libaudio.a libaudio_a_SOURCES = \ audio_device.cpp\ audio_decoder.cpp\ audio_encoder.cpp\ audio_codecs.cpp\ audio_rx.cpp\ audio_session.cpp\ audio_tx.cpp\ dtmf_player.cpp\ freq_gen.cpp\ g711.cpp\ g721.cpp\ g723_16.cpp\ g723_24.cpp\ g723_40.cpp\ g72x.cpp\ media_buffer.cpp\ rtp_telephone_event.cpp\ tone_gen.cpp\ twinkle_rtp_session.cpp\ twinkle_zrtp_ui.cpp\ audio_device.h\ audio_decoder.h\ audio_encoder.h\ audio_codecs.h\ audio_rx.h\ audio_session.h\ audio_tx.h\ dtmf_player.h\ freq_gen.h\ g711.h\ g72x.h\ media_buffer.h\ rtp_telephone_event.h\ tone_gen.h\ twinkle_rtp_session.h\ twinkle_zrtp_ui.h SUBDIRS = gsm EXTRA_DIST = README_G711 all: all-recursive .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/audio/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/audio/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libaudio.a: $(libaudio_a_OBJECTS) $(libaudio_a_DEPENDENCIES) -rm -f libaudio.a $(libaudio_a_AR) libaudio.a $(libaudio_a_OBJECTS) $(libaudio_a_LIBADD) $(RANLIB) libaudio.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_codecs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_decoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_encoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_rx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_tx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtmf_player.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freq_gen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g711.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g721.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g723_16.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g723_24.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g723_40.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g72x.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/media_buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtp_telephone_event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tone_gen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twinkle_rtp_session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twinkle_zrtp_ui.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LIBRARIES) installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ clean clean-generic clean-noinstLIBRARIES clean-recursive \ ctags ctags-recursive distclean distclean-compile \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-exec install-exec-am \ install-info install-info-am install-man install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-recursive pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/audio/freq_gen.cpp0000644000175000001440000000652311127714055014303 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "freq_gen.h" #include #include #include #include "rtp_telephone_event.h" #define PI 3.141592653589793 t_freq_gen::t_freq_gen(vector frequencies, int8 db_level) { assert(frequencies.size() > 0); assert(db_level <= 0); _frequencies = frequencies; // dB = 20 * log(amplitude / 32768) // 32767 is used below as +32768 does not fit in 16 bits _amplitude = int16(pow(10.0, db_level / 20.0) * 32767 / _frequencies.size()); } t_freq_gen::t_freq_gen(uint8 dtmf, int8 db_level) : _frequencies(2) { assert(db_level <= 0); switch (dtmf) { case TEL_EV_DTMF_1: _frequencies[0] = 697; _frequencies[1] = 1209; break; case TEL_EV_DTMF_2: _frequencies[0] = 697; _frequencies[1] = 1336; break; case TEL_EV_DTMF_3: _frequencies[0] = 697; _frequencies[1] = 1477; break; case TEL_EV_DTMF_A: _frequencies[0] = 697; _frequencies[1] = 1633; break; case TEL_EV_DTMF_4: _frequencies[0] = 770; _frequencies[1] = 1209; break; case TEL_EV_DTMF_5: _frequencies[0] = 770; _frequencies[1] = 1336; break; case TEL_EV_DTMF_6: _frequencies[0] = 770; _frequencies[1] = 1477; break; case TEL_EV_DTMF_B: _frequencies[0] = 770; _frequencies[1] = 1633; break; case TEL_EV_DTMF_7: _frequencies[0] = 852; _frequencies[1] = 1209; break; case TEL_EV_DTMF_8: _frequencies[0] = 852; _frequencies[1] = 1336; break; case TEL_EV_DTMF_9: _frequencies[0] = 852; _frequencies[1] = 1477; break; case TEL_EV_DTMF_C: _frequencies[0] = 852; _frequencies[1] = 1633; break; case TEL_EV_DTMF_STAR: _frequencies[0] = 941; _frequencies[1] = 1209; break; case TEL_EV_DTMF_0: _frequencies[0] = 941; _frequencies[1] = 1336; break; case TEL_EV_DTMF_POUND: _frequencies[0] = 941; _frequencies[1] = 1477; break; case TEL_EV_DTMF_D: _frequencies[0] = 941; _frequencies[1] = 1633; break; default: assert(false); } // dB = 20 * log(amplitude / 32768) // 32767 is used below as +32768 does not fit in 16 bits _amplitude = int16(pow(10.0, db_level / 20.0) * 32767 / _frequencies.size()); } int16 t_freq_gen::get_sample(uint32 ts_usec) const { double freq_sum = 0.0; for (vector::const_iterator f = _frequencies.begin(); f != _frequencies.end(); f++) { freq_sum += sin(*f * 2.0 * PI * (double)ts_usec / 1000000.0); } return (int16)(_amplitude * freq_sum); } void t_freq_gen::get_samples(int16 *sample_buf, uint16 buf_len, uint32 ts_start, double interval) const { for (uint16 i = 0; i < buf_len; i++) { sample_buf[i] = get_sample(uint32(ts_start + interval * i)); } } twinkle-1.4.2/src/audio/media_buffer.cpp0000644000175000001440000000604211127714055015121 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "media_buffer.h" #include #include "audits/memman.h" //////////// // PUBLIC //////////// t_media_buffer::t_media_buffer(int size) { buf_size = size; empty = true; buffer = new unsigned char[size]; MEMMAN_NEW_ARRAY(buffer); pos_start = 0; pos_end = 0; } t_media_buffer::~t_media_buffer() { MEMMAN_DELETE_ARRAY(buffer); delete [] buffer; } void t_media_buffer::add(unsigned char *data, int len) { int data_start, data_end; mtx.lock(); // The amount of data should fit in the buffer. if (len > buf_size) { mtx.unlock(); return; } int current_size_content = size_content(); if (empty) { data_start = 0; data_end = len - 1; pos_start = 0; empty = false; } else { data_start = (pos_end + 1) % buf_size; data_end = (data_start + len - 1) % buf_size; } // Copy the data into the buffer if (data_end >= data_start) { memcpy(buffer + data_start, data, len); } else { // The data wraps around the end of the buffer memcpy(buffer + data_start, data, buf_size - data_start); memcpy(buffer, data + buf_size - data_start, data_end + 1); } // Check if the new data wrapped over the start of the old data. // If so, then advance the start of the old data behind the end of the new // data as new data has erased the oldest data. if (buf_size - current_size_content < len) { pos_start = (data_end + 1) % buf_size; } pos_end = data_end; mtx.unlock(); } bool t_media_buffer::get(unsigned char *data, int len) { mtx.lock(); if (len > size_content()) { mtx.unlock(); return false; } // Retrieve the data from the buffer if (pos_start + len <= buf_size) { memcpy(data, buffer + pos_start, len); } else { // The data to be retrieved wraps around the end of // the buffer. memcpy(data, buffer + pos_start, buf_size - pos_start); memcpy(data + buf_size - pos_start, buffer, len - buf_size + pos_start); } pos_start = (pos_start + len) % buf_size; // Check if buffer is empty if (pos_start == (pos_end + 1) % buf_size) { empty = true; } mtx.unlock(); return true; } int t_media_buffer::size_content(void) { int len; mtx.lock(); if (empty) { len = 0; } else if (pos_end >= pos_start) { len = pos_end - pos_start + 1; } else { len = pos_end + buf_size - pos_start + 1; } mtx.unlock(); return len; } twinkle-1.4.2/src/audio/twinkle_rtp_session.cpp0000644000175000001440000000570211127714055016620 00000000000000 /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "twinkle_rtp_session.h" #include "log.h" #include "sys_settings.h" #define TWINKLE_ZID_FILE ".twinkle.zid" t_twinkle_rtp_session::~t_twinkle_rtp_session() {} #ifdef HAVE_ZRTP void t_twinkle_rtp_session::init_zrtp(void) { string zid_filename = sys_config->get_dir_user(); zid_filename += '/'; zid_filename += TWINKLE_ZID_FILE; if (initialize(zid_filename.c_str()) >=0) { zrtp_initialized = true; return; } // ZID file initialization failed. Maybe the ZID file // is corrupt. Try to remove it if (unlink(zid_filename.c_str()) < 0) { string msg = "Failed to remove "; msg += zid_filename; log_file->write_report(msg, "t_twinkle_rtp_session::init_zrtp", LOG_NORMAL, LOG_CRITICAL); return; } // Try to initialize once more if (initialize(zid_filename.c_str()) >= 0) { zrtp_initialized = true; } else { string msg = "Failed to initialize ZRTP - "; msg += zid_filename; log_file->write_report(msg, "t_twinkle_rtp_session::init_zrtp", LOG_NORMAL, LOG_CRITICAL); } } bool t_twinkle_rtp_session::is_zrtp_initialized(void) const { return zrtp_initialized; } t_twinkle_rtp_session::t_twinkle_rtp_session(const InetHostAddress &host) : SymmetricZRTPSession(host), zrtp_initialized(false) { init_zrtp(); } t_twinkle_rtp_session::t_twinkle_rtp_session(const InetHostAddress &host, unsigned short port) : SymmetricZRTPSession(host, port) , zrtp_initialized(false) { init_zrtp(); } #else t_twinkle_rtp_session::t_twinkle_rtp_session(const InetHostAddress &host) : SymmetricRTPSession(host) { } t_twinkle_rtp_session::t_twinkle_rtp_session(const InetHostAddress &host, unsigned short port) : SymmetricRTPSession(host, port) { } #endif uint32 t_twinkle_rtp_session::getLastTimestamp(const SyncSource *src) const { if ( src && !isMine(*src) ) return 0L; recvLock.readLock(); uint32 ts = 0; if (src != NULL) { SyncSourceLink* srcm = getLink(*src); IncomingRTPPktLink* l = srcm->getFirst(); while (l) { ts = l->getTimestamp(); l = l->getSrcNext(); } } else { IncomingRTPPktLink* l = recvFirst; while (l) { ts = l->getTimestamp(); l = l->getNext(); } } recvLock.unlock(); return ts; } twinkle-1.4.2/src/audio/audio_encoder.h0000644000175000001440000001125411127714046014757 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Audio encoders #ifndef _AUDIO_ENCODER_H #define _AUDIO_ENCODER_H #include #include "twinkle_config.h" #include "audio_codecs.h" #include "user.h" #ifdef HAVE_GSM #include #else #include "gsm/inc/gsm.h" #endif #ifdef HAVE_SPEEX #include #endif #ifdef HAVE_ILBC #ifndef HAVE_ILBC_CPP extern "C" { #endif #include #ifndef HAVE_ILBC_CPP } #endif #endif // Abstract definition of an audio encoder class t_audio_encoder { protected: t_audio_codec _codec; uint16 _payload_id; // payload id for the codec uint16 _ptime; // in milliseconds uint16 _max_payload_size; // maximum size of payload t_user *_user_config; t_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config); public: virtual ~t_audio_encoder() {}; t_audio_codec get_codec(void) const; uint16 get_payload_id(void) const; uint16 get_ptime(void) const; uint16 get_sample_rate(void) const; uint16 get_max_payload_size(void) const; // Encode a 16-bit PCM sample buffer to a encoded payload // Returns the number of bytes written into the payload. // The silence flag indicates if the returned sound samples represent silence // that may be suppressed. virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) = 0; }; // G.711 A-law class t_g711a_audio_encoder : public t_audio_encoder { public: t_g711a_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config); virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence); }; // G.711 u-law class t_g711u_audio_encoder : public t_audio_encoder { public: t_g711u_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config); virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence); }; // GSM class t_gsm_audio_encoder : public t_audio_encoder { private: gsm gsm_encoder; public: t_gsm_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config); virtual ~t_gsm_audio_encoder(); virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence); }; #ifdef HAVE_SPEEX class t_speex_audio_encoder : public t_audio_encoder { public: enum t_mode { MODE_NB, // Narrow band MODE_WB, // Wide band MODE_UWB // Ultra wide band }; private: SpeexBits speex_bits; void *speex_enc_state; t_mode _mode; public: t_speex_audio_encoder(uint16 payload_id, uint16 ptime, t_mode mode, t_user *user_config); virtual ~t_speex_audio_encoder(); virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence); }; #endif #ifdef HAVE_ILBC class t_ilbc_audio_encoder : public t_audio_encoder { private: iLBC_Enc_Inst_t _ilbc_encoder; uint8 _mode; // 20, 30 ms (frame size) public: t_ilbc_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config); virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence); }; #endif class t_g726_audio_encoder : public t_audio_encoder { public: enum t_bit_rate { BIT_RATE_16, BIT_RATE_24, BIT_RATE_32, BIT_RATE_40 }; private: uint16 encode_16(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size); uint16 encode_24(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size); uint16 encode_32(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size); uint16 encode_40(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size); g72x_state _state; t_bit_rate _bit_rate; t_g726_packing _packing; public: t_g726_audio_encoder(uint16 payload_id, uint16 ptime, t_bit_rate bit_rate, t_user *user_config); virtual uint16 encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence); }; #endif twinkle-1.4.2/src/audio/audio_session.cpp0000644000175000001440000004252611127714055015364 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinkle_config.h" #include #include #include #include #include #include "audio_session.h" #include "line.h" #include "log.h" #include "sys_settings.h" #include "translator.h" #include "user.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" #ifdef HAVE_ZRTP #include "twinkle_zrtp_ui.h" #endif static t_audio_session *_audio_session; /////////// // PRIVATE /////////// bool t_audio_session::is_3way(void) const { t_line *l = get_line(); t_phone *p = l->get_phone(); return p->part_of_3way(l->get_line_number()); } t_audio_session *t_audio_session::get_peer_3way(void) const { t_line *l = get_line(); t_phone *p = l->get_phone(); t_line *peer_line = p->get_3way_peer_line(l->get_line_number()); return peer_line->get_audio_session(); } bool t_audio_session::open_dsp(void) { if (sys_config->equal_audio_dev(sys_config->get_dev_speaker(), sys_config->get_dev_mic())) { return open_dsp_full_duplex(); } return open_dsp_speaker() && open_dsp_mic(); } bool t_audio_session::open_dsp_full_duplex(void) { // Open audio device speaker = t_audio_io::open(sys_config->get_dev_speaker(), true, true, true, 1, SAMPLEFORMAT_S16, audio_sample_rate(codec), true); if (!speaker) { string msg(TRANSLATE2("CoreAudio", "Failed to open sound card")); log_file->write_report(msg, "t_audio_session::open_dsp_full_duplex", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } // Disable recording // If recording is not disabled, then the capture buffers will // already fill with data. Then when the audio_rx thread starts // to read blocks of 160 samples, it gets all these initial blocks // very quickly 1 per 12 ms I have seen. And hence the timestamps // for these blocks get out of sync with the RTP stack. // Also a large delay is introduced by this. So recording should // be enabled just before the data is read from the device. speaker->enable(true, false); mic = speaker; return true; } bool t_audio_session::open_dsp_speaker(void) { speaker = t_audio_io::open(sys_config->get_dev_speaker(), true, false, true, 1, SAMPLEFORMAT_S16, audio_sample_rate(codec), true); if (!speaker) { string msg(TRANSLATE2("CoreAudio", "Failed to open sound card")); log_file->write_report(msg, "t_audio_session::open_dsp_speaker", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } return true; } bool t_audio_session::open_dsp_mic(void) { mic = t_audio_io::open(sys_config->get_dev_mic(), false, true, true, 1, SAMPLEFORMAT_S16, audio_sample_rate(codec), true); if (!mic) { string msg(TRANSLATE2("CoreAudio", "Failed to open sound card")); log_file->write_report(msg, "t_audio_session::open_dsp_mic", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } // Disable recording // If recording is not disabled, then the capture buffers will // already fill with data. Then when the audio_rx thread starts // to read blocks of 160 samples, it gets all these initial blocks // very quickly 1 per 12 ms I have seen. And hence the timestamps // for these blocks get out of sync with the RTP stack. // Also a large delay is introduced by this. So recording should // be enabled just before the data is read from the device. speaker->enable(true, false); return true; } /////////// // PUBLIC /////////// t_audio_session::t_audio_session(t_session *_session, const string &_recv_host, unsigned short _recv_port, const string &_dst_host, unsigned short _dst_port, t_audio_codec _codec, unsigned short _ptime, const map &recv_payload2ac, const map &send_ac2payload, bool encrypt) { valid = false; session = _session; audio_rx = NULL; audio_tx = NULL; thr_audio_rx = NULL; thr_audio_tx = NULL; speaker = NULL; mic = NULL; codec = _codec; ptime = _ptime; is_encrypted = false; zrtp_sas.clear(); // Assume the SAS is confirmed. When a SAS is received from the ZRTP // stack, the confirmed flag will be cleared. zrtp_sas_confirmed = true; srtp_cipher_mode.clear(); log_file->write_header("t_audio_session::t_audio_session"); log_file->write_raw("Receive RTP from: "); log_file->write_raw(_recv_host); log_file->write_raw(":"); log_file->write_raw(_recv_port); log_file->write_endl(); log_file->write_raw("Send RTP to: "); log_file->write_raw(_dst_host); log_file->write_raw(":"); log_file->write_raw(_dst_port); log_file->write_endl(); log_file->write_footer(); t_user *user_config = get_line()->get_user(); // Create RTP session try { if (_recv_host.empty() || _recv_port == 0) { rtp_session = new t_twinkle_rtp_session( InetHostAddress("0.0.0.0")); MEMMAN_NEW(rtp_session); } else { rtp_session = new t_twinkle_rtp_session( InetHostAddress(_recv_host.c_str()), _recv_port); MEMMAN_NEW(rtp_session); } #ifdef HAVE_ZRTP ZrtpQueue* zque = dynamic_cast(rtp_session); if (zque && rtp_session->is_zrtp_initialized()) { zque->setEnableZrtp(encrypt); if (user_config->get_zrtp_enabled()) { // Create the ZRTP call back interface TwinkleZrtpUI* twui = new TwinkleZrtpUI(this); // The ZrtpQueue keeps track of the twui - the destructor of // ZrtpQueue (aka t_twinkle_rtp_session) deletes this object, // thus no other management is required. zque->setUserCallback(twui); } } #endif } catch(...) { // If the RTPSession constructor throws an exception, no // object is created, so clear the pointer. rtp_session = NULL; string msg(TRANSLATE2("CoreAudio", "Failed to create a UDP socket (RTP) on port %1")); msg = replace_first(msg, "%1", int2str(_recv_port)); log_file->write_report(msg, "t_audio_session::t_audio_session", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); return; } if (!_dst_host.empty() && _dst_port != 0) { rtp_session->addDestination( InetHostAddress(_dst_host.c_str()), _dst_port); } // Set payload format for outgoing RTP packets map::const_iterator it; it = send_ac2payload.find(codec); assert(it != send_ac2payload.end()); unsigned short payload_id = it->second; rtp_session->setPayloadFormat(DynamicPayloadFormat( payload_id, audio_sample_rate(codec))); // Open and initialize sound card t_audio_session *as_peer; if (is_3way() && (as_peer = get_peer_3way())) { speaker = as_peer->get_dsp_speaker(); mic = as_peer->get_dsp_mic(); if (!speaker || !mic) return; } else { if (!open_dsp()) return; } #ifdef HAVE_SPEEX // Speex AEC auxiliary data initialization do_echo_cancellation = false; if (user_config->get_speex_dsp_aec()) { int nsamples = audio_sample_rate(codec) / 1000 * ptime; speex_echo_state = speex_echo_state_init(nsamples, 5*nsamples); do_echo_cancellation = true; echo_captured_last = true; } #endif // Create recorder if (!_recv_host.empty() && _recv_port != 0) { audio_rx = new t_audio_rx(this, mic, rtp_session, codec, payload_id, ptime); MEMMAN_NEW(audio_rx); // Setup 3-way configuration if this audio session is part of // a 3-way. if (is_3way()) { t_audio_session *peer = get_peer_3way(); if (!peer || !peer->audio_rx) { // There is no peer rx yet, so become the main rx audio_rx->join_3way(true, NULL); if (peer && peer->audio_tx) { peer->audio_tx->set_peer_rx_3way(audio_rx); } } else { // There is a peer rx already so that must be the // main rx. audio_rx->join_3way(false, peer->audio_rx); peer->audio_rx->set_peer_rx_3way(audio_rx); if (peer->audio_tx) { peer->audio_tx->set_peer_rx_3way(audio_rx); } } } } // Create player if (!_dst_host.empty() && _dst_port != 0) { audio_tx = new t_audio_tx(this, speaker, rtp_session, codec, recv_payload2ac, ptime); MEMMAN_NEW(audio_tx); // Setup 3-way configuration if this audio session is part of // a 3-way. if (is_3way()) { t_audio_session *peer = get_peer_3way(); if (!peer) { // There is no peer tx yet, so become the mixer tx audio_tx->join_3way(true, NULL, NULL); } else if (!peer->audio_tx) { // There is a peer audio session, but no peer tx, // so become the mixer tx audio_tx->join_3way(true, NULL, peer->audio_rx); } else { // There is a peer tx already. That must be the // mixer. audio_tx->join_3way( false, peer->audio_tx, peer->audio_rx); } } } valid = true; } t_audio_session::~t_audio_session() { // Delete of the audio_rx and audio_tx objects will terminate // thread execution. if (audio_rx) { // Reconfigure 3-way configuration if this audio session is // part of a 3-way. if (is_3way()) { t_audio_session *peer = get_peer_3way(); if (peer) { // Make the peer audio rx the main rx and remove // reference to this audio rx if (peer->audio_rx) { peer->audio_rx->set_peer_rx_3way(NULL); peer->audio_rx->set_main_rx_3way(true); } // Remove reference to this audio rx if (peer->audio_tx) { peer->audio_tx->set_peer_rx_3way(NULL); } } } MEMMAN_DELETE(audio_rx); delete audio_rx; } if (audio_tx) { // Reconfigure 3-way configuration if this audio session is // part of a 3-way. if (is_3way()) { t_audio_session *peer = get_peer_3way(); if (peer) { // Make the peer audio tx the mixer and remove // reference to this audio tx if (peer->audio_tx) { peer->audio_tx->set_peer_tx_3way(NULL); peer->audio_tx->set_mixer_3way(true); } } } MEMMAN_DELETE(audio_tx); delete audio_tx; } if (thr_audio_rx) { MEMMAN_DELETE(thr_audio_rx); delete thr_audio_rx; } if (thr_audio_tx) { MEMMAN_DELETE(thr_audio_tx); delete thr_audio_tx; } if (rtp_session) { log_file->write_header("t_audio_session::~t_audio_session"); log_file->write_raw("Line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": stopping RTP session.\n"); log_file->write_footer(); MEMMAN_DELETE(rtp_session); delete rtp_session; log_file->write_header("t_audio_session::~t_audio_session"); log_file->write_raw("Line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": RTP session stopped.\n"); log_file->write_footer(); } if (speaker && (!is_3way() || !get_peer_3way())) { if (mic == speaker) mic = 0; MEMMAN_DELETE(speaker); delete speaker; speaker = 0; } if (mic && (!is_3way() || !get_peer_3way())) { MEMMAN_DELETE(mic); delete mic; mic = 0; } #ifdef HAVE_SPEEX // cleaning speech AEC if (do_echo_cancellation) { speex_echo_state_destroy(speex_echo_state); } #endif } void t_audio_session::set_session(t_session *_session) { mtx_session.lock(); session = _session; mtx_session.unlock(); } void t_audio_session::run(void) { _audio_session = this; log_file->write_header("t_audio_session::run"); log_file->write_raw("Line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": starting RTP session.\n"); log_file->write_footer(); rtp_session->startRunning(); log_file->write_header("t_audio_session::run"); log_file->write_raw("Line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": RTP session started.\n"); log_file->write_footer(); if (audio_rx) { try { // Set the running flag now instead of at the start of // t_audio_tx::run as due to race conditions the thread might // get destroyed before the run method starts running. The // destructor still has to wait on the thread to finish. audio_rx->set_running(true); thr_audio_rx = new t_thread(main_audio_rx, NULL); MEMMAN_NEW(thr_audio_rx); // thr_audio_rx->set_sched_fifo(90); thr_audio_rx->detach(); } catch (int) { audio_rx->set_running(false); string msg(TRANSLATE2("CoreAudio", "Failed to create audio receiver thread.")); log_file->write_report(msg, "t_audio_session::run", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); exit(1); } } if (audio_tx) { try { // See comment above for audio_rx audio_tx->set_running(true); thr_audio_tx = new t_thread(main_audio_tx, NULL); MEMMAN_NEW(thr_audio_tx); // thr_audio_tx->set_sched_fifo(90); thr_audio_tx->detach(); } catch (int) { audio_tx->set_running(false); string msg(TRANSLATE2("CoreAudio", "Failed to create audio transmitter thread.")); log_file->write_report(msg, "t_audio_session::run", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); exit(1); } } } void t_audio_session::set_pt_out_dtmf(unsigned short pt) { if (audio_rx) audio_rx->set_pt_telephone_event(pt); } void t_audio_session::set_pt_in_dtmf(unsigned short pt, unsigned short pt_alt) { if (audio_tx) audio_tx->set_pt_telephone_event(pt, pt_alt); } void t_audio_session::send_dtmf(char digit, bool inband) { if (audio_rx) audio_rx->push_dtmf(digit, inband); } t_line *t_audio_session::get_line(void) const { t_line *line; mtx_session.lock(); line = session->get_line(); mtx_session.unlock(); return line; } void t_audio_session::start_3way(void) { if (audio_rx) { audio_rx->join_3way(true, NULL); } if (audio_tx) { audio_tx->join_3way(true, NULL, NULL); } } void t_audio_session::stop_3way(void) { if (audio_rx) { t_audio_session *peer = get_peer_3way(); if (peer) { if (peer->audio_rx) { peer->audio_rx->set_peer_rx_3way(NULL); } if (peer->audio_tx) { peer->audio_tx->set_peer_rx_3way(NULL); } } audio_rx->stop_3way(); } if (audio_tx) { t_audio_session *peer = get_peer_3way(); if (peer) { if (peer->audio_tx) { peer->audio_tx->set_peer_tx_3way(NULL); } } audio_tx->stop_3way(); } } bool t_audio_session::is_valid(void) const { return valid; } t_audio_io* t_audio_session::get_dsp_speaker(void) const { return speaker; } t_audio_io* t_audio_session::get_dsp_mic(void) const { return mic; } bool t_audio_session::matching_sample_rates(void) const { int codec_sample_rate = audio_sample_rate(codec); return (speaker->get_sample_rate() == codec_sample_rate && mic->get_sample_rate() == codec_sample_rate); } void t_audio_session::confirm_zrtp_sas(void) { #ifdef HAVE_ZRTP ZrtpQueue* zque = dynamic_cast(rtp_session); if (zque) { zque->SASVerified(); set_zrtp_sas_confirmed(true); } #endif } void t_audio_session::reset_zrtp_sas_confirmation(void) { #ifdef HAVE_ZRTP ZrtpQueue* zque = dynamic_cast(rtp_session); if (zque) { zque->resetSASVerified(); set_zrtp_sas_confirmed(false); } #endif } void t_audio_session::enable_zrtp(void) { #ifdef HAVE_ZRTP ZrtpQueue* zque = dynamic_cast(rtp_session); if (zque) { zque->setEnableZrtp(true); } #endif } void t_audio_session::zrtp_request_go_clear(void) { #ifdef HAVE_ZRTP ZrtpQueue* zque = dynamic_cast(rtp_session); if (zque) { zque->requestGoClear(); } #endif } void t_audio_session::zrtp_go_clear_ok(void) { #ifdef HAVE_ZRTP ZrtpQueue* zque = dynamic_cast(rtp_session); if (zque) { zque->goClearOk(); } #endif } bool t_audio_session::get_is_encrypted(void) const { mtx_zrtp_data.lock(); bool b = is_encrypted; mtx_zrtp_data.unlock(); return b; } string t_audio_session::get_zrtp_sas(void) const { mtx_zrtp_data.lock(); string s = zrtp_sas; mtx_zrtp_data.unlock(); return s; } bool t_audio_session::get_zrtp_sas_confirmed(void) const { mtx_zrtp_data.lock(); bool b = zrtp_sas_confirmed; mtx_zrtp_data.unlock(); return b; } string t_audio_session::get_srtp_cipher_mode(void) const { mtx_zrtp_data.lock(); string s = srtp_cipher_mode; mtx_zrtp_data.unlock(); return s; } void t_audio_session::set_is_encrypted(bool on) { mtx_zrtp_data.lock(); is_encrypted = on; mtx_zrtp_data.unlock(); } void t_audio_session::set_zrtp_sas(const string &sas) { mtx_zrtp_data.lock(); zrtp_sas = sas; mtx_zrtp_data.unlock(); } void t_audio_session::set_zrtp_sas_confirmed(bool confirmed) { mtx_zrtp_data.lock(); zrtp_sas_confirmed = confirmed; mtx_zrtp_data.unlock(); } void t_audio_session::set_srtp_cipher_mode(const string &cipher_mode) { mtx_zrtp_data.lock(); srtp_cipher_mode = cipher_mode; mtx_zrtp_data.unlock(); } #ifdef HAVE_SPEEX bool t_audio_session::get_do_echo_cancellation(void) const { return do_echo_cancellation; } bool t_audio_session::get_echo_captured_last(void) { return echo_captured_last; } void t_audio_session::set_echo_captured_last(bool value) { echo_captured_last = value; } SpeexEchoState *t_audio_session::get_speex_echo_state(void) { return speex_echo_state; } #endif void *main_audio_rx(void *arg) { _audio_session->audio_rx->run(); return NULL; } void *main_audio_tx(void *arg) { _audio_session->audio_tx->run(); return NULL; } twinkle-1.4.2/src/audio/twinkle_zrtp_ui.h0000644000175000001440000000565711127714046015422 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Author: Werner Dittmann , (C) 2006 // Michel de Boer /** * @file * User interface call back functions for libzrtpcpp. */ #ifndef __TWINKLEZRTPUI_H_ #define __TWINKLEZRTPUI_H_ #include "twinkle_config.h" #ifdef HAVE_ZRTP #include #include #include #include "audio_session.h" #include "userintf.h" using namespace GnuZrtpCodes; /** User interface for libzrtpcpp. */ class TwinkleZrtpUI : public ZrtpUserCallback { public: /** * Constructor. * @param session [in] The audio session that is encrypted by ZRTP. */ TwinkleZrtpUI(t_audio_session* session); virtual ~TwinkleZrtpUI() {}; //@{ /** @name ZRTP call back functions called from the ZRTP thread */ virtual void secureOn(std::string cipher); virtual void secureOff(); virtual void showSAS(std::string sas, bool verified); virtual void confirmGoClear(); virtual void showMessage(MessageSeverity sev, int subCode); virtual void zrtpNegotiationFailed(MessageSeverity severity, int subCode); virtual void zrtpNotSuppOther(); //} private: /** Audio session associated with this user interface. */ t_audio_session* audioSession; //@{ /** @name Message mappings for libzrtpcpp */ static map infoMap; /**< Info messages */ static map warningMap; /**< Warnings */ static map severeMap; /**< Severe errors */ static map zrtpMap; /**< ZRTP errors */ static bool mapsDone; /**< Flag to indicate that maps are initialized */ static std::string unknownCode; /**< Unknown error code */ //@} /** * Map a message code returned by libzrtpcpp to a message text. * @param severity [in] The severity of the message. * @param subCode [in] The message code. * @return The message text. */ const string *const mapCodesToString(MessageSeverity severity, int subCode); }; #endif // HAVE_ZRTP #endif // __TWINKLEZRTPUI_H_ twinkle-1.4.2/src/audio/audio_codecs.h0000644000175000001440000000655411127714046014607 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _AUDIO_CODECS_H #define _AUDIO_CODECS_H #include "g711.h" #include "g72x.h" // Audio codecs enum t_audio_codec { CODEC_NULL, CODEC_UNSUPPORTED, CODEC_G711_ALAW, CODEC_G711_ULAW, CODEC_GSM, CODEC_SPEEX_NB, CODEC_SPEEX_WB, CODEC_SPEEX_UWB, CODEC_ILBC, CODEC_G726_16, CODEC_G726_24, CODEC_G726_32, CODEC_G726_40, CODEC_TELEPHONE_EVENT }; // Default ptime values (ms) for audio codecs #define PTIME_G711_ALAW 20 #define PTIME_G711_ULAW 20 #define PTIME_G726 20 #define PTIME_GSM 20 #define PTIME_SPEEX 20 #define MIN_PTIME 10 #define MAX_PTIME 80 // Audio sample settings #define AUDIO_SAMPLE_SIZE 16 // Maximum length (in packets) for concealment of lost packets #define MAX_CONCEALMENT 2 // Size of jitter buffer in ms // The jitter buffer is used to smooth playing out incoming RTP packets. // The size of the buffer is also used as the expiry time in the ccRTP // stack. Packets that have timestamp that is older than then size of // the jitter buffer will not be sent out anymore. #define JITTER_BUF_MS 80 // Duration of the expiry timer in the RTP stack. // The ccRTP stack checks all data delivered to it against its clock. // If the data is too old it will not send it out. Data can be old // for several reasons: // // 1) The thread reading the soundcard has been paused for a while // 2) The audio card buffers sound before releasing it. // // Especially the latter seems to happen on some soundcards. Data // not older than defined delay are still allowed to go out. It's up // to the receiving and to deal with the jitter this may cause. #define MAX_OUT_AUDIO_DELAY_MS 160 // Buffer sizes #define JITTER_BUF_SIZE(sample_rate) (JITTER_BUF_MS * (sample_rate)/1000 * AUDIO_SAMPLE_SIZE/8) // Log speex errors #define LOG_SPEEX_ERROR(func, spxfunc, spxerr) {\ log_file->write_header((func), LOG_NORMAL, LOG_DEBUG);\ log_file->write_raw("Speex error: ");\ log_file->write_raw((spxfunc));\ log_file->write_raw(" returned ");\ log_file->write_raw((spxerr));\ log_file->write_footer(); } // Return the sampling rate for a codec unsigned short audio_sample_rate(t_audio_codec codec); // Returns true if the codec is a speex codec bool is_speex_codec(t_audio_codec codec); // Resample the input buffer to the output buffer // Returns the number of samples put in the output buffer // If the output buffer is too small, the number of samples will be // truncated. int resample(short *input_buf, int input_len, int input_sample_rate, short *output_buf, int output_len, int output_sample_rate); // Mix 2 16 bits signed linear PCM values short mix_linear_pcm(short pcm1, short pcm2); #endif twinkle-1.4.2/src/audio/audio_decoder.h0000644000175000001440000001361311127714046014746 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Audio decoders #ifndef _AUDIO_DECODER_H #define _AUDIO_DECODER_H #include #include "twinkle_config.h" #include "audio_codecs.h" #include "user.h" #ifdef HAVE_GSM #include #else #include "gsm/inc/gsm.h" #endif #ifdef HAVE_SPEEX #include #include #endif #ifdef HAVE_ILBC #ifndef HAVE_ILBC_CPP extern "C" { #endif #include #ifndef HAVE_ILBC_CPP } #endif #endif // Abstract definition of an audio decoder class t_audio_decoder { protected: t_audio_codec _codec; uint16 _default_ptime; bool _plc; // packet loss concealment t_user *_user_config; t_audio_decoder(uint16 default_ptime, bool plc, t_user *user_config); public: virtual ~t_audio_decoder() {}; t_audio_codec get_codec(void) const; uint16 get_default_ptime(void) const; virtual uint16 get_ptime(uint16 payload_size) const = 0; // Decode a buffer of encoded samples to 16-bit PCM. // Returns the number of pcm samples written into pcm_buf // Returns 0 if decoding failed virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size) = 0; // Indicates if codec has PLC algorithm bool has_plc(void) const; // Create a payload to conceal a lost packet. // Returns the number of pcm samples written into pcm_buf // Returns 0 if decoding failed virtual uint16 conceal(int16 *pcm_buf, uint16 pcm_buf_size); // Determine if the payload size is valid for this decoder virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const = 0; }; // G.711 A-law class t_g711a_audio_decoder : public t_audio_decoder { public: t_g711a_audio_decoder(uint16 default_ptime, t_user *user_config); virtual uint16 get_ptime(uint16 payload_size) const; virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; // G.711 u-law class t_g711u_audio_decoder : public t_audio_decoder { public: t_g711u_audio_decoder(uint16 default_ptime, t_user *user_config); virtual uint16 get_ptime(uint16 payload_size) const; virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; // GSM class t_gsm_audio_decoder : public t_audio_decoder { private: gsm gsm_decoder; public: t_gsm_audio_decoder(t_user *user_config); virtual ~t_gsm_audio_decoder(); virtual uint16 get_ptime(uint16 payload_size) const; virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; #ifdef HAVE_SPEEX // Speex class t_speex_audio_decoder : public t_audio_decoder { public: enum t_mode { MODE_NB, // Narrow band MODE_WB, // Wide band MODE_UWB // Ultra wide band }; private: SpeexBits speex_bits; void *speex_dec_state; t_mode _mode; public: t_speex_audio_decoder(t_mode mode, t_user *user_config); virtual ~t_speex_audio_decoder(); virtual uint16 get_ptime(uint16 payload_size) const; virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); virtual uint16 conceal(int16 *pcm_buf, uint16 pcm_buf_size); virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; #endif #ifdef HAVE_ILBC // iLBC class t_ilbc_audio_decoder : public t_audio_decoder { private: iLBC_Dec_Inst_t _ilbc_decoder_20; // decoder for 20ms frames iLBC_Dec_Inst_t _ilbc_decoder_30; // decoder for 30ms frames // The number of ms received in the last frame, so the conceal function // can determine which decoder to use to conceal a lost frame. int _last_received_ptime; public: t_ilbc_audio_decoder(uint16 default_ptime, t_user *user_config); virtual uint16 get_ptime(uint16 payload_size) const; virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); virtual uint16 conceal(int16 *pcm_buf, uint16 pcm_buf_size); virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; #endif // G.726 class t_g726_audio_decoder : public t_audio_decoder { public: enum t_bit_rate { BIT_RATE_16, BIT_RATE_24, BIT_RATE_32, BIT_RATE_40 }; private: uint16 decode_16(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); uint16 decode_24(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); uint16 decode_32(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); uint16 decode_40(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); struct g72x_state _state; t_bit_rate _bit_rate; uint8 _bits_per_sample; t_g726_packing _packing; public: t_g726_audio_decoder(t_bit_rate bit_rate, uint16 default_ptime, t_user *user_config); virtual uint16 get_ptime(uint16 payload_size) const; virtual uint16 decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf, uint16 pcm_buf_size); virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; #endif twinkle-1.4.2/src/audio/audio_session.h0000644000175000001440000001155711127714046015031 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _AUDIO_SESSION_H #define _AUDIO_SESSION_H #include #include #include "audio_rx.h" #include "audio_tx.h" #include "session.h" #include "twinkle_rtp_session.h" #include "threads/thread.h" #include "threads/mutex.h" #ifdef HAVE_SPEEX #include #endif using namespace std; using namespace ost; // Forward declarations class t_session; class t_line; class t_audio_session { private: // SIP session owning this audio session t_session *session; /** Mutex for concurrent access to the session. */ mutable t_mutex mtx_session; // This flag indicates if the created audio session is valid. // It might be invalid because, the RTP session could not be created // or the soundcard could not be opened. bool valid; // file descriptor audio device t_audio_io *speaker; t_audio_io *mic; t_twinkle_rtp_session *rtp_session; t_audio_codec codec; unsigned short ptime; // in milliseconds t_thread *thr_audio_rx; // recording thread t_thread *thr_audio_tx; // playing thread // ZRTP info mutable t_mutex mtx_zrtp_data; bool is_encrypted; string zrtp_sas; bool zrtp_sas_confirmed; string srtp_cipher_mode; #ifdef HAVE_SPEEX // Indicator whether to use (Speex) AEC bool do_echo_cancellation; // Indicator whether the last operation of (Speex) AEC, // speex_echo_capture or speex_echo_playback, was the speex_echo_capture bool echo_captured_last; // speex AEC state SpeexEchoState *speex_echo_state; #endif // 3-way conference data // Returns if this audio session is part of a 3-way conference bool is_3way(void) const; // Returns the peer audio session of a 3-way conference t_audio_session *get_peer_3way(void) const; // Open the sound card bool open_dsp(void); bool open_dsp_full_duplex(void); bool open_dsp_speaker(void); bool open_dsp_mic(void); public: t_audio_rx *audio_rx; t_audio_tx *audio_tx; t_audio_session(t_session *_session, const string &_recv_host, unsigned short _recv_port, const string &_dst_host, unsigned short _dst_port, t_audio_codec _codec, unsigned short _ptime, const map &recv_payload2ac, const map &send_ac2payload, bool encrypt); ~t_audio_session(); void run(void); /** * Change the owning session. * @param _session New session owning this audio session. */ void set_session(t_session *_session); // Set outgoing/incoming DTMF dynamic payload types void set_pt_out_dtmf(unsigned short pt); void set_pt_in_dtmf(unsigned short pt, unsigned short pt_alt); // Send DTMF digit void send_dtmf(char digit, bool inband); // Get the line that belongs to this audio session t_line *get_line(void) const; // Become the first session in a 3-way conference void start_3way(void); // Leave a 3-way conference void stop_3way(void); // Check if audio session is valid bool is_valid(void) const; // Get pointer for soundcard I/O object t_audio_io* get_dsp_speaker(void) const; t_audio_io* get_dsp_mic(void) const; // Check if sample rate from speaker and mic match with sample rate // from codec. The sample rates might not match due to 3-way conference // calls with mixed sample rate bool matching_sample_rates(void) const; // ZRTP actions void confirm_zrtp_sas(void); void reset_zrtp_sas_confirmation(void); void enable_zrtp(void); void zrtp_request_go_clear(void); void zrtp_go_clear_ok(void); // ZRTP data manipulations bool get_is_encrypted(void) const; string get_zrtp_sas(void) const; bool get_zrtp_sas_confirmed(void) const; string get_srtp_cipher_mode(void) const; void set_is_encrypted(bool on); void set_zrtp_sas(const string &sas); void set_zrtp_sas_confirmed(bool confirmed); void set_srtp_cipher_mode(const string &cipher_mode); #ifdef HAVE_SPEEX // speex acoustic echo cancellation (AEC) manipulations bool get_do_echo_cancellation(void) const; bool get_echo_captured_last(void); void set_echo_captured_last(bool value); SpeexEchoState *get_speex_echo_state(void); #endif }; // Main functions for rx and tx threads void *main_audio_rx(void *arg); void *main_audio_tx(void *arg); #endif twinkle-1.4.2/src/audio/audio_device.cpp0000644000175000001440000006377011134630134015135 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "audio_device.h" #include #include #include #include #include #include #include "sys_settings.h" #include "translator.h" #include "log.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" #ifdef HAVE_LIBASOUND #include #endif t_audio_io* t_audio_io::open(const t_audio_device& dev, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency) { t_audio_io* aio; if(dev.type == t_audio_device::OSS) { aio = new t_oss_io(); MEMMAN_NEW(aio); #ifdef HAVE_LIBASOUND } else if (dev.type == t_audio_device::ALSA) { aio = new t_alsa_io(); MEMMAN_NEW(aio); #endif } else { string msg("Audio device not implemented"); log_file->write_report(msg, "t_audio_io::open", LOG_NORMAL, LOG_CRITICAL); return 0; } if (aio->open(dev.device, playback, capture, blocking, channels, format, sample_rate, short_latency)) { return aio; } else { string msg("Open audio device failed"); log_file->write_report(msg, "t_audio_io::open", LOG_NORMAL, LOG_CRITICAL); MEMMAN_DELETE(aio); delete aio; return 0L; } } bool t_audio_io::validate(const t_audio_device& dev, bool playback, bool capture) { t_audio_io *aio = open(dev, playback, capture, false, 1, SAMPLEFORMAT_S16, 8000, true); if (aio) { MEMMAN_DELETE(aio); delete aio; return true; } return false; } t_audio_io::~t_audio_io() {} int t_audio_io::get_sample_rate(void) const { return _sample_rate; } bool t_audio_io::open(const string& device, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency) { _sample_rate = sample_rate; return true; } t_oss_io::t_oss_io() : fd(-1), play_buffersize(0), rec_buffersize(0) { } t_oss_io::~t_oss_io() { if (fd > 0) { int arg = 0; ioctl(fd, SNDCTL_DSP_RESET, &arg); close(fd); } fd = -1; } bool t_oss_io::open(const string& device, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency) { t_audio_io::open(device, playback, capture, blocking, channels, format, sample_rate, short_latency); int mode = 0; int status; log_file->write_header("t_oss_io::open", LOG_NORMAL); log_file->write_raw("Opening OSS device: "); log_file->write_raw(device); log_file->write_endl(); if (playback) log_file->write_raw("play\n"); if (capture) log_file->write_raw("capture\n"); log_file->write_footer(); assert (playback || capture); if (playback && capture) mode |= O_RDWR; else if (playback) mode |= O_WRONLY; else if (capture) mode |= O_RDONLY; // On some systems opening the audio devices blocks if another // process or thread has opened it already. To prevent a deadlock // first try to open the device in non-blocking mode. // If the device is still open by another twinkle thread then that // is a bug, but this way at least non deadlock is caused. if(blocking) { fd = ::open(device.c_str(), mode | O_NONBLOCK); if (fd == -1) { string msg("OSS audio device open failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); return false; } else { close(fd); fd = -1; } } else mode |= O_NONBLOCK; fd = ::open(device.c_str(), mode); if (fd < 0) { string msg("OSS audio device open failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); return false; } // Full duplex if (playback && capture) { status = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); if (status == -1) { string msg("SNDCTL_DSP_SETDUPLEX ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(TRANSLATE("Sound card cannot be set to full duplex."), MSG_CRITICAL); close(fd); return false; } } // Set fragment size int arg; if (short_latency) { switch (sys_config->get_oss_fragment_size()) { case 16: arg = 0x00ff0004; // 255 buffers of 2^4 bytes each break; case 32: arg = 0x00ff0005; // 255 buffers of 2^5 bytes each break; case 64: arg = 0x00ff0006; // 255 buffers of 2^5 bytes each break; case 128: arg = 0x00ff0007; // 255 buffers of 2^7 bytes each break; case 256: arg = 0x00ff0008; // 255 buffers of 2^8 bytes each break; default: arg = 0x00ff0007; // 255 buffers of 2^7 bytes each } } else { arg = 0x00ff000a; // 255 buffers of 2^10 bytes each } status = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &arg); if (status == -1) { string msg("SNDCTL_DSP_FRAGMENT ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(TRANSLATE("Cannot set buffer size on sound card."), MSG_CRITICAL); close(fd); return false; } // Channels arg = channels; status = ioctl(fd, SNDCTL_DSP_CHANNELS, &arg); if (status == -1) { string msg("SNDCTL_DSP_CHANNELS ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); msg = TRANSLATE("Sound card cannot be set to %1 channels."); msg = replace_first(msg, "%1", int2str(channels)); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } if (arg != channels) { log_file->write_report("Unable to set channels", "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); string msg = "Sound card cannot be set to "; msg = TRANSLATE("Sound card cannot be set to %1 channels."); msg = replace_first(msg, "%1", int2str(channels)); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } // Sample format int fmt; switch (format) { case SAMPLEFORMAT_S16: #ifdef WORDS_BIGENDIAN fmt = AFMT_S16_BE; #else fmt = AFMT_S16_LE; #endif break; case SAMPLEFORMAT_U16: #ifdef WORDS_BIGENDIAN fmt = AFMT_U16_BE; #else fmt = AFMT_U16_LE; #endif break; case SAMPLEFORMAT_S8: fmt = AFMT_S8; break; case SAMPLEFORMAT_U8: fmt = AFMT_U8; break; default: fmt = 0; // fail } arg = fmt; status = ioctl(fd, SNDCTL_DSP_SETFMT, &arg); if (status == -1) { string msg("SNDCTL_DSP_SETFMT ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(TRANSLATE("Cannot set sound card to 16 bits recording."), MSG_CRITICAL); return false; } arg = fmt; status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); if (status == -1) { string msg("SOUND_PCM_WRITE_BITS ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); ui->cb_display_msg(TRANSLATE("Cannot set sound card to 16 bits playing."), MSG_CRITICAL); return false; } // Sample rate arg = sample_rate; status = ioctl(fd, SNDCTL_DSP_SPEED, &arg); if (status == -1) { string msg("SNDCTL_DSP_SPEED ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::open", LOG_NORMAL, LOG_CRITICAL); msg = TRANSLATE("Cannot set sound card sample rate to %1"); msg = replace_first(msg, "%1", int2str(sample_rate)); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } play_buffersize = rec_buffersize = 0; if (playback) play_buffersize = get_buffer_space(false); if (capture) rec_buffersize = get_buffer_space(true); return true; } void t_oss_io::enable(bool enable_playback, bool enable_recording) { int arg, status; arg = enable_recording ? PCM_ENABLE_INPUT : 0; arg |= enable_playback ? PCM_ENABLE_OUTPUT : 0; status = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &arg); if (status == -1) { string msg("SNDCTL_DSP_SETTRIGGER ioctl failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_oss_io::enable", LOG_NORMAL, LOG_CRITICAL); } } void t_oss_io::flush(bool playback_buffer, bool recording_buffer) { for (int i = 0; i < 2; i++) { // i == 0: flush playback buffer, 1: flush recording buffer if (i == 0 && playback_buffer || i == 1 && recording_buffer) { int skip_bytes = ( (i==0) ? play_buffersize : rec_buffersize) - get_buffer_space(i == 1); if(skip_bytes <= 0) continue; unsigned char *trash = new unsigned char[skip_bytes]; MEMMAN_NEW_ARRAY(trash); read(trash, skip_bytes); MEMMAN_DELETE_ARRAY(trash); delete [] trash; } } } int t_oss_io::get_buffer_space(bool is_recording_buffer) { audio_buf_info dsp_info; int status = ioctl(fd, is_recording_buffer ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &dsp_info); if (status == -1) return 0; return dsp_info.bytes; } int t_oss_io::get_buffer_size(bool is_recording_buffer) { if (is_recording_buffer) return rec_buffersize; else return play_buffersize; } bool t_oss_io::play_buffer_underrun(void) { return get_buffer_space(false) >= get_buffer_size(false); } int t_oss_io::read(unsigned char* buf, int len) { return ::read(fd, buf, len); } int t_oss_io::write(const unsigned char* buf, int len) { return ::write(fd, buf, len); } #ifdef HAVE_LIBASOUND t_alsa_io::t_alsa_io() : pcm_play_ptr(0), pcm_rec_ptr(0), play_framesize(1), rec_framesize(1), play_buffersize(0), rec_buffersize(0) { } t_alsa_io::~t_alsa_io() { if (pcm_play_ptr) { log_file->write_header("t_alsa_io::~t_alsa_io", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("snd_pcm_close, handle = "); log_file->write_raw(ptr2str(pcm_play_ptr)); log_file->write_endl(); log_file->write_footer(); // Without the snd_pcm_hw_free, snd_pcm_close sometimes fails. snd_pcm_hw_free(pcm_play_ptr); snd_pcm_close(pcm_play_ptr); pcm_play_ptr = 0; } if (pcm_rec_ptr) { log_file->write_header("t_alsa_io::~t_alsa_io", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("snd_pcm_close, handle = "); log_file->write_raw(ptr2str(pcm_rec_ptr)); log_file->write_endl(); log_file->write_footer(); snd_pcm_hw_free(pcm_rec_ptr); snd_pcm_close(pcm_rec_ptr); pcm_rec_ptr = 0; } } bool t_alsa_io::open(const string& device, bool playback, bool capture, bool blocking, int channels, t_audio_sampleformat format, int sample_rate, bool short_latency) { t_audio_io::open(device, playback, capture, blocking, channels, format, sample_rate, short_latency); int mode = 0; string msg; this->short_latency = short_latency; const char* dev = device.c_str(); if(dev[0] == 0) dev = "default"; log_file->write_header("t_alsa_io::open", LOG_NORMAL); log_file->write_raw("Opening ALSA device: "); log_file->write_raw(dev); log_file->write_endl(); if (playback) log_file->write_raw("play\n"); if (capture) log_file->write_raw("capture\n"); log_file->write_footer(); if (playback && capture) { // Full duplex: Perform the operation in two steps if (!open(device, true, false, blocking, channels, format, sample_rate, short_latency)) return false; if (!open(device, false, true, blocking, channels, format, sample_rate, short_latency)) return false; return true; } snd_pcm_t* pcm_ptr; #define HANDLE_ALSA_ERROR(func) string msg(func); msg += " failed: "; msg += snd_strerror(err); \ log_file->write_report(msg, "t_alsa_io::open", LOG_NORMAL, LOG_CRITICAL); msg = TRANSLATE("Opening ALSA driver failed") + ": " + msg; \ ui->cb_display_msg(msg, MSG_CRITICAL); if(pcm_ptr) snd_pcm_close(pcm_ptr); return false; if (!blocking) mode = SND_PCM_NONBLOCK; int err = snd_pcm_open(&pcm_ptr, dev, playback ? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE, mode); if (err < 0) { string msg("snd_pcm_open failed: "); msg += snd_strerror(err); log_file->write_report(msg, "t_alsa_io::open", LOG_NORMAL, LOG_CRITICAL); msg = "Cannot open ALSA driver for PCM "; if (playback) { msg = TRANSLATE("Cannot open ALSA driver for PCM playback"); } else { msg = TRANSLATE("Cannot open ALSA driver for PCM capture"); } msg += ": "; msg += snd_strerror(err); ui->cb_display_msg(msg, MSG_CRITICAL); return false; } log_file->write_header("t_alsa_io::open", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("snd_pcm_open succeeded, handle = "); log_file->write_raw(ptr2str(pcm_ptr)); log_file->write_endl(); log_file->write_footer(); snd_pcm_hw_params_t *hw_params; snd_pcm_sw_params_t *sw_params; // Set HW params if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_hw_params_malloc"); } MEMMAN_NEW(hw_params); if ((err = snd_pcm_hw_params_any (pcm_ptr, hw_params)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_hw_params_any"); } if ((err = snd_pcm_hw_params_set_access (pcm_ptr, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_hw_params_set_access"); } snd_pcm_format_t fmt; int sample_bits; switch (format) { case SAMPLEFORMAT_S16: #ifdef WORDS_BIGENDIAN fmt = SND_PCM_FORMAT_S16_BE; #else fmt = SND_PCM_FORMAT_S16_LE; #endif sample_bits = 16; break; case SAMPLEFORMAT_U16: #ifdef WORDS_BIGENDIAN fmt = SND_PCM_FORMAT_U16_BE; #else fmt = SND_PCM_FORMAT_U16_LE; #endif sample_bits = 16; break; case SAMPLEFORMAT_S8: fmt = SND_PCM_FORMAT_S8; sample_bits = 8; break; case SAMPLEFORMAT_U8: fmt = SND_PCM_FORMAT_U8; sample_bits = 8; break; default: {HANDLE_ALSA_ERROR("invalid sample format");} } if ((err = snd_pcm_hw_params_set_format (pcm_ptr, hw_params, fmt)) < 0) { string s("snd_pcm_hw_params_set_format("); s += int2str(fmt); s += ")"; HANDLE_ALSA_ERROR(s); } // Some sound cards do not support the exact sample rate specified in the // wav files. Still we first try to set the exact sample rate instead of // specifying the 3rd parameter as -1 to choose an approximate. // For some reason on my first sound card that supports the exact rate, // I get mono sound when the -1 parameter is specified. if ((err = snd_pcm_hw_params_set_rate (pcm_ptr, hw_params, sample_rate, 0)) < 0) { msg = "Cannot set soundcard to exact sample rate of "; msg += int2str(sample_rate); msg += ".\nThe card will choose a lower approximate rate."; log_file->write_report(msg, "t_alsa_io::open", LOG_NORMAL, LOG_WARNING); if ((err = snd_pcm_hw_params_set_rate (pcm_ptr, hw_params, sample_rate, -1)) < 0) { string s("snd_pcm_hw_params_set_rate("); s += int2str(sample_rate); s += ")"; HANDLE_ALSA_ERROR(s); } } // Read back card rate for reporting in the log file. unsigned int card_rate; int card_dir; snd_pcm_hw_params_get_rate(hw_params, &card_rate, &card_dir); if ((err = snd_pcm_hw_params_set_channels (pcm_ptr, hw_params, channels)) < 0) { string s("snd_pcm_hw_params_set_channels("); s += int2str(channels); s += ")"; HANDLE_ALSA_ERROR(s); } // Note: The buffersize is in FRAMES, not BYTES (one frame = sizeof(sample) * channels) snd_pcm_uframes_t buffersize; unsigned int periods = 8; // Double buffering int dir = 1; // Set the size of one period in samples if (short_latency) { if (playback) { buffersize = sys_config->get_alsa_play_period_size(); } else { buffersize = sys_config->get_alsa_capture_period_size(); } } else { buffersize = 1024; } if ((err = snd_pcm_hw_params_set_period_size_near (pcm_ptr, hw_params, &buffersize, &dir)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_hw_params_set_period_size_near"); } // The number of periods determines the ALSA application buffer size. // This size must be larger than the jitter buffer. // TODO: use some more sophisticated algorithm here: read back the period // size and calculate the number of periods needed (only in the // short latency case)? if (buffersize <= 64) { periods *= 8; } else if (buffersize <= 256) { periods *= 4; } dir = 1; if ((err = snd_pcm_hw_params_set_periods(pcm_ptr, hw_params, periods, dir)) < 0) { if ((err = snd_pcm_hw_params_set_periods_near(pcm_ptr, hw_params, &periods, &dir)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_hw_params_set_periods"); } } if ((err = snd_pcm_hw_params (pcm_ptr, hw_params)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_hw_params"); } // Find out if the sound card supports pause functionality can_pause = (snd_pcm_hw_params_can_pause(hw_params) == 1); MEMMAN_DELETE(hw_params); snd_pcm_hw_params_free(hw_params); // Set SW params if ((err = snd_pcm_sw_params_malloc(&sw_params)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_sw_params_malloc"); } MEMMAN_NEW(sw_params); if ((err = snd_pcm_sw_params_current (pcm_ptr, sw_params)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_sw_params_current"); } if ((err = snd_pcm_sw_params (pcm_ptr, sw_params)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_sw_params"); } MEMMAN_DELETE(sw_params); snd_pcm_sw_params_free(sw_params); if ((err = snd_pcm_prepare (pcm_ptr)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_prepare"); } if (playback) { pcm_play_ptr = pcm_ptr; play_framesize = (sample_bits / 8) * channels; play_buffersize = (int)buffersize * periods * play_framesize; play_periods = periods; log_file->write_header("t_alsa_io::open", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("ALSA playback buffer settings.\n"); log_file->write_raw("Rate = "); log_file->write_raw(card_rate); log_file->write_raw(" frames/sec\n"); log_file->write_raw("Frame size = "); log_file->write_raw(play_framesize); log_file->write_raw(" bytes\n"); log_file->write_raw("Periods = "); log_file->write_raw(play_periods); log_file->write_endl(); log_file->write_raw("Period size = "); log_file->write_raw(buffersize * play_framesize); log_file->write_raw(" bytes\n"); log_file->write_raw("Buffer size = "); log_file->write_raw(play_buffersize); log_file->write_raw(" bytes\n"); log_file->write_raw("Can pause: "); log_file->write_bool(can_pause); log_file->write_endl(); log_file->write_footer(); } else { // Since audio_rx checks buffer before reading, start manually if ((err = snd_pcm_start(pcm_ptr)) < 0) { HANDLE_ALSA_ERROR("snd_pcm_start"); } pcm_rec_ptr = pcm_ptr; rec_framesize = (sample_bits / 8) * channels; rec_buffersize = (int)buffersize * periods * rec_framesize; rec_periods = periods; // HACK: snd_pcm_delay seems not to work for the dsnoop device. // This code determines if snd_pcm is working. As the capture // device just started, it should return zero or a small number. // So if it returns that more than half of the buffer is filled // already, it seems broken. rec_delay_broken = false; if (get_buffer_space(true) > rec_buffersize / 2) { rec_delay_broken = true; log_file->write_report( "snd_pcm_delay does not work for capture buffer.", "t_alsa_io::open", LOG_NORMAL, LOG_DEBUG); } log_file->write_header("t_alsa_io::open", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("ALSA capture buffer settings.\n"); log_file->write_raw("Rate = "); log_file->write_raw(card_rate); log_file->write_raw(" frames/sec\n"); log_file->write_raw("Frame size = "); log_file->write_raw(rec_framesize); log_file->write_raw(" bytes\n"); log_file->write_raw("Periods = "); log_file->write_raw(rec_periods); log_file->write_endl(); log_file->write_raw("Period size = "); log_file->write_raw(buffersize * rec_framesize); log_file->write_raw(" bytes\n"); log_file->write_raw("Buffer size = "); log_file->write_raw(rec_buffersize); log_file->write_raw(" bytes\n"); log_file->write_raw("Can pause: "); log_file->write_bool(can_pause); log_file->write_endl(); log_file->write_footer(); } return true; #undef HANDLE_ALSA_ERROR } void t_alsa_io::enable(bool enable_playback, bool enable_recording) { if (!can_pause) return; if (pcm_play_ptr) { snd_pcm_pause(pcm_play_ptr, (int)enable_playback); } if (pcm_rec_ptr) { snd_pcm_pause(pcm_rec_ptr, (int)enable_recording); } } void t_alsa_io::flush(bool playback_buffer, bool recording_buffer) { if (playback_buffer && pcm_play_ptr) { // snd_pcm_reset(pcm_play_ptr); snd_pcm_drop(pcm_play_ptr); snd_pcm_prepare(pcm_play_ptr); snd_pcm_start(pcm_play_ptr); } if (recording_buffer && pcm_rec_ptr) { // For some obscure reason snd_pcm_reset causes the CPU // load to rise to 99.9% when playing and capturing is // done on the same sound card. // Therefor snd_pcm_reset is replaced by functions to // stop the card, drop samples and start again. // snd_pcm_reset(pcm_rec_ptr); snd_pcm_drop(pcm_rec_ptr); snd_pcm_prepare(pcm_rec_ptr); snd_pcm_start(pcm_rec_ptr); } } int t_alsa_io::get_buffer_space(bool is_recording_buffer) { int rv; int err; snd_pcm_sframes_t delay; snd_pcm_status_t* status; snd_pcm_status_alloca(&status); if(is_recording_buffer) { if(!pcm_rec_ptr) return 0; // This does not work as snd_pcm_status_get_avail_max does not return // accurate results. // snd_pcm_status(pcm_rec_ptr, status); // rv = rec_framesize * snd_pcm_status_get_avail_max(status); snd_pcm_hwsync(pcm_rec_ptr); if ((err = snd_pcm_delay(pcm_rec_ptr, &delay)) < 0) { string msg = "snd_pcm_delay for capture buffer failed: "; msg += snd_strerror(err); log_file->write_report(msg, "t_alsa_io::get_buffer_space", LOG_NORMAL, LOG_DEBUG); delay = 0; snd_pcm_prepare(pcm_rec_ptr); } if (rec_delay_broken) { rv = 0; // there is no way to get an accurate number } else { rv = int(delay * rec_framesize); } if (rv > rec_buffersize) { rv = rec_buffersize; // capture buffer overrun snd_pcm_prepare(pcm_rec_ptr); } } else { if(!pcm_play_ptr) return 0; snd_pcm_status(pcm_play_ptr, status); rv = play_framesize * snd_pcm_status_get_avail_max(status); if (rv > play_buffersize) { rv = play_buffersize; // playback buffer underrun snd_pcm_prepare(pcm_play_ptr); } } return rv; } int t_alsa_io::get_buffer_size(bool is_recording_buffer) { if (is_recording_buffer) return rec_buffersize; else return play_buffersize; } bool t_alsa_io::play_buffer_underrun(void) { if (!pcm_play_ptr) return false; return snd_pcm_state(pcm_play_ptr) == SND_PCM_STATE_XRUN; } int t_alsa_io::read(unsigned char* buf, int len) { string msg; if (!pcm_rec_ptr) { log_file->write_report("Illegal pcm_rec_prt.", "t_alsa_io::read", LOG_NORMAL, LOG_CRITICAL); return -1; } int len_frames = len / rec_framesize; int read_frames = 0; for(;;) { int read = snd_pcm_readi(pcm_rec_ptr, buf, len_frames); if (read == -EPIPE) { msg = "Capture buffer overrun."; log_file->write_report(msg, "t_alsa_io::read", LOG_NORMAL, LOG_DEBUG); snd_pcm_prepare(pcm_rec_ptr); snd_pcm_start(pcm_rec_ptr); continue; } else if (read <= 0) { msg = "PCM read error: "; msg += snd_strerror(read); log_file->write_report(msg, "t_alsa_io::read", LOG_NORMAL, LOG_DEBUG); return -1; } else if (read < len_frames) { buf += rec_framesize * read; len_frames -= read; read_frames += read; continue; } return (read_frames + read) * rec_framesize; } } int t_alsa_io::write(const unsigned char* buf, int len) { int len_frames = len / play_framesize; int frames_written = 0; string msg; for (;;) { if(!pcm_play_ptr) return -1; int written = snd_pcm_writei(pcm_play_ptr, buf, len_frames); if (written == -EPIPE) { msg = "Playback buffer underrun."; log_file->write_report(msg, "t_alsa_io::write", LOG_NORMAL, LOG_DEBUG); snd_pcm_prepare(pcm_play_ptr); continue; } else if (written == -EINVAL) { msg = "Invalid argument passed to snd_pcm_writei: "; msg += snd_strerror(written); log_file->write_report(msg, "t_alsa_io::write", LOG_NORMAL, LOG_DEBUG); } else if (written < 0) { msg = "PCM write error: "; msg += snd_strerror(written); log_file->write_report(msg, "t_alsa_io::write", LOG_NORMAL, LOG_DEBUG); return -1; } else if (written < len_frames) { buf += written * play_framesize; len_frames -= written; frames_written += written; continue; } return (frames_written + written) * play_framesize; } } // This function fills the specified list with ALSA hardware soundcards found on the system. // It uses plughw:xx instead of hw:xx for specifiers, because hw:xx are not practical to // use (e.g. they require a resampler/channel mixer in the application). // playback indicates if a list with playback or capture devices should be created. void alsa_fill_soundcards(list& l, bool playback) { int err = 0; int card = -1, device = -1; snd_ctl_t *handle; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; snd_ctl_card_info_alloca(&info); snd_pcm_info_alloca(&pcminfo); for (;;) { err = snd_card_next(&card); if (err < 0 || card < 0) break; if (card >= 0) { string name = "hw:"; name += int2str(card); if ((err = snd_ctl_open(&handle, name.c_str(), 0)) < 0) continue; if ((err = snd_ctl_card_info(handle, info)) < 0) { snd_ctl_close(handle); continue; } const char *card_name = snd_ctl_card_info_get_name(info); for (;;) { err = snd_ctl_pcm_next_device(handle, &device); if (err < 0 || device < 0) break; snd_pcm_info_set_device(pcminfo, device); snd_pcm_info_set_subdevice(pcminfo, 0); if (playback) { snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK); } else { snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE); } if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) continue; t_audio_device dev; dev.device = string("plughw:") + int2str(card) + string(",") + int2str(device); dev.name = string(card_name) + " ("; dev.name += snd_pcm_info_get_name(pcminfo); dev.name += ")"; dev.type = t_audio_device::ALSA; l.push_back(dev); } snd_ctl_close(handle); } } } // endif ifdef HAVE_LIBASOUND #endif twinkle-1.4.2/src/audio/twinkle_zrtp_ui.cpp0000644000175000001440000002562211127714055015747 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Author: Werner Dittmann , (C) 2006 // Michel de Boer #include "twinkle_zrtp_ui.h" #ifdef HAVE_ZRTP #include "phone.h" #include "line.h" #include "log.h" #include "util.h" using namespace std; using namespace GnuZrtpCodes; extern t_phone *phone; // Initialize static data mapTwinkleZrtpUI::infoMap; mapTwinkleZrtpUI::warningMap; mapTwinkleZrtpUI::severeMap; mapTwinkleZrtpUI::zrtpMap; bool TwinkleZrtpUI::mapsDone = false; std::string TwinkleZrtpUI::unknownCode = "Unknown error code"; TwinkleZrtpUI::TwinkleZrtpUI(t_audio_session* session) : audioSession(session) { if (mapsDone) { return; } // Initialize error mapping infoMap.insert(pair(InfoHelloReceived, string("Hello received, preparing a Commit"))); infoMap.insert(pair(InfoCommitDHGenerated, string("Commit: Generated a public DH key"))); infoMap.insert(pair(InfoRespCommitReceived, string("Responder: Commit received, preparing DHPart1"))); infoMap.insert(pair(InfoDH1DHGenerated, string("DH1Part: Generated a public DH key"))); infoMap.insert(pair(InfoInitDH1Received, string("Initiator: DHPart1 received, preparing DHPart2"))); infoMap.insert(pair(InfoRespDH2Received, string("Responder: DHPart2 received, preparing Confirm1"))); infoMap.insert(pair(InfoInitConf1Received, string("Initiator: Confirm1 received, preparing Confirm2"))); infoMap.insert(pair(InfoRespConf2Received, string("Responder: Confirm2 received, preparing Conf2Ack"))); infoMap.insert(pair(InfoRSMatchFound, string("At least one retained secrets matches - security OK"))); infoMap.insert(pair(InfoSecureStateOn, string("Entered secure state"))); infoMap.insert(pair(InfoSecureStateOff, string("No more security for this session"))); warningMap.insert(pair(WarningDHAESmismatch, string("Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096"))); warningMap.insert(pair(WarningGoClearReceived, string("Received a GoClear message"))); warningMap.insert(pair(WarningDHShort, string("Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096"))); warningMap.insert(pair(WarningNoRSMatch, string("No retained shared secrets available - must verify SAS"))); warningMap.insert(pair(WarningCRCmismatch, string("Internal ZRTP packet checksum mismatch - packet dropped"))); warningMap.insert(pair(WarningSRTPauthError, string("Dropping packet because SRTP authentication failed!"))); warningMap.insert(pair(WarningSRTPreplayError, string("Dropping packet because SRTP replay check failed!"))); warningMap.insert(pair(WarningNoExpectedRSMatch, string("Valid retained shared secrets availabe but no matches found - must verify SAS"))); severeMap.insert(pair(SevereHelloHMACFailed, string("Hash HMAC check of Hello failed!"))); severeMap.insert(pair(SevereCommitHMACFailed, string("Hash HMAC check of Commit failed!"))); severeMap.insert(pair(SevereDH1HMACFailed, string("Hash HMAC check of DHPart1 failed!"))); severeMap.insert(pair(SevereDH2HMACFailed, string("Hash HMAC check of DHPart2 failed!"))); severeMap.insert(pair(SevereCannotSend, string("Cannot send data - connection or peer down?"))); severeMap.insert(pair(SevereProtocolError, string("Internal protocol error occured!"))); severeMap.insert(pair(SevereNoTimer, string("Cannot start a timer - internal resources exhausted?"))); severeMap.insert(pair(SevereTooMuchRetries, string("Too much retries during ZRTP negotiation - connection or peer down?"))); zrtpMap.insert(pair(MalformedPacket, string("Malformed packet (CRC OK, but wrong structure)"))); zrtpMap.insert(pair(CriticalSWError, string("Critical software error"))); zrtpMap.insert(pair(UnsuppZRTPVersion, string("Unsupported ZRTP version"))); zrtpMap.insert(pair(HelloCompMismatch, string("Hello components mismatch"))); zrtpMap.insert(pair(UnsuppHashType, string("Hash type not supported"))); zrtpMap.insert(pair(UnsuppCiphertype, string("Cipher type not supported"))); zrtpMap.insert(pair(UnsuppPKExchange, string("Public key exchange not supported"))); zrtpMap.insert(pair(UnsuppSRTPAuthTag, string("SRTP auth. tag not supported"))); zrtpMap.insert(pair(UnsuppSASScheme, string("SAS scheme not supported"))); zrtpMap.insert(pair(NoSharedSecret, string("No shared secret available, DH mode required"))); zrtpMap.insert(pair(DHErrorWrongPV, string("DH Error: bad pvi or pvr ( == 1, 0, or p-1)"))); zrtpMap.insert(pair(DHErrorWrongHVI, string("DH Error: hvi != hashed data"))); zrtpMap.insert(pair(SASuntrustedMiTM, string("Received relayed SAS from untrusted MiTM"))); zrtpMap.insert(pair(ConfirmHMACWrong, string("Auth. Error: Bad Confirm pkt HMAC"))); zrtpMap.insert(pair(NonceReused, string("Nonce reuse"))); zrtpMap.insert(pair(EqualZIDHello, string("Equal ZIDs in Hello"))); zrtpMap.insert(pair(GoCleatNotAllowed, string("GoClear packet received, but not allowed"))); mapsDone = true; } void TwinkleZrtpUI::secureOn(std::string cipher) { audioSession->set_is_encrypted(true); audioSession->set_srtp_cipher_mode(cipher); t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); log_file->write_header("TwinkleZrtpUI::secureOn"); log_file->write_raw("Line "); log_file->write_raw(lineno + 1); log_file->write_raw(": audio encryption enabled: "); log_file->write_raw(cipher); log_file->write_endl(); log_file->write_footer(); ui->cb_async_line_encrypted(lineno, true); ui->cb_async_line_state_changed(); } void TwinkleZrtpUI::secureOff() { audioSession->set_is_encrypted(false); t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); log_file->write_header("TwinkleZrtpUI::secureOff"); log_file->write_raw("Line "); log_file->write_raw(lineno + 1); log_file->write_raw(": audio encryption disabled.\n"); log_file->write_footer(); ui->cb_async_line_encrypted(lineno, false); ui->cb_async_line_state_changed(); } void TwinkleZrtpUI::showSAS(std::string sas, bool verified) { audioSession->set_zrtp_sas(sas); audioSession->set_zrtp_sas_confirmed(verified); t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); log_file->write_header("TwinkleZrtpUI::showSAS"); log_file->write_raw("Line "); log_file->write_raw(lineno + 1); log_file->write_raw(": SAS ="); log_file->write_raw(sas); log_file->write_endl(); log_file->write_footer(); if (!verified) { ui->cb_async_show_zrtp_sas(lineno, sas); } ui->cb_async_line_state_changed(); } void TwinkleZrtpUI::confirmGoClear() { t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); ui->cb_async_zrtp_confirm_go_clear(lineno); } void TwinkleZrtpUI::showMessage(MessageSeverity sev, int subCode) { t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); string msg = "Line "; msg += int2str(lineno + 1); msg += ": "; msg += *mapCodesToString(sev, subCode); switch (sev) { case Info: log_file->write_report(msg, "TwinkleZrtpUI::showMessage", LOG_NORMAL, LOG_INFO); break; case Warning: log_file->write_report(msg, "TwinkleZrtpUI::showMessage", LOG_NORMAL, LOG_WARNING); break; default: log_file->write_report(msg, "TwinkleZrtpUI::showMessage", LOG_NORMAL, LOG_CRITICAL); } } void TwinkleZrtpUI::zrtpNegotiationFailed(MessageSeverity severity, int subCode) { t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); string m = "Line "; m += int2str(lineno + 1); m += ": ZRTP negotiation failed.\n"; m += *mapCodesToString(severity, subCode); switch (severity) { case Info: log_file->write_report(m, "TwinkleZrtpUI::zrtpNegotiationFailed", LOG_NORMAL, LOG_INFO); break; case Warning: log_file->write_report(m, "TwinkleZrtpUI::zrtpNegotiationFailed", LOG_NORMAL, LOG_WARNING); break; default: log_file->write_report(m, "TwinkleZrtpUI::zrtpNegotiationFailed", LOG_NORMAL, LOG_CRITICAL); } } void TwinkleZrtpUI::zrtpNotSuppOther() { t_line *line = audioSession->get_line(); int lineno = line->get_line_number(); string msg = "Line "; msg += int2str(lineno + 1); msg += ": remote party does not support ZRTP."; log_file->write_report(msg, "TwinkleZrtpUI::zrtpNotSuppOther"); } const string *const TwinkleZrtpUI::mapCodesToString(MessageSeverity severity, int subCode) { string *m = &unknownCode; switch (severity) { case Info: m = &infoMap[subCode]; break; case Warning: m = &warningMap[subCode]; break; case Severe: m = &severeMap[subCode]; break; case ZrtpError: if (subCode < 0) { subCode *= -1; } m = &zrtpMap[subCode]; break; default: break; } return m; } #endif twinkle-1.4.2/src/audio/audio_codecs.cpp0000644000175000001440000000556411127714055015142 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "audio_codecs.h" unsigned short audio_sample_rate(t_audio_codec codec) { switch(codec) { case CODEC_G711_ALAW: case CODEC_G711_ULAW: case CODEC_GSM: case CODEC_SPEEX_NB: case CODEC_ILBC: case CODEC_G726_16: case CODEC_G726_24: case CODEC_G726_32: case CODEC_G726_40: case CODEC_TELEPHONE_EVENT: return 8000; case CODEC_SPEEX_WB: return 16000; case CODEC_SPEEX_UWB: return 32000; default: // Use 8000 as default rate return 8000; } } bool is_speex_codec(t_audio_codec codec) { return (codec == CODEC_SPEEX_NB || codec == CODEC_SPEEX_WB || codec == CODEC_SPEEX_UWB); } int resample(short *input_buf, int input_len, int input_sample_rate, short *output_buf, int output_len, int output_sample_rate) { if (input_sample_rate > output_sample_rate) { int downsample_factor = input_sample_rate / output_sample_rate; int output_idx = -1; for (int i = 0; i < input_len; i += downsample_factor) { output_idx = i / downsample_factor; if (output_idx >= output_len) { // Output buffer is full return output_len; } output_buf[output_idx] = input_buf[i]; } return output_idx + 1; } else { int upsample_factor = output_sample_rate / input_sample_rate; int output_idx = -1; for (int i = 0; i < input_len; i++) { for (int j = 0; j < upsample_factor; j++) { output_idx = i * upsample_factor + j; if (output_idx >= output_len) { // Output buffer is full return output_len; } output_buf[output_idx] = input_buf[i]; } } return output_idx + 1; } } short mix_linear_pcm(short pcm1, short pcm2) { long mixed_sample = long(pcm1) + long(pcm2); // Compress a 17 bit PCM value into a 16-bit value. // The easy way is to divide the value by 2, but this lowers // the volume. // Only lower the volume for the loud values. As for a normal // voice call the values are not that loud, this gives better // quality. if (mixed_sample > 16384) { mixed_sample = 16384 + (mixed_sample - 16384) / 3; } else if (mixed_sample < -16384) { mixed_sample = -16384 - (-16384 - mixed_sample) / 3; } return short(mixed_sample); } twinkle-1.4.2/src/audio/g711.cpp0000644000175000001440000002025111127714055013166 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g711.c * * u-law, A-law and linear PCM conversions. */ /* * December 30, 1994: * Functions linear2alaw, linear2ulaw have been updated to correctly * convert unquantized 16 bit values. * Tables for direct u- to A-law and A- to u-law conversions have been * corrected. * Borge Lindberg, Center for PersonKommunikation, Aalborg University. * bli@cpk.auc.dk * */ #include "g711.h" #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF}; static short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF}; /* copy from CCITT G.711 specifications */ unsigned char _u2a[128] = { /* u- to A-law conversions */ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* corrected: 81, 82, 83, 84, 85, 86, 87, 88, should be: */ 80, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128}; unsigned char _a2u[128] = { /* A- to u-law conversions */ 1, 3, 5, 7, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 72, /* corrected: 73, 74, 75, 76, 77, 78, 79, 79, should be: */ 73, 74, 75, 76, 77, 78, 79, 80, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; static short search( short val, short *table, short size) { short i; for (i = 0; i < size; i++) { if (val <= *table++) return (i); } return (size); } /* * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law * * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. * * Linear Input Code Compressed Code * ------------------------ --------------- * 0000000wxyza 000wxyz * 0000001wxyza 001wxyz * 000001wxyzab 010wxyz * 00001wxyzabc 011wxyz * 0001wxyzabcd 100wxyz * 001wxyzabcde 101wxyz * 01wxyzabcdef 110wxyz * 1wxyzabcdefg 111wxyz * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char linear2alaw( short pcm_val) /* 2's complement (16-bit range) */ { short mask; short seg; unsigned char aval; pcm_val = pcm_val >> 3; if (pcm_val >= 0) { mask = 0xD5; /* sign (7th) bit = 1 */ } else { mask = 0x55; /* sign bit = 0 */ pcm_val = -pcm_val - 1; } /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_aend, 8); /* Combine the sign, segment, and quantization bits. */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { aval = (unsigned char) seg << SEG_SHIFT; if (seg < 2) aval |= (pcm_val >> 1) & QUANT_MASK; else aval |= (pcm_val >> seg) & QUANT_MASK; return (aval ^ mask); } } /* * alaw2linear() - Convert an A-law value to 16-bit linear PCM * */ short alaw2linear( unsigned char a_val) { short t; short seg; a_val ^= 0x55; t = (a_val & QUANT_MASK) << 4; seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; switch (seg) { case 0: t += 8; break; case 1: t += 0x108; break; default: t += 0x108; t <<= seg - 1; } return ((a_val & SIGN_BIT) ? t : -t); } #define BIAS (0x84) /* Bias for linear code. */ #define CLIP 8159 /* * linear2ulaw() - Convert a linear PCM value to u-law * * In order to simplify the encoding process, the original linear magnitude * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * * Biased Linear Input Code Compressed Code * ------------------------ --------------- * 00000001wxyza 000wxyz * 0000001wxyzab 001wxyz * 000001wxyzabc 010wxyz * 00001wxyzabcd 011wxyz * 0001wxyzabcde 100wxyz * 001wxyzabcdef 101wxyz * 01wxyzabcdefg 110wxyz * 1wxyzabcdefgh 111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number * of leading 0's. The quantization interval is directly available as the * four bits wxyz. * The trailing bits (a - h) are ignored. * * Ordinarily the complement of the resulting code word is used for * transmission, and so the code word is complemented before it is returned. * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char linear2ulaw( short pcm_val) /* 2's complement (16-bit range) */ { short mask; short seg; unsigned char uval; /* Get the sign and the magnitude of the value. */ pcm_val = pcm_val >> 2; if (pcm_val < 0) { pcm_val = -pcm_val; mask = 0x7F; } else { mask = 0xFF; } if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ pcm_val += (BIAS >> 2); /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_uend, 8); /* * Combine the sign, segment, quantization bits; * and complement the code word. */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); return (uval ^ mask); } } /* * ulaw2linear() - Convert a u-law value to 16-bit linear PCM * * First, a biased linear code is derived from the code word. An unbiased * output can then be obtained by subtracting 33 from the biased code. * * Note that this function expects to be passed the complement of the * original code word. This is in keeping with ISDN conventions. */ short ulaw2linear( unsigned char u_val) { short t; /* Complement to obtain normal u-law value. */ u_val = ~u_val; /* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */ t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); } /* A-law to u-law conversion */ unsigned char alaw2ulaw( unsigned char aval) { aval &= 0xff; return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : (0x7F ^ _a2u[aval ^ 0x55])); } /* u-law to A-law conversion */ unsigned char ulaw2alaw( unsigned char uval) { uval &= 0xff; return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1))); } twinkle-1.4.2/src/audio/tone_gen.cpp0000644000175000001440000001301111134632133014273 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "tone_gen.h" #include "log.h" #include "sys_settings.h" #include "user.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" #include "audio_device.h" // Number of samples read at once from the wav file #define NUM_SAMPLES_PER_TURN 1024 // Duration of one turn in ms #define DURATION_TURN (NUM_SAMPLES_PER_TURN * 1000 / wav_info.samplerate) // Main function for play thread void *tone_gen_play(void *arg) { ui->add_prohibited_thread(); t_tone_gen *tg = (t_tone_gen *)arg; tg->play(); ui->remove_prohibited_thread(); return NULL; } t_tone_gen::t_tone_gen(const string &filename, const t_audio_device &_dev_tone) : dev_tone(_dev_tone), sema_finished(0) { string f; wav_file = NULL; aio = 0; valid = false; data_buf = NULL; thr_play = NULL; loop = false; pause = 0; if (filename.size() == 0) return; // Add share directory to filename if (filename[0] != '/') { f = sys_config->get_dir_share(); f += "/"; f += filename; } else { f = filename; } wav_filename = f; memset(&wav_info, 0, sizeof(SF_INFO)); wav_file = sf_open(f.c_str(), SFM_READ, &wav_info); if (!wav_file) { string msg("Cannot open "); msg += f; log_file->write_report(msg, "t_tone_gen::t_tone_gen", LOG_NORMAL, LOG_WARNING); ui->cb_display_msg(msg, MSG_WARNING); return; } log_file->write_header("t_tone_gen::t_tone_gen"); log_file->write_raw("Opened "); log_file->write_raw(f); log_file->write_endl(); log_file->write_footer(); valid = true; stop_playing = false; } t_tone_gen::~t_tone_gen() { if (wav_file) { sf_close(wav_file); } if (aio) { MEMMAN_DELETE(aio); delete aio; } aio = 0; if (data_buf) { MEMMAN_DELETE_ARRAY(data_buf); delete [] data_buf; } if (thr_play) { MEMMAN_DELETE(thr_play); delete thr_play; } log_file->write_report("Deleted tone generator.", "t_tone_gen::~t_tone_gen"); } bool t_tone_gen::is_valid(void) const { return valid; } void t_tone_gen::play(void) { if (!valid) { log_file->write_report( "Tone generator is invalid. Cannot play tone", "t_tone_gen::play", LOG_NORMAL, LOG_WARNING); sema_finished.up(); return; } aio = t_audio_io::open(dev_tone, true, false, true, wav_info.channels, SAMPLEFORMAT_S16, wav_info.samplerate, false); if (!aio) { string msg("Failed to open sound card: "); msg += get_error_str(errno); log_file->write_report(msg, "t_tone_gen::play", LOG_NORMAL, LOG_WARNING); ui->cb_display_msg(msg, MSG_WARNING); sema_finished.up(); return; } log_file->write_report("Start playing tone.", "t_tone_gen::play"); do { // Each samples consists of #channels shorts data_buf = new short[NUM_SAMPLES_PER_TURN * wav_info.channels]; MEMMAN_NEW_ARRAY(data_buf); sf_count_t frames_read = NUM_SAMPLES_PER_TURN; while (frames_read == NUM_SAMPLES_PER_TURN) { if (stop_playing) break; // Play sample frames_read = sf_readf_short(wav_file, data_buf, NUM_SAMPLES_PER_TURN); if (frames_read > 0) { aio->write((unsigned char*)data_buf, frames_read * wav_info.channels * 2); } } MEMMAN_DELETE_ARRAY(data_buf); delete [] data_buf; data_buf = NULL; if (stop_playing) break; // Pause between repetitions if (loop) { // Play silence if (pause > 0) { data_buf = new short[NUM_SAMPLES_PER_TURN * wav_info.channels]; MEMMAN_NEW_ARRAY(data_buf); memset(data_buf, 0, NUM_SAMPLES_PER_TURN * wav_info.channels * 2); for (int i = 0; i < pause; i += DURATION_TURN) { aio->write((unsigned char*)data_buf, NUM_SAMPLES_PER_TURN * wav_info.channels * 2); if (stop_playing) break; } MEMMAN_DELETE_ARRAY(data_buf); delete [] data_buf; data_buf = NULL; } if (stop_playing) break; // Set file pointer back to start of data sf_seek(wav_file, 0, SEEK_SET); } } while (loop); log_file->write_report("Tone ended.", "t_tone_gen::play_tone"); sema_finished.up(); } void t_tone_gen::start_play_thread(bool _loop, int _pause) { loop = _loop; pause = _pause; thr_play = new t_thread(tone_gen_play, this); MEMMAN_NEW(thr_play); thr_play->detach(); } void t_tone_gen::stop(void) { log_file->write_report("Stopping tone.", "t_tone_gen::stop"); if (stop_playing) { log_file->write_report("Tone has stopped already.", "t_tone_gen::stop"); return; } // This will stop the playing thread. stop_playing = true; // The semaphore will be upped by the playing thread as soon // as playing finishes. sema_finished.down(); log_file->write_report("Tone stopped.", "t_tone_gen::stop"); if (aio) { MEMMAN_DELETE(aio); delete aio; aio = 0; } } twinkle-1.4.2/src/audio/README_G7110000644000175000001440000000622110503576707013372 00000000000000The files in this directory comprise ANSI-C language reference implementations of the CCITT (International Telegraph and Telephone Consultative Committee) G.711, G.721 and G.723 voice compressions. They have been tested on Sun SPARCstations and passed 82 out of 84 test vectors published by CCITT (Dec. 20, 1988) for G.721 and G.723. [The two remaining test vectors, which the G.721 decoder implementation for u-law samples did not pass, may be in error because they are identical to two other vectors for G.723_40.] This source code is released by Sun Microsystems, Inc. to the public domain. Please give your acknowledgement in product literature if this code is used in your product implementation. Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system software. However, Sun's implementations have been optimized for higher performance on SPARCstations. The source files for CCITT conversion routines in this directory are: g72x.h header file for g721.c, g723_24.c and g723_40.c g711.c CCITT G.711 u-law and A-law compression g72x.c common denominator of G.721 and G.723 ADPCM codes g721.c CCITT G.721 32Kbps ADPCM coder (with g72x.c) g723_24.c CCITT G.723 24Kbps ADPCM coder (with g72x.c) g723_40.c CCITT G.723 40Kbps ADPCM coder (with g72x.c) Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked as follows: unsigned char ucode, acode; short pcm_val; ucode = linear2ulaw(pcm_val); ucode = alaw2ulaw(acode); acode = linear2alaw(pcm_val); acode = ulaw2alaw(ucode); pcm_val = ulaw2linear(ucode); pcm_val = alaw2linear(acode); The other CCITT compression routines are invoked as follows: #include "g72x.h" struct g72x_state state; int sample, code; g72x_init_state(&state); code = {g721,g723_24,g723_40}_encoder(sample, coding, &state); sample = {g721,g723_24,g723_40}_decoder(code, coding, &state); where coding = AUDIO_ENCODING_ULAW for 8-bit u-law samples AUDIO_ENCODING_ALAW for 8-bit A-law samples AUDIO_ENCODING_LINEAR for 16-bit linear PCM samples This directory also includes the following sample programs: encode.c CCITT ADPCM encoder decode.c CCITT ADPCM decoder Makefile makefile for the sample programs The sample programs contain examples of how to call the various compression routines and pack/unpack the bits. The sample programs read byte streams from stdin and write to stdout. The input/output data is raw data (no file header or other identifying information is embedded). The sample programs are invoked as follows: encode [-3|4|5] [-a|u|l] outfile decode [-3|4|5] [-a|u|l] outfile where: -3 encode to (decode from) G.723 24kbps (3-bit) data -4 encode to (decode from) G.721 32kbps (4-bit) data [the default] -5 encode to (decode from) G.723 40kbps (5-bit) data -a encode from (decode to) A-law data -u encode from (decode to) u-law data [the default] -l encode from (decode to) 16-bit linear data Examples: # Read 16-bit linear and output G.721 encode -4 -l g721file # Read 40Kbps G.723 and output A-law decode -5 -a alawfile # Compress and then decompress u-law data using 24Kbps G.723 encode -3 ulawout twinkle-1.4.2/src/audio/g721.cpp0000644000175000001440000001223311127714055013170 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g721.c * * Description: * * g721_encoder(), g721_decoder() * * These routines comprise an implementation of the CCITT G.721 ADPCM * coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which * take advantage of work station attributes, such as hardware 2's * complement arithmetic and large memory. Specifically, certain time * consuming operations such as multiplications are replaced * with lookup tables and software 2's complement operations are * replaced with hardware 2's complement. * * The deviation from the bit level specification (lookup tables) * preserves the bit level performance specifications. * * As outlined in the G.721 Recommendation, the algorithm is broken * down into modules. Each section of code below is preceded by * the name of the module which it is implementing. * */ #include "g72x.h" #include "g711.h" static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400}; /* * Maps G.721 code word to reconstructed scale factor normalized log * magnitude values. */ static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048}; /* Maps G.721 code word to log of scale factor multiplier. */ static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12}; /* * Maps G.721 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; /* * g721_encoder() * * Encodes the input vale of linear PCM, A-law or u-law data sl and returns * the resulting code. -1 is returned for unknown input coding value. */ int g721_encoder( int sl, int in_coding, struct g72x_state *state_ptr) { short sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short sr; /* ADDB */ short y; /* MIX */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */ d = sl - se; /* estimation difference */ /* quantize the prediction difference */ y = step_size(state_ptr); /* quantizer step size */ i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */ dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */ dqsez = sr + sez - se; /* pole prediction diff. */ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g721_decoder() * * Description: * * Decodes a 4-bit code of G.721 encoded data of i and * returns the resulting linear PCM, A-law or u-law value. * return -1 for unknown out_coding value. */ int g721_decoder( int i, int out_coding, struct g72x_state *state_ptr) { short sezi, sei, sez, se; /* ACCUM */ short y; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x0f; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* dynamic quantizer step size */ dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was 14-bit dynamic range */ default: return (-1); } } twinkle-1.4.2/src/audio/twinkle_rtp_session.h0000644000175000001440000000277611127714046016275 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef TWINKLE_RTP_SESSION_H #define TWINKLE_RTP_SESSION_H #include "twinkle_config.h" #include #ifdef HAVE_ZRTP #include #else #include #endif using namespace std; using namespace ost; #ifdef HAVE_ZRTP class t_twinkle_rtp_session : public SymmetricZRTPSession { private: bool zrtp_initialized; void init_zrtp(void); public: bool is_zrtp_initialized(void) const; #else class t_twinkle_rtp_session : public SymmetricRTPSession { #endif public: virtual ~t_twinkle_rtp_session(); t_twinkle_rtp_session(const InetHostAddress &host); t_twinkle_rtp_session(const InetHostAddress &host, unsigned short port); uint32 getLastTimestamp(const SyncSource *src=NULL) const; }; #endif twinkle-1.4.2/src/audio/g72x.cpp0000644000175000001440000003406011134631766013306 00000000000000/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g72x.c * * Common routines for G.721 and G.723 conversions. */ #include #include "g72x.h" #include "g711.h" static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000}; /* * quan() * * quantizes the input val against the table of size short integers. * It returns i if table[i - 1] <= val < table[i]. * * Using linear search for simple coding. */ static int quan( int val, short *table, int size) { int i; for (i = 0; i < size; i++) if (val < *table++) break; return (i); } /* * fmult() * * returns the integer product of the 14-bit integer "an" and * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". */ static int fmult( int an, int srn) { short anmag, anexp, anmant; short wanexp, wanmant; short retval; anmag = (an > 0) ? an : ((-an) & 0x1FFF); anexp = quan(anmag, power2, 15) - 6; anmant = (anmag == 0) ? 32 : (anexp >= 0) ? anmag >> anexp : anmag << -anexp; wanexp = anexp + ((srn >> 6) & 0xF) - 13; wanmant = (anmant * (srn & 077) + 0x30) >> 4; retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp); return (((an ^ srn) < 0) ? -retval : retval); } /* * g72x_init_state() * * This routine initializes and/or resets the g72x_state structure * pointed to by 'state_ptr'. * All the initial state values are specified in the CCITT G.721 document. */ void g72x_init_state( struct g72x_state *state_ptr) { int cnta; state_ptr->yl = 34816; state_ptr->yu = 544; state_ptr->dms = 0; state_ptr->dml = 0; state_ptr->ap = 0; for (cnta = 0; cnta < 2; cnta++) { state_ptr->a[cnta] = 0; state_ptr->pk[cnta] = 0; state_ptr->sr[cnta] = 32; } for (cnta = 0; cnta < 6; cnta++) { state_ptr->b[cnta] = 0; state_ptr->dq[cnta] = 32; } state_ptr->td = 0; } /* * predictor_zero() * * computes the estimated signal from 6-zero predictor. * */ int predictor_zero( struct g72x_state *state_ptr) { int i; int sezi; sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); for (i = 1; i < 6; i++) /* ACCUM */ sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); return (sezi); } /* * predictor_pole() * * computes the estimated signal from 2-pole predictor. * */ int predictor_pole( struct g72x_state *state_ptr) { return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); } /* * step_size() * * computes the quantization step size of the adaptive quantizer. * */ int step_size( struct g72x_state *state_ptr) { int y; int dif; int al; if (state_ptr->ap >= 256) return (state_ptr->yu); else { y = state_ptr->yl >> 6; dif = state_ptr->yu - y; al = state_ptr->ap >> 2; if (dif > 0) y += (dif * al) >> 6; else if (dif < 0) y += (dif * al + 0x3F) >> 6; return (y); } } /* * quantize() * * Given a raw sample, 'd', of the difference signal and a * quantization step size scale factor, 'y', this routine returns the * ADPCM codeword to which that sample gets quantized. The step * size scale factor division operation is done in the log base 2 domain * as a subtraction. */ int quantize( int d, /* Raw difference signal sample */ int y, /* Step size multiplier */ short *table, /* quantization table */ int size) /* table size of short integers */ { short dqm; /* Magnitude of 'd' */ short exp; /* Integer part of base 2 log of 'd' */ short mant; /* Fractional part of base 2 log */ short dl; /* Log of magnitude of 'd' */ short dln; /* Step size scale factor normalized log */ int i; /* * LOG * * Compute base 2 log of 'd', and store in 'dl'. */ dqm = abs(d); exp = quan(dqm >> 1, power2, 15); mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */ dl = (exp << 7) + mant; /* * SUBTB * * "Divide" by step size multiplier. */ dln = dl - (y >> 2); /* * QUAN * * Obtain codword i for 'd'. */ i = quan(dln, table, size); if (d < 0) /* take 1's complement of i */ return ((size << 1) + 1 - i); else if (i == 0) /* take 1's complement of 0 */ return ((size << 1) + 1); /* new in 1988 */ else return (i); } /* * reconstruct() * * Returns reconstructed difference signal 'dq' obtained from * codeword 'i' and quantization step size scale factor 'y'. * Multiplication is performed in log base 2 domain as addition. */ int reconstruct( int sign, /* 0 for non-negative value */ int dqln, /* G.72x codeword */ int y) /* Step size multiplier */ { short dql; /* Log of 'dq' magnitude */ short dex; /* Integer part of log */ short dqt; short dq; /* Reconstructed difference signal sample */ dql = dqln + (y >> 2); /* ADDA */ if (dql < 0) { return ((sign) ? -0x8000 : 0); } else { /* ANTILOG */ dex = (dql >> 7) & 15; dqt = 128 + (dql & 127); dq = (dqt << 7) >> (14 - dex); return ((sign) ? (dq - 0x8000) : dq); } } /* * update() * * updates the state variables for each output code */ void update( int code_size, /* distinguish 723_40 with others */ int y, /* quantizer step size */ int wi, /* scale factor multiplier */ int fi, /* for long/short term energies */ int dq, /* quantized prediction difference */ int sr, /* reconstructed signal */ int dqsez, /* difference from 2-pole predictor */ struct g72x_state *state_ptr) /* coder state pointer */ { int cnt; short mag, exp; /* Adaptive predictor, FLOAT A */ short a2p = 0; /* LIMC */ short a1ul; /* UPA1 */ short pks1; /* UPA2 */ short fa1; char tr; /* tone/transition detector */ short ylint, thr2, dqthr; short ylfrac, thr1; short pk0; pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */ mag = dq & 0x7FFF; /* prediction difference magnitude */ /* TRANS */ ylint = state_ptr->yl >> 15; /* exponent part of yl */ ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */ thr1 = (32 + ylfrac) << ylint; /* threshold */ thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */ if (state_ptr->td == 0) /* signal supposed voice */ tr = 0; else if (mag <= dqthr) /* supposed data, but small mag */ tr = 0; /* treated as voice */ else /* signal is data (modem) */ tr = 1; /* * Quantizer scale factor adaptation. */ /* FUNCTW & FILTD & DELAY */ /* update non-steady state step size multiplier */ state_ptr->yu = y + ((wi - y) >> 5); /* LIMB */ if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ state_ptr->yu = 544; else if (state_ptr->yu > 5120) state_ptr->yu = 5120; /* FILTE & DELAY */ /* update steady state step size multiplier */ state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); /* * Adaptive predictor coefficients. */ if (tr == 1) { /* reset a's and b's for modem signal */ state_ptr->a[0] = 0; state_ptr->a[1] = 0; state_ptr->b[0] = 0; state_ptr->b[1] = 0; state_ptr->b[2] = 0; state_ptr->b[3] = 0; state_ptr->b[4] = 0; state_ptr->b[5] = 0; } else { /* update a's and b's */ pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ /* update predictor pole a[1] */ a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); if (dqsez != 0) { fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; if (fa1 < -8191) /* a2p = function of fa1 */ a2p -= 0x100; else if (fa1 > 8191) a2p += 0xFF; else a2p += fa1 >> 5; if (pk0 ^ state_ptr->pk[1]) /* LIMC */ if (a2p <= -12160) a2p = -12288; else if (a2p >= 12416) a2p = 12288; else a2p -= 0x80; else if (a2p <= -12416) a2p = -12288; else if (a2p >= 12160) a2p = 12288; else a2p += 0x80; } /* TRIGB & DELAY */ state_ptr->a[1] = a2p; /* UPA1 */ /* update predictor pole a[0] */ state_ptr->a[0] -= state_ptr->a[0] >> 8; if (dqsez != 0) if (pks1 == 0) state_ptr->a[0] += 192; else state_ptr->a[0] -= 192; /* LIMD */ a1ul = 15360 - a2p; if (state_ptr->a[0] < -a1ul) state_ptr->a[0] = -a1ul; else if (state_ptr->a[0] > a1ul) state_ptr->a[0] = a1ul; /* UPB : update predictor zeros b[6] */ for (cnt = 0; cnt < 6; cnt++) { if (code_size == 5) /* for 40Kbps G.723 */ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9; else /* for G.721 and 24Kbps G.723 */ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; if (dq & 0x7FFF) { /* XOR */ if ((dq ^ state_ptr->dq[cnt]) >= 0) state_ptr->b[cnt] += 128; else state_ptr->b[cnt] -= 128; } } } for (cnt = 5; cnt > 0; cnt--) state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ if (mag == 0) { state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; } else { exp = quan(mag, power2, 15); state_ptr->dq[0] = (dq >= 0) ? (exp << 6) + ((mag << 6) >> exp) : (exp << 6) + ((mag << 6) >> exp) - 0x400; } state_ptr->sr[1] = state_ptr->sr[0]; /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ if (sr == 0) { state_ptr->sr[0] = 0x20; } else if (sr > 0) { exp = quan(sr, power2, 15); state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); } else if (sr > -32768) { mag = -sr; exp = quan(mag, power2, 15); state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; } else state_ptr->sr[0] = 0xFC20; /* DELAY A */ state_ptr->pk[1] = state_ptr->pk[0]; state_ptr->pk[0] = pk0; /* TONE */ if (tr == 1) /* this sample has been treated as data */ state_ptr->td = 0; /* next one will be treated as voice */ else if (a2p < -11776) /* small sample-to-sample correlation */ state_ptr->td = 1; /* signal may be data */ else /* signal is voice */ state_ptr->td = 0; /* * Adaptation speed control. */ state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */ state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */ if (tr == 1) state_ptr->ap = 256; else if (y < 1536) /* SUBTC */ state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else if (state_ptr->td == 1) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= (state_ptr->dml >> 3)) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else state_ptr->ap += (-state_ptr->ap) >> 4; } /* * tandem_adjust(sr, se, y, i, sign) * * At the end of ADPCM decoding, it simulates an encoder which may be receiving * the output of this decoder as a tandem process. If the output of the * simulated encoder differs from the input to this decoder, the decoder output * is adjusted by one level of A-law or u-law codes. * * Input: * sr decoder output linear PCM sample, * se predictor estimate sample, * y quantizer step size, * i decoder input code, * sign sign bit of code i * * Return: * adjusted A-law or u-law compressed sample. */ int tandem_adjust_alaw( int sr, /* decoder output linear PCM sample */ int se, /* predictor estimate sample */ int y, /* quantizer step size */ int i, /* decoder input code */ int sign, short *qtab) { unsigned char sp; /* A-law compressed 8-bit code */ short dx; /* prediction error */ char id; /* quantized prediction error */ int sd; /* adjusted A-law decoded sample value */ int im; /* biased magnitude of i */ int imx; /* biased magnitude of id */ if (sr <= -32768) sr = -1; sp = linear2alaw((sr >> 1) << 3); /* short to A-law compression */ dx = (alaw2linear(sp) >> 2) - se; /* 16-bit prediction error */ id = quantize(dx, y, qtab, sign - 1); if (id == i) { /* no adjustment on sp */ return (sp); } else { /* sp adjustment needed */ /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ im = i ^ sign; /* 2's complement to biased unsigned */ imx = id ^ sign; if (imx > im) { /* sp adjusted to next lower value */ if (sp & 0x80) { sd = (sp == 0xD5) ? 0x55 : ((sp ^ 0x55) - 1) ^ 0x55; } else { sd = (sp == 0x2A) ? 0x2A : ((sp ^ 0x55) + 1) ^ 0x55; } } else { /* sp adjusted to next higher value */ if (sp & 0x80) sd = (sp == 0xAA) ? 0xAA : ((sp ^ 0x55) + 1) ^ 0x55; else sd = (sp == 0x55) ? 0xD5 : ((sp ^ 0x55) - 1) ^ 0x55; } return (sd); } } int tandem_adjust_ulaw( int sr, /* decoder output linear PCM sample */ int se, /* predictor estimate sample */ int y, /* quantizer step size */ int i, /* decoder input code */ int sign, short *qtab) { unsigned char sp; /* u-law compressed 8-bit code */ short dx; /* prediction error */ char id; /* quantized prediction error */ int sd; /* adjusted u-law decoded sample value */ int im; /* biased magnitude of i */ int imx; /* biased magnitude of id */ if (sr <= -32768) sr = 0; sp = linear2ulaw(sr << 2); /* short to u-law compression */ dx = (ulaw2linear(sp) >> 2) - se; /* 16-bit prediction error */ id = quantize(dx, y, qtab, sign - 1); if (id == i) { return (sp); } else { /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ im = i ^ sign; /* 2's complement to biased unsigned */ imx = id ^ sign; if (imx > im) { /* sp adjusted to next lower value */ if (sp & 0x80) sd = (sp == 0xFF) ? 0x7E : sp + 1; else sd = (sp == 0) ? 0 : sp - 1; } else { /* sp adjusted to next higher value */ if (sp & 0x80) sd = (sp == 0x80) ? 0x80 : sp - 1; else sd = (sp == 0x7F) ? 0xFE : sp + 1; } return (sd); } } twinkle-1.4.2/src/audio/rtp_telephone_event.h0000644000175000001440000000440111127714046016224 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 2833 // RTP payload format for DTMF telephone events #ifndef _RTP_TELEPHONE_EVENT_H #define _RTP_TELEPHONE_EVENT_H // RFC 2833 3.10 // DTMF events #define TEL_EV_DTMF_0 0 #define TEL_EV_DTMF_1 1 #define TEL_EV_DTMF_2 2 #define TEL_EV_DTMF_3 3 #define TEL_EV_DTMF_4 4 #define TEL_EV_DTMF_5 5 #define TEL_EV_DTMF_6 6 #define TEL_EV_DTMF_7 7 #define TEL_EV_DTMF_8 8 #define TEL_EV_DTMF_9 9 #define TEL_EV_DTMF_STAR 10 #define TEL_EV_DTMF_POUND 11 #define TEL_EV_DTMF_A 12 #define TEL_EV_DTMF_B 13 #define TEL_EV_DTMF_C 14 #define TEL_EV_DTMF_D 15 #define VALID_DTMF_EV(ev) ( (ev) <= TEL_EV_DTMF_D ) #define VALID_DTMF_SYM(s) ( ((s) >= '0' && (s) <= '9') || \ ((s) >= 'a' && (s) <= 'd') || \ ((s) >= 'A' && (s) <= 'D') || \ (s) == '*' || (s) == '#' ) // RFC 2833 3.5 // Payload format (in network order!!) struct t_rtp_telephone_event { private: unsigned char event : 8; unsigned char volume : 6; bool reserved : 1; bool end : 1; unsigned short duration : 16; public: // Values set/get are in host order void set_event(unsigned char _event); void set_volume(unsigned char _volume); void set_reserved(bool _reserved); void set_end(bool _end); void set_duration(unsigned short _duration); unsigned char get_event(void) const; unsigned char get_volume(void) const; bool get_reserved(void) const; bool get_end(void) const; unsigned short get_duration(void) const; }; unsigned char char2dtmf_ev(char sym); char dtmf_ev2char(unsigned char ev); #endif twinkle-1.4.2/src/audio/audio_rx.cpp0000644000175000001440000006775411141037241014333 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include "audio_rx.h" #include "log.h" #include "phone.h" #include "rtp_telephone_event.h" #include "userintf.h" #include "line.h" #include "sys_settings.h" #include "sequence_number.h" #include "audits/memman.h" extern t_phone *phone; #define SAMPLE_BUF_SIZE (audio_encoder->get_ptime() * audio_encoder->get_sample_rate()/1000 *\ AUDIO_SAMPLE_SIZE/8) // Debug macro to print timestamp #define DEBUG_TS(s) { gettimeofday(&debug_timer, NULL);\ cout << "DEBUG: ";\ cout << debug_timer.tv_sec * 1000 +\ debug_timer.tv_usec / 1000;\ cout << " " << (s) << endl;\ } ////////// // PRIVATE ////////// bool t_audio_rx::get_sound_samples(unsigned short &sound_payload_size, bool &silence) { int status; struct timespec sleeptimer; //struct timeval debug_timer; silence = false; mtx_3way.lock(); if (is_3way && !is_main_rx_3way) { // We are not the main receiver in a 3-way call, so // get the sound samples from the local media buffer. // This buffer will be filled by the main receiver. if (!media_3way_peer_rx->get(input_sample_buf, SAMPLE_BUF_SIZE)) { // The mutex is unlocked before going to sleep. // First I had the mutex unlock after the sleep. // That worked fine with LinuxThreading, but it does // not work with NPTL. It causes a deadlock when // the main receiver calls post_media_peer_rx_3way // as NPTL does not fair scheduling. This thread // simly gets the lock again and the main receiver // dies from starvation. mtx_3way.unlock(); // There is not enough data yet. Sleep for 1 ms. sleeptimer.tv_sec = 0; sleeptimer.tv_nsec = 1000000; nanosleep(&sleeptimer, NULL); return false; } mtx_3way.unlock(); } else { // Don't keep the 3way mutex locked while waiting for the DSP. mtx_3way.unlock(); // Get the sound samples from the DSP status = input_device->read(input_sample_buf, SAMPLE_BUF_SIZE); if (status != SAMPLE_BUF_SIZE) { if (!logged_capture_failure) { // Log this failure only once log_file->write_header("t_audio_rx::get_sound_samples", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": sound capture failed.\n"); log_file->write_raw("Status: "); log_file->write_raw(status); log_file->write_endl(); log_file->write_footer(); logged_capture_failure = true; } stop_running = true; return false; } // If line is muted, then fill sample buffer with silence. // Note that we keep reading the dsp, to prevent the DSP buffers // from filling up. if (get_line()->get_is_muted()) { memset(input_sample_buf, 0, SAMPLE_BUF_SIZE); } } // Convert buffer to a buffer of shorts as the samples are 16 bits short *sb = (short *)input_sample_buf; mtx_3way.lock(); if (is_3way) { // Send the sound samples to the other receiver if we // are the main receiver. // There may be no other receiver when one of the far-ends // has put the call on-hold. if (is_main_rx_3way && peer_rx_3way) { peer_rx_3way->post_media_peer_rx_3way(input_sample_buf, SAMPLE_BUF_SIZE, audio_encoder->get_sample_rate()); } // Mix the sound samples with the 3rd party if (media_3way_peer_tx->get(mix_buf_3way, SAMPLE_BUF_SIZE)) { short *mix_sb = (short *)mix_buf_3way; for (int i = 0; i < SAMPLE_BUF_SIZE / 2; i++) { sb[i] = mix_linear_pcm(sb[i], mix_sb[i]); } } } mtx_3way.unlock(); /*** PREPROCESSING & ENCODING ***/ bool preprocessing_silence = false; #ifdef HAVE_SPEEX // speex acoustic echo cancellation if (audio_session->get_do_echo_cancellation() && !audio_session->get_echo_captured_last()) { spx_int16_t *input_buf = new spx_int16_t[SAMPLE_BUF_SIZE/2]; MEMMAN_NEW_ARRAY(input_buf); for (int i = 0; i < SAMPLE_BUF_SIZE / 2; i++) { input_buf[i] = sb[i]; } speex_echo_capture(audio_session->get_speex_echo_state(), input_buf, sb); audio_session->set_echo_captured_last(true); MEMMAN_DELETE_ARRAY(input_buf); delete [] input_buf; } // preprocessing preprocessing_silence = !speex_preprocess_run(speex_preprocess_state, sb); // According to the speex API documentation the return value // from speex_preprocess_run() is only defined when VAD is // enabled. So to be safe, reset the return value, if VAD is // disabled. if (!speex_dsp_vad) preprocessing_silence = false; #endif // encoding sound_payload_size = audio_encoder->encode(sb, nsamples, payload, payload_size, silence); // recognizing silence (both from preprocessing and encoding) silence = silence || preprocessing_silence; return true; } bool t_audio_rx::get_dtmf_event(void) { // DTMF events are not supported in a 3-way conference if (is_3way) return false; if (!sema_dtmf_q.try_down()) { // No DTMF event available return false; } // Get next DTMF event mtx_dtmf_q.lock(); t_dtmf_event dtmf_event = dtmf_queue.front(); dtmf_queue.pop(); mtx_dtmf_q.unlock(); ui->cb_async_send_dtmf(get_line()->get_line_number(), dtmf_event.dtmf_tone); // Create DTMF player if (dtmf_event.inband) { dtmf_player = new t_inband_dtmf_player(this, audio_encoder, user_config, dtmf_event.dtmf_tone, timestamp, nsamples); MEMMAN_NEW(dtmf_player); // Log DTMF event log_file->write_header("t_audio_rx::get_dtmf_event", LOG_NORMAL); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": start inband DTMF tone - "); log_file->write_raw(dtmf_event.dtmf_tone); log_file->write_endl(); log_file->write_footer(); } else { // The telephone events may have a different sampling rate than // the audio codec. Change nsamples accordingly. nsamples = audio_sample_rate(CODEC_TELEPHONE_EVENT)/1000 * audio_encoder->get_ptime(); dtmf_player = new t_rtp_event_dtmf_player(this, audio_encoder, user_config, dtmf_event.dtmf_tone, timestamp, nsamples); MEMMAN_NEW(dtmf_player); // Log DTMF event log_file->write_header("t_audio_rx::get_dtmf_event", LOG_NORMAL); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": start DTMF event - "); log_file->write_raw(dtmf_event.dtmf_tone); log_file->write_endl(); log_file->write_raw("Payload type: "); log_file->write_raw(pt_telephone_event); log_file->write_endl(); log_file->write_footer(); // Set RTP payload format // HACK: the sample rate for telephone events is 8000, but the // ccRTP stack does not handle it well when the sample rate // changes. When the sample rate of the audio codec is kept // on the ccRTP session settings, then all works fine. rtp_session->setPayloadFormat(DynamicPayloadFormat(pt_telephone_event, audio_encoder->get_sample_rate())); // should be this: audio_sample_rate(CODEC_TELEPHONE_EVENT) // As all RTP event contain the same timestamp, the ccRTP stack will // discard packets when the timestamp gets to old. // Increase the expire timeout value to prevent this. rtp_session->setExpireTimeout((JITTER_BUF_MS + user_config->get_dtmf_duration() + user_config->get_dtmf_pause()) * 1000); } return true; } void t_audio_rx::set_sound_payload_format(void) { nsamples = audio_encoder->get_sample_rate()/1000 * audio_encoder->get_ptime(); rtp_session->setPayloadFormat(DynamicPayloadFormat(audio_encoder->get_payload_id(), audio_encoder->get_sample_rate())); } ////////// // PUBLIC ////////// t_audio_rx::t_audio_rx(t_audio_session *_audio_session, t_audio_io *_input_device, t_twinkle_rtp_session *_rtp_session, t_audio_codec _codec, unsigned short _payload_id, unsigned short _ptime) : sema_dtmf_q(0) { audio_session = _audio_session; user_config = audio_session->get_line()->get_user(); assert(user_config); input_device = _input_device; rtp_session = _rtp_session; dtmf_player = NULL; is_running = false; stop_running = false; logged_capture_failure = false; use_nat_keepalive = phone->use_nat_keepalive(user_config); pt_telephone_event = -1; // Create audio encoder switch (_codec) { case CODEC_G711_ALAW: audio_encoder = new t_g711a_audio_encoder(_payload_id, _ptime, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_G711_ULAW: audio_encoder = new t_g711u_audio_encoder(_payload_id, _ptime, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_GSM: audio_encoder = new t_gsm_audio_encoder(_payload_id, _ptime, user_config); MEMMAN_NEW(audio_encoder); break; #ifdef HAVE_SPEEX case CODEC_SPEEX_NB: audio_encoder = new t_speex_audio_encoder(_payload_id, _ptime, t_speex_audio_encoder::MODE_NB, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_SPEEX_WB: audio_encoder = new t_speex_audio_encoder(_payload_id, _ptime, t_speex_audio_encoder::MODE_WB, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_SPEEX_UWB: audio_encoder = new t_speex_audio_encoder(_payload_id, _ptime, t_speex_audio_encoder::MODE_UWB, user_config); MEMMAN_NEW(audio_encoder); break; #endif #ifdef HAVE_ILBC case CODEC_ILBC: audio_encoder = new t_ilbc_audio_encoder(_payload_id, _ptime, user_config); MEMMAN_NEW(audio_encoder); break; #endif case CODEC_G726_16: audio_encoder = new t_g726_audio_encoder(_payload_id, _ptime, t_g726_audio_encoder::BIT_RATE_16, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_G726_24: audio_encoder = new t_g726_audio_encoder(_payload_id, _ptime, t_g726_audio_encoder::BIT_RATE_24, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_G726_32: audio_encoder = new t_g726_audio_encoder(_payload_id, _ptime, t_g726_audio_encoder::BIT_RATE_32, user_config); MEMMAN_NEW(audio_encoder); break; case CODEC_G726_40: audio_encoder = new t_g726_audio_encoder(_payload_id, _ptime, t_g726_audio_encoder::BIT_RATE_40, user_config); MEMMAN_NEW(audio_encoder); break; default: assert(false); } payload_size = audio_encoder->get_max_payload_size(); input_sample_buf = new unsigned char[SAMPLE_BUF_SIZE]; MEMMAN_NEW_ARRAY(input_sample_buf); payload = new unsigned char[payload_size]; MEMMAN_NEW_ARRAY(payload); nsamples = audio_encoder->get_sample_rate()/1000 * audio_encoder->get_ptime(); // Initialize 3-way settings to 'null' media_3way_peer_tx = NULL; media_3way_peer_rx = NULL; peer_rx_3way = NULL; mix_buf_3way = NULL; is_3way = false; is_main_rx_3way = false; #ifdef HAVE_SPEEX // initializing speex preprocessing state speex_preprocess_state = speex_preprocess_state_init(nsamples, audio_encoder->get_sample_rate()); int arg; float farg; // Noise reduction arg = (user_config->get_speex_dsp_nrd() ? 1 : 0); speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_DENOISE, &arg); arg = -30; speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &arg); // Automatic gain control arg = (user_config->get_speex_dsp_agc() ? 1 : 0); speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC, &arg); farg = (float) (user_config->get_speex_dsp_agc_level()) * 327.68f; speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &farg); arg = 30; speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &arg); // Voice activity detection arg = (user_config->get_speex_dsp_vad() ? 1 : 0); speex_dsp_vad = (bool)arg; speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_VAD, &arg); // Acoustic echo cancellation if (audio_session->get_do_echo_cancellation()) { speex_preprocess_ctl(speex_preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE, audio_session->get_speex_echo_state()); } #endif } t_audio_rx::~t_audio_rx() { struct timespec sleeptimer; if (is_running) { stop_running = true; do { sleeptimer.tv_sec = 0; sleeptimer.tv_nsec = 10000000; nanosleep(&sleeptimer, NULL); } while (is_running); } #ifdef HAVE_SPEEX // cleaning speex preprocessing if (audio_session->get_do_echo_cancellation()) { speex_echo_state_reset(audio_session->get_speex_echo_state()); } speex_preprocess_state_destroy(speex_preprocess_state); #endif MEMMAN_DELETE_ARRAY(input_sample_buf); delete [] input_sample_buf; MEMMAN_DELETE_ARRAY(payload); delete [] payload; MEMMAN_DELETE(audio_encoder); delete audio_encoder; // Clean up resources for 3-way conference calls if (media_3way_peer_tx) { MEMMAN_DELETE(media_3way_peer_tx); delete media_3way_peer_tx; } if (media_3way_peer_rx) { MEMMAN_DELETE(media_3way_peer_rx); delete media_3way_peer_rx; } if (mix_buf_3way) { MEMMAN_DELETE_ARRAY(mix_buf_3way); delete [] mix_buf_3way; } if (dtmf_player) { MEMMAN_DELETE(dtmf_player); delete dtmf_player; } } void t_audio_rx::set_running(bool running) { is_running = running; } // NOTE: no operations on the phone object are allowed inside the run() method. // Such an operation needs a lock on the transaction layer. The destructor // on audio_rx is called while this lock is locked. The destructor waits // in a busy loop for the run() method to finish. If the run() method would // need the phone lock, this would lead to a dead lock (and a long trip // in debug hell!) void t_audio_rx::run(void) { //struct timeval debug_timer; unsigned short sound_payload_size; uint32 dtmf_rtp_timestamp; phone->add_prohibited_thread(); ui->add_prohibited_thread(); // This flag indicates if we are currently in a silence period. // The start of a new stream is assumed to start in silence, such // that the very first RTP packet will be marked. bool silence_period = true; uint64 silence_nsamples = 0; // duration in samples // This flag indicates if a sound frame can be suppressed bool suppress_samples = false; // The running flag is set already in t_audio_session::run to prevent // a crash when the thread gets destroyed before it starts running. // is_running = true; // For a 3-way conference only the main receiver has access // to the dsp. if (!is_3way || is_main_rx_3way) { // Enable recording if (sys_config->equal_audio_dev(sys_config->get_dev_speaker(), sys_config->get_dev_mic())) { input_device->enable(true, true); } else { input_device->enable(false, true); } // If the stream is stopped for call-hold, then the buffer might // be filled with old sound samples. input_device->flush(false, true); } // Synchronize the timestamp driven by the sampling rate // of the recording with the timestamp of the RTP session. // As the RTP session is already created in advance, the // RTP clock is a bit ahead already. timestamp = rtp_session->getCurrentTimestamp() + nsamples; // This loop keeps running until the stop_running flag is set to true. // When a call is being released the stop_running flag is set to true. // At that moment the lock on the transaction layer (phone) is taken. // So do not use operations that take the phone lock, otherwise a // dead lock may occur during call release. while (true) { if (stop_running) break; if (dtmf_player) { rtp_session->setMark(false); // Skip samples from sound card input_device->read(input_sample_buf, SAMPLE_BUF_SIZE); sound_payload_size = dtmf_player->get_payload( payload, payload_size, timestamp, dtmf_rtp_timestamp); silence_period = false; } else if (get_dtmf_event()) { // RFC 2833 // Set marker in first RTP packet of a DTMF event rtp_session->setMark(true); // Skip samples from sound card input_device->read(input_sample_buf, SAMPLE_BUF_SIZE); assert(dtmf_player); sound_payload_size = dtmf_player->get_payload( payload, payload_size, timestamp, dtmf_rtp_timestamp); silence_period = false; } else if (get_sound_samples(sound_payload_size, suppress_samples)) { if (suppress_samples && use_nat_keepalive) { if (!silence_period) silence_nsamples = 0; // Send a silence packet at the NAT keep alive interval // to keep the NAT bindings for RTP fresh. silence_nsamples += SAMPLE_BUF_SIZE / 2; if (silence_nsamples > (uint64_t)user_config->get_timer_nat_keepalive() * 1000 * audio_encoder->get_sample_rate()) { suppress_samples = false; } } if (silence_period && !suppress_samples) { // RFC 3551 4.1 // Set marker bit in first RTP packet after silence rtp_session->setMark(true); } else { rtp_session->setMark(false); } silence_period = suppress_samples; } else { continue; } // If timestamp is more than 1 payload size ahead of the clock of // the ccRTP stack, then drop the current payload and do not advance // the timestamp. This will happen if the DSP delivers more // sound samples than the set sample rate. To compensate for this // samples must be dropped. uint32 current_timestamp = rtp_session->getCurrentTimestamp(); if (seq32_t(timestamp) <= seq32_t(current_timestamp + nsamples)) { if (dtmf_player) { // Send DTMF payload rtp_session->putData(dtmf_rtp_timestamp, payload, sound_payload_size); // If DTMF has ended then set payload back to sound if (dtmf_player->finished()) { set_sound_payload_format(); MEMMAN_DELETE(dtmf_player); delete dtmf_player; dtmf_player = NULL; } } else if (!suppress_samples) { // Send sound samples // Set the expire timeout to the jitter buffer size. // This allows for old packets still to be sent out. rtp_session->setExpireTimeout(MAX_OUT_AUDIO_DELAY_MS * 1000); rtp_session->putData(timestamp, payload, sound_payload_size); } timestamp += nsamples; } else { log_file->write_header("t_audio_rx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": discarded surplus of sound samples.\n"); log_file->write_raw("Timestamp: "); log_file->write_raw(timestamp); log_file->write_endl(); log_file->write_raw("Current timestamp: "); log_file->write_raw(current_timestamp); log_file->write_endl(); log_file->write_raw("nsamples: "); log_file->write_raw(nsamples); log_file->write_endl(); log_file->write_footer(); } // If there is enough data in the DSP buffers to fill another // RTP packet then do not sleep, but immediately go to the // next cycle to play out the data. Probably this thread did // not get enough time, so the buffer filled up. The far end // jitter buffer has to cope with the jitter caused by this. if (is_3way && !is_main_rx_3way) { if (media_3way_peer_rx->size_content() >= SAMPLE_BUF_SIZE) { continue; } } else { if (input_device->get_buffer_space(true) >= SAMPLE_BUF_SIZE) continue; } // There is no data left in the DSP buffers to play out anymore. // So the timestamp must be in sync with the clock of the ccRTP // stack. It might get behind if the sound cards samples a bit // slower than the set sample rate. Advance the timestamp to get // in sync again. current_timestamp = rtp_session->getCurrentTimestamp(); if (seq32_t(timestamp) <= seq32_t(current_timestamp - (JITTER_BUF_MS / audio_encoder->get_ptime()) * nsamples)) { timestamp += nsamples * (JITTER_BUF_MS / audio_encoder->get_ptime()); log_file->write_header("t_audio_rx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": timestamp forwarded by "); log_file->write_raw(nsamples * (JITTER_BUF_MS / audio_encoder->get_ptime())); log_file->write_endl(); log_file->write_raw("Timestamp: "); log_file->write_raw(timestamp); log_file->write_endl(); log_file->write_raw("Current timestamp: "); log_file->write_raw(current_timestamp); log_file->write_endl(); log_file->write_raw("nsamples: "); log_file->write_raw(nsamples); log_file->write_endl(); log_file->write_footer(); } } phone->remove_prohibited_thread(); ui->remove_prohibited_thread(); is_running = false; } void t_audio_rx::set_pt_telephone_event(int pt) { pt_telephone_event = pt; } void t_audio_rx::push_dtmf(char digit, bool inband) { // Ignore invalid DTMF digits if (!VALID_DTMF_SYM(digit)) return; // Ignore DTMF tones in a 3-way conference if (is_3way) return; t_dtmf_event dtmf_event; dtmf_event.dtmf_tone = char2dtmf_ev(digit); dtmf_event.inband = inband; mtx_dtmf_q.lock(); dtmf_queue.push(dtmf_event); mtx_dtmf_q.unlock(); sema_dtmf_q.up(); } t_line *t_audio_rx::get_line(void) const { return audio_session->get_line(); } void t_audio_rx::join_3way(bool main_rx, t_audio_rx *peer_rx) { mtx_3way.lock(); if (is_3way) { log_file->write_header("t_audio_rx::join_3way", LOG_NORMAL); log_file->write_raw("ERROR: audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(" - 3way is already active.\n"); log_file->write_footer(); mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_rx::join_3way"); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": join 3-way.\n"); if (main_rx) { log_file->write_raw("Role is: mixer.\n"); } else { log_file->write_raw("Role is: non-mixing.\n"); } if (peer_rx) { log_file->write_raw("A peer receiver already exists.\n"); } else { log_file->write_raw("A peer receiver does not exist.\n"); } log_file->write_footer(); // Create media buffers for the 2 far-ends of a 3-way call. // The size of the media buffer is the size of the jitter buffer. // This allows for jitter in the RTP streams and also for // incompatible payload sizes. Eg. 1 far-end may send 20ms paylaods, // while the other sends 30ms payloads. The outgoing RTP stream might // even have another payload size. // When the data has been captured from the soundcard, it will be // checked if there is enough data available in the media buffers, i.e. // the same amount of data as captured from the soundcard for mixing. // If there is it will be retrieved and mixed. // If there isn't the captured sound will simply be sent on its own // to the far-end. Meanwhile the buffer will fill up with data such // that from the next captured sample there will be sufficient data // for mixing. media_3way_peer_tx = new t_media_buffer( JITTER_BUF_SIZE(audio_encoder->get_sample_rate())); MEMMAN_NEW(media_3way_peer_tx); media_3way_peer_rx = new t_media_buffer( JITTER_BUF_SIZE(audio_encoder->get_sample_rate())); MEMMAN_NEW(media_3way_peer_rx); // Create a mix buffer for one sample frame. mix_buf_3way = new unsigned char[SAMPLE_BUF_SIZE]; MEMMAN_NEW_ARRAY(mix_buf_3way); peer_rx_3way = peer_rx; is_3way = true; is_main_rx_3way = main_rx; // Stop DTMF tones as these are not supported in a 3way if (dtmf_player) { MEMMAN_DELETE(dtmf_player); delete dtmf_player; dtmf_player = NULL; } mtx_3way.unlock(); } void t_audio_rx::set_peer_rx_3way(t_audio_rx *peer_rx) { mtx_3way.lock(); if (!is_3way) { mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_rx::set_peer_rx_3way"); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); if (peer_rx) { log_file->write_raw(": set peer receiver.\n"); } else { log_file->write_raw(": erase peer receiver.\n"); } if (is_main_rx_3way) { log_file->write_raw("Role is: mixer.\n"); } else { log_file->write_raw("Role is: non-mixing.\n"); } log_file->write_footer(); peer_rx_3way = peer_rx; mtx_3way.unlock(); } void t_audio_rx::set_main_rx_3way(bool main_rx) { mtx_3way.lock(); if (!is_3way) { mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_rx::set_main_rx_3way"); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); if (main_rx) { log_file->write_raw(": change role to: mixer.\n"); } else { log_file->write_raw(": change role to: non-mixing.\n"); } log_file->write_footer(); // Initialize the DSP if we become the mixer and we were not before if (main_rx && !is_main_rx_3way) { // Enable recording if (sys_config->equal_audio_dev(sys_config->get_dev_speaker(), sys_config->get_dev_mic())) { input_device->enable(true, true); } else { input_device->enable(false, true); } // If the stream is stopped for call-hold, then the buffer might // be filled with old sound samples. input_device->flush(false, true); } is_main_rx_3way = main_rx; mtx_3way.unlock(); } void t_audio_rx::stop_3way(void) { mtx_3way.lock(); if (!is_3way) { log_file->write_header("t_audio_rx::stop_3way"); log_file->write_raw("ERROR: audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(" - 3way is not active.\n"); log_file->write_footer(); mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_rx::stop_3way"); log_file->write_raw("Audio rx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": stop 3-way.\n"); log_file->write_footer(); is_3way = false; is_main_rx_3way = false; peer_rx_3way = NULL; MEMMAN_DELETE(media_3way_peer_tx); delete media_3way_peer_tx; media_3way_peer_tx = NULL; MEMMAN_DELETE(media_3way_peer_rx); delete media_3way_peer_rx; media_3way_peer_rx = NULL; MEMMAN_DELETE_ARRAY(mix_buf_3way); delete [] mix_buf_3way; mix_buf_3way = NULL; mtx_3way.unlock(); } void t_audio_rx::post_media_peer_tx_3way(unsigned char *media, int len, unsigned short peer_sample_rate) { mtx_3way.lock(); if (!is_3way) { // This is not a 3-way call. This is not necessarily an // error condition. The 3rd party may be in the process of // leaving the conference. // Simply discard the posted media mtx_3way.unlock(); return; } if (peer_sample_rate != audio_encoder->get_sample_rate()) { // Resample media from peer to sample rate of this receiver int output_len = (len / 2) * audio_encoder->get_sample_rate() / peer_sample_rate; short *output_buf = new short[output_len]; MEMMAN_NEW_ARRAY(output_buf); int resample_len = resample((short *)media, len / 2, peer_sample_rate, output_buf, output_len, audio_encoder->get_sample_rate()); media_3way_peer_tx->add((unsigned char *)output_buf, resample_len * 2); MEMMAN_DELETE_ARRAY(output_buf); delete [] output_buf; } else { media_3way_peer_tx->add(media, len); } mtx_3way.unlock(); } void t_audio_rx::post_media_peer_rx_3way(unsigned char *media, int len, unsigned short peer_sample_rate) { mtx_3way.lock(); if (!is_3way) { // This is not a 3-way call. This is not necessarily an // error condition. The 3rd party may be in the process of // leaving the conference. // Simply discard the posted media mtx_3way.unlock(); return; } if (peer_sample_rate != audio_encoder->get_sample_rate()) { // Resample media from peer to sample rate of this receiver int output_len = (len / 2) * audio_encoder->get_sample_rate() / peer_sample_rate; short *output_buf = new short[output_len]; MEMMAN_NEW_ARRAY(output_buf); int resample_len = resample((short *)media, len / 2, peer_sample_rate, output_buf, output_len, audio_encoder->get_sample_rate()); media_3way_peer_rx->add((unsigned char *)output_buf, resample_len * 2); MEMMAN_DELETE_ARRAY(output_buf); delete [] output_buf; } else { media_3way_peer_rx->add(media, len); } mtx_3way.unlock(); } bool t_audio_rx::get_is_main_rx_3way(void) const { return is_main_rx_3way; } twinkle-1.4.2/src/audio/audio_rx.h0000644000175000001440000001462411140746537014002 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _AUDIO_RX_H #define _AUDIO_RX_H // Receive audio from the soundcard and send it to the RTP thread. #include #include #include #include "audio_codecs.h" #include "audio_device.h" #include "audio_encoder.h" #include "dtmf_player.h" #include "media_buffer.h" #include "user.h" #include "threads/mutex.h" #include "threads/sema.h" #include "twinkle_rtp_session.h" #include "twinkle_config.h" #ifdef HAVE_SPEEX #include #include #endif using namespace std; using namespace ost; // Forward declarations class t_audio_session; class t_line; class t_audio_rx { private: // audio_session owning this audio receiver t_audio_session *audio_session; // User profile of user using the line // This is a pointer to the user_config owned by a phone user. // So this pointer should never be deleted. t_user *user_config; // file descriptor audio capture device t_audio_io* input_device; // RTP session t_twinkle_rtp_session *rtp_session; // Media buffer to buffer media from the peer audio trasmitter in a // 3-way call. This media stream will be mixed with the // audio captured from the soundcard. t_media_buffer *media_3way_peer_tx; // Media captured by the peer audio receiver in a 3-way conference t_media_buffer *media_3way_peer_rx; // The peer audio receiver in a 3-way conference. t_audio_rx *peer_rx_3way; // Buffer for mixing purposes in 3-way conference. unsigned char *mix_buf_3way; // Indicates if this receiver is part of a 3-way conference call bool is_3way; // Indicates if this is this receiver has to capture sound from the // soundcard. In a 3-way call, one receiver captures sound, while the // other receiver simply takes the sound from the main receiver. bool is_main_rx_3way; // Mutex to protect actions on 3-way conference data t_mutex mtx_3way; // Audio encoder t_audio_encoder *audio_encoder; // Buffer to store PCM samples for ptime ms unsigned char *input_sample_buf; // Indicates if NAT keep alive packets must be sent during silence // suppression. bool use_nat_keepalive; // RTP payload unsigned short payload_size; unsigned char *payload; unsigned short nsamples; // number of samples taken per packet // Payload type for telephone-event payload. int pt_telephone_event; // Queue of DTMF tones to be sent struct t_dtmf_event { uint8 dtmf_tone; bool inband; }; queue dtmf_queue; t_mutex mtx_dtmf_q; t_semaphore sema_dtmf_q; // DTMF player t_dtmf_player *dtmf_player; // Inidicates if the recording thread is running volatile bool is_running; // The thread exits when this indicator is set to true volatile bool stop_running; // Indicates if a capture failure was already logged (log throttling). bool logged_capture_failure; // Timestamp for next RTP packet unsigned long timestamp; #ifdef HAVE_SPEEX /** Speex preprocessor state */ SpeexPreprocessState *speex_preprocess_state; /** Speex VAD enabled? */ bool speex_dsp_vad; #endif // Get sound samples for 1 RTP packet from the soundcard. // Returns false if the main loop has to start another cycle to get // samples (eg. no samples available yet). // If not enough samples are available yet, then a 1 ms sleep will be taken. // Also returns false if capturing samples from the soundcard failed. // Returns true if sounds samples are received. The samples are stored // in the payload buffer in the proper encoding. // The number bytes of the sound payload is returned in sound_payload_size // The silence flag indicates if the returned sound samples represent silence // that may be suppressed. bool get_sound_samples(unsigned short &sound_payload_size, bool &silence); // Get next DTMF event generated by the user. // Returns false if there is no next DTMF event bool get_dtmf_event(void); // Set RTP payload for outgoing sound packets based on the codec. void set_sound_payload_format(void); public: // Create the audio receiver // _fd file descriptor of capture device // _rtp_session RTP socket tp send the RTP stream // _codec audio codec to use // _ptime length of the audio packets in ms // _ptime = 0 means use default ptime value for the codec t_audio_rx(t_audio_session *_audio_session, t_audio_io *_input_device, t_twinkle_rtp_session *_rtp_session, t_audio_codec _codec, unsigned short _payload_id, unsigned short _ptime = 0); ~t_audio_rx(); // Set the is running flag void set_running(bool running); void run(void); // Set the dynamic payload type for telephone events void set_pt_telephone_event(int pt); // Push a new DTMF tone in the DTMF queue void push_dtmf(char digit, bool inband); // Get phone line belonging to this audio transmitter t_line *get_line(void) const; // Join a 3-way conference call. // main_rx indicates if this receiver must be the main receiver capturing // the sound from the soundcard. // The peer_rx is the peer receiver (may be NULL( void join_3way(bool main_rx, t_audio_rx *peer_rx); // Change the peer receiver in a 3-way (set to NULL to erase). void set_peer_rx_3way(t_audio_rx *peer_rx); // Change the main rx role in a 3-way void set_main_rx_3way(bool main_rx); // Delete 3rd party from a 3-way conference. void stop_3way(void); // Post media from the peer transmitter in a 3-way. void post_media_peer_tx_3way(unsigned char *media, int len, unsigned short peer_sample_rate); // Post media from the peer receiver in a 3-way. void post_media_peer_rx_3way(unsigned char *media, int len, unsigned short peer_sample_rate); // Returns if this receiver is the main receiver in a 3-way bool get_is_main_rx_3way(void) const; }; #endif twinkle-1.4.2/src/audio/audio_tx.h0000644000175000001440000001513011127714046013770 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _AUDIO_TX_H #define _AUDIO_TX_H // Receive RTP and send audio to soundcard #include #include #include "audio_codecs.h" #include "audio_decoder.h" #include "audio_rx.h" #include "media_buffer.h" #include "rtp_telephone_event.h" #include "user.h" #include "threads/mutex.h" #include "gsm/inc/gsm.h" #include "audio_device.h" #include "twinkle_rtp_session.h" #include "twinkle_config.h" using namespace std; using namespace ost; // Forward declarations class t_audio_session; class t_line; class t_audio_tx { private: // audio_session owning this audio transmitter t_audio_session *audio_session; // User profile of user using the line // This is a pointer to the user_config owned by a phone user. // So this pointer should never be deleted. t_user *user_config; // file descriptor audio capture device t_audio_io *playback_device; t_twinkle_rtp_session *rtp_session; // Indicates if this transmitter is part of a 3-way conference bool is_3way; // Indicates if this transmitter is the mixer in a 3-way conference. // The mixer will mix this audio stream with the audio from the other // party and send it to the soundcard. // If the transmitter is part of a 3-way conference, but not the // mixer, then it simply has to send its audio payload to the mixer. bool is_3way_mixer; // Media buffer for media from the other far-end. This buffer is // used by the mixer. t_media_buffer *media_3way_peer_tx; // The peer audio transmitter in a 3-way conference t_audio_tx *peer_tx_3way; // The audio receiver that needs input from this transmitter in // a 3-way conference. t_audio_rx *peer_rx_3way; // Buffer for mixing purposes in 3-way conference. unsigned char *mix_buf_3way; // Mutex to protect 3-way resources t_mutex mtx_3way; // Codec information t_audio_codec codec; map payload2codec; unsigned short ptime; // in milliseconds // Sample rate of sound card. // The sample rate of the sound card is set to the sample rate // used for the initial codec. The far end may dynamically switch // to a codec with another sample rate. This will not change the // sample rate of the sound card! (capture and playback cannot // be done at different sampling rates). unsigned short sc_sample_rate; // Mapping from codecs to decoders map map_audio_decoder; // Buffer to store PCM samples of a received RTP packet unsigned char *sample_buf; // Jitter buffer (PCM). // jitter_buf_len indicates the number of bytes in the jitter buffer. // At the start of playing the samples are stored in the jitter buffer. // Once the buffer is full, all samples are copied to the memory of // the soundcard. From that point the soundcard itself is the jitter // buffer. unsigned char *jitter_buf; unsigned short jitter_buf_len; bool load_jitter_buf; // Buffer to keep last played packets for concealment. unsigned char *conceal_buf[MAX_CONCEALMENT]; unsigned short conceal_buflen[MAX_CONCEALMENT]; // length of packet short conceal_pos; // points to the oldest packet. short conceal_num; // number of retained packets. unsigned short soundcard_buf_size; // Payload type for telephone-event payload. // Some endpoints ignore the payload type that was sent in an // outgoing INVITE and simply sends it with the payload type, // they indicated in the 200 OK. Accept both payloads for // interoperability. int pt_telephone_event; int pt_telephone_event_alt; // Timestamp of previous DTMF tone unsigned long dtmf_previous_timestamp; // Inidicates if the playing thread is running volatile bool is_running; // The thread exits when this indicator is set to true volatile bool stop_running; // Retain a packet (PCM encoded) for possible concealment. void retain_for_concealment(unsigned char *buf, unsigned short len); // Play last num packets again. void conceal(short num); // Erase concealment buffers. void clear_conceal_buf(void); // Play PCM encoded samples // - only_3rd_party indicates if there is only 3rd_party audio available, // i.e. due to jitter, packet loss or silence suppression void play_pcm(unsigned char *buf, unsigned short len, bool only_3rd_party = false); public: // Create the audio transmitter // _fd file descriptor of capture device // _rtp_session RTP socket tp send the RTP stream // _codec audio codec to use // _ptime length of the audio packets in ms // _ptime = 0 means use default ptime value for the codec t_audio_tx(t_audio_session *_audio_session, t_audio_io *_playback_device, t_twinkle_rtp_session *_rtp_session, t_audio_codec _codec, const map &_payload2codec, unsigned short _ptime = 0); ~t_audio_tx(); // Set the is running flag void set_running(bool running); void run(void); // Set the dynamic payload type for telephone events void set_pt_telephone_event(int pt, int pt_alt); // Get phone line belonging to this audio transmitter t_line *get_line(void) const; // Join this transmitter in a 3way conference. // mixer indicates if this transmitter must be the mixer. // - peer_tx is the peer transmitter in a 3-way // - audio_rx is the audio receiver needing the output from this // transmitter for mixing. void join_3way(bool mixer, t_audio_tx *peer_tx, t_audio_rx *peer_rx); // Change the peer rx/tx (NULL to erase) void set_peer_tx_3way(t_audio_tx *peer_tx); void set_peer_rx_3way(t_audio_rx *peer_rx); // Change the mixer role void set_mixer_3way(bool mixer); // Stop the 3-way conference and make it a 1-on-1 call again. void stop_3way(void); // Post media from the peer transmitter for a 3-way mixer. void post_media_peer_tx_3way(unsigned char *media, int len, unsigned short peer_sample_rate); // Returns if this transmitter is the mixer in a 3-way bool get_is_3way_mixer(void) const; }; #endif twinkle-1.4.2/src/audio/audio_tx.cpp0000644000175000001440000007313111134631374014330 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include "audio_tx.h" #include "log.h" #include "phone.h" #include "userintf.h" #include "util.h" #include "line.h" #include "sequence_number.h" #include "audits/memman.h" extern t_phone *phone; #define SAMPLE_BUF_SIZE (MAX_PTIME * sc_sample_rate/1000 * AUDIO_SAMPLE_SIZE/8) // Debug macro to print timestamp #define DEBUG_TS(s) { gettimeofday(&debug_timer, NULL);\ cout << "DEBUG: ";\ cout << debug_timer.tv_sec * 1000 +\ debug_timer.tv_usec / 1000;\ cout << ":" << debug_timer.tv_sec * 1000 + debug_timer.tv_usec / 1000 - (debug_timer_prev.tv_sec * 1000 + debug_timer_prev.tv_usec / 1000);\ cout << " " << (s) << endl;\ debug_timer_prev = debug_timer;\ } ////////// // PUBLIC ////////// t_audio_tx::t_audio_tx(t_audio_session *_audio_session, t_audio_io *_playback_device, t_twinkle_rtp_session *_rtp_session, t_audio_codec _codec, const map &_payload2codec, unsigned short _ptime) { audio_session = _audio_session; user_config = audio_session->get_line()->get_user(); assert(user_config); playback_device = _playback_device; rtp_session = _rtp_session; codec = _codec; sc_sample_rate = audio_sample_rate(_codec); payload2codec = _payload2codec; is_running = false; stop_running = false; // Create audio decoders map_audio_decoder[CODEC_G711_ALAW] = new t_g711a_audio_decoder(_ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_G711_ALAW]); map_audio_decoder[CODEC_G711_ULAW] = new t_g711u_audio_decoder(_ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_G711_ULAW]); map_audio_decoder[CODEC_GSM] = new t_gsm_audio_decoder(user_config); MEMMAN_NEW(map_audio_decoder[CODEC_GSM]); #ifdef HAVE_SPEEX map_audio_decoder[CODEC_SPEEX_NB] = new t_speex_audio_decoder( t_speex_audio_decoder::MODE_NB, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_SPEEX_NB]); map_audio_decoder[CODEC_SPEEX_WB] = new t_speex_audio_decoder( t_speex_audio_decoder::MODE_WB, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_SPEEX_WB]); map_audio_decoder[CODEC_SPEEX_UWB] = new t_speex_audio_decoder( t_speex_audio_decoder::MODE_UWB, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_SPEEX_UWB]); #endif #ifdef HAVE_ILBC map_audio_decoder[CODEC_ILBC] = new t_ilbc_audio_decoder(_ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_ILBC]); #endif map_audio_decoder[CODEC_G726_16] = new t_g726_audio_decoder( t_g726_audio_decoder::BIT_RATE_16, _ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_G726_16]); map_audio_decoder[CODEC_G726_24] = new t_g726_audio_decoder( t_g726_audio_decoder::BIT_RATE_24, _ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_G726_24]); map_audio_decoder[CODEC_G726_32] = new t_g726_audio_decoder( t_g726_audio_decoder::BIT_RATE_32, _ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_G726_32]); map_audio_decoder[CODEC_G726_40] = new t_g726_audio_decoder( t_g726_audio_decoder::BIT_RATE_40, _ptime, user_config); MEMMAN_NEW(map_audio_decoder[CODEC_G726_40]); ptime = map_audio_decoder[codec]->get_default_ptime(); sample_buf = new unsigned char[SAMPLE_BUF_SIZE]; MEMMAN_NEW_ARRAY(sample_buf); // Create concealment buffers for (int i = 0; i < MAX_CONCEALMENT; i++) { conceal_buf[i] = new unsigned char[SAMPLE_BUF_SIZE]; MEMMAN_NEW_ARRAY(conceal_buf[i]); conceal_buflen[i] = 0; } conceal_num = 0; conceal_pos = 0; // Initialize jitter buffer jitter_buf = new unsigned char[JITTER_BUF_SIZE(sc_sample_rate)]; MEMMAN_NEW_ARRAY(jitter_buf); jitter_buf_len = 0; load_jitter_buf = true; soundcard_buf_size = playback_device->get_buffer_size(false); // Initialize 3-way settings is_3way = false; is_3way_mixer = false; media_3way_peer_tx = NULL; peer_tx_3way = NULL; peer_rx_3way = NULL; mix_buf_3way = NULL; // Initialize telephone event settings pt_telephone_event = -1; pt_telephone_event_alt = 1; } t_audio_tx::~t_audio_tx() { struct timespec sleeptimer; if (is_running) { stop_running = true; do { sleeptimer.tv_sec = 0; sleeptimer.tv_nsec = 10000000; nanosleep(&sleeptimer, NULL); continue; } while (is_running); } MEMMAN_DELETE_ARRAY(sample_buf); delete [] sample_buf; MEMMAN_DELETE_ARRAY(jitter_buf); delete [] jitter_buf; for (int i = 0; i < MAX_CONCEALMENT; i++) { MEMMAN_DELETE_ARRAY(conceal_buf[i]); delete [] conceal_buf[i]; } // Destroy audio decoders for (map::iterator i = map_audio_decoder.begin(); i != map_audio_decoder.end(); i++) { MEMMAN_DELETE(i->second); delete i->second; } // Cleanup 3-way resources if (media_3way_peer_tx) { MEMMAN_DELETE(media_3way_peer_tx); delete media_3way_peer_tx; } if (mix_buf_3way) { MEMMAN_DELETE_ARRAY(mix_buf_3way); delete [] mix_buf_3way; } } void t_audio_tx::retain_for_concealment(unsigned char *buf, unsigned short len) { if (conceal_num == 0) { memcpy(conceal_buf[0], buf, len); conceal_buflen[0] = len; conceal_num = 1; conceal_pos = 0; return; } if (conceal_num < MAX_CONCEALMENT) { memcpy(conceal_buf[conceal_num], buf, len); conceal_buflen[conceal_num] = len; conceal_num++; return; } memcpy(conceal_buf[conceal_pos], buf, len); conceal_buflen[conceal_pos] = len; conceal_pos = (conceal_pos + 1) % MAX_CONCEALMENT; } void t_audio_tx::conceal(short num) { // Some codecs have a PLC. // Only use this PLC is the sound card sample rate equals the codec // sample rate. If they differ, then we should resample the codec // samples. As this should be a rare case, we are lazy here. In // this rare case, use Twinkle's low-tech PLC. if (map_audio_decoder[codec]->has_plc() && audio_sample_rate(codec) == sc_sample_rate) { short *sb = (short *)sample_buf; for (int i = 0; i < num; i++) { int nsamples; nsamples = map_audio_decoder[codec]->conceal(sb, SAMPLE_BUF_SIZE); if (nsamples > 0) { play_pcm(sample_buf, nsamples * 2); } } return; } // Replay previous packets for other codecs short i = (conceal_pos + (MAX_CONCEALMENT - num)) % MAX_CONCEALMENT; if (i >= conceal_pos) { for (int j = i; j < MAX_CONCEALMENT; j++) { play_pcm(conceal_buf[j], conceal_buflen[j]); } for (int j = 0; j < conceal_pos; j++) { play_pcm(conceal_buf[j], conceal_buflen[j]); } } else { for (int j = i; j < conceal_pos; j++) { play_pcm(conceal_buf[j], conceal_buflen[j]); } } } void t_audio_tx::clear_conceal_buf(void) { conceal_pos = 0; conceal_num = 0; } void t_audio_tx::play_pcm(unsigned char *buf, unsigned short len, bool only_3rd_party) { int status; //struct timeval debug_timer, debug_timer_prev; unsigned char *playbuf = buf; // If there is only sound from the 3rd party in a 3-way, then check // if there is still enough sound in the buffer of the DSP to be // played. If not, then play out the sound from the 3rd party only. if (only_3rd_party) { /* Does not work on all ALSA implementations. if (playback_device->get_buffer_space(false) < soundcard_buf_size - len) { */ if (!playback_device->play_buffer_underrun()) { // There is still sound in the DSP buffers to be // played, so let's wait. Maybe in the next cycle // an RTP packet from the far-end will be received. return; } } // If we are in a 3-way then send the samples to the peer audio // receiver for mixing if (!only_3rd_party && is_3way && peer_rx_3way) { peer_rx_3way->post_media_peer_tx_3way(buf, len, sc_sample_rate); } // If we are in a 3-way conference and we are not the mixer then // send the sound samples to the mixer if (is_3way && !is_3way_mixer) { if (peer_tx_3way) { peer_tx_3way->post_media_peer_tx_3way(buf, len, sc_sample_rate); return; } else { // There is no peer. return; } } // Mix audio for 3-way conference if (is_3way && is_3way_mixer) { if (media_3way_peer_tx->get(mix_buf_3way, len)) { short *mix_sb = (short *)mix_buf_3way; short *sb = (short *)buf; for (int i = 0; i < len / 2; i++) { mix_sb[i] = mix_linear_pcm(sb[i], mix_sb[i]); } playbuf = mix_buf_3way; } } // Fill jitter buffer before playing if (load_jitter_buf) { if (jitter_buf_len + len < JITTER_BUF_SIZE(sc_sample_rate)) { memcpy(jitter_buf + jitter_buf_len, playbuf, len); jitter_buf_len += len; } else { // Write the contents of the jitter buffer to the DSP. // The buffers in the DSP will now function as jitter // buffer. status = playback_device->write(jitter_buf, jitter_buf_len); if (status != jitter_buf_len) { string msg("Writing to dsp failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_audio_tx::play_pcm", LOG_NORMAL, LOG_CRITICAL); } // Write passed sound samples to DSP. status = playback_device->write(playbuf, len); if (status != len) { string msg("Writing to dsp failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_audio_tx::play_pcm", LOG_NORMAL, LOG_CRITICAL); } load_jitter_buf = false; } return; } // If buffer on soundcard is empty, then the jitter buffer needs // to be refilled. This should only occur when no RTP packets // have been received for a while (silence suppression or packet loss) /* * This code does not work on all ALSA implementations, e.g. ALSA via pulse audio int bufferspace = playback_device->get_buffer_space(false); if (bufferspace == soundcard_buf_size && len <= JITTER_BUF_SIZE(sc_sample_rate)) { */ if (playback_device->play_buffer_underrun()) { memcpy(jitter_buf, playbuf, len); jitter_buf_len = len; load_jitter_buf = true; log_file->write_header("t_audio_tx::play_pcm", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": jitter buffer empty.\n"); log_file->write_footer(); return; } // If the play-out buffer contains the maximum number of // packets then start skipping packets to prevent // unacceptable delay. // This can only happen if the thread did not get // processing time for a while and RTP packets start to // pile up. // Or if a soundcard plays out the samples at just less then // the requested sample rate. /* Not needed anymore, the ::run loop already discards incoming RTP packets with a late timestamp. This seems to solve the slow soundcard problem better. The solution below caused annoying ticks in the playout. if (soundcard_buf_size - bufferspace > JITTER_BUF_SIZE + len) { log_file->write_header("t_audio_tx::play_pcm", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": jitter buffer overflow: "); log_file->write_raw(bufferspace); log_file->write_raw(" bytes.\n"); log_file->write_footer(); return; } */ // Write passed sound samples to DSP. status = playback_device->write(playbuf, len); if (status != len) { string msg("Writing to dsp failed: "); msg += get_error_str(errno); log_file->write_report(msg, "t_audio_tx::play_pcm", LOG_NORMAL, LOG_CRITICAL); return; } } void t_audio_tx::set_running(bool running) { is_running = running; } void t_audio_tx::run(void) { const AppDataUnit* adu; struct timespec sleeptimer; //struct timeval debug_timer, debug_timer_prev; int last_seqnum = -1; // seqnum of last received RTP packet // RTP packets with multiple SSRCs may be received. Each SSRC // represents an audio stream. Twinkle will only play 1 audio stream. // On a reception of a new SSRC, Twinkle will switch over to play the // new stream. This supports devices that change SSRC during a call. uint32 ssrc_current = 0; bool recvd_dtmf = false; // indicates if last RTP packets is a DTMF event // The running flag is set already in t_audio_session::run to prevent // a crash when the thread gets destroyed before it starts running. // is_running = true; uint32 rtp_timestamp = 0; // This thread may not take the lock on the transaction layer to // prevent dead locks phone->add_prohibited_thread(); ui->add_prohibited_thread(); while (true) { do { adu = NULL; if (stop_running) break; rtp_timestamp = rtp_session->getFirstTimestamp(); adu = rtp_session->getData( rtp_session->getFirstTimestamp()); if (adu == NULL || adu->getSize() <= 0) { // There is no packet available. This may have // several reasons: // - the thread scheduling granularity does // not match ptime // - packet lost // - packet delayed // Wait another cycle for a packet. The // jitter buffer will cope with this variation. if (adu) { delete adu; adu = NULL; } // If we are the mixer in a 3-way call and there // is enough media from the other far-end then // this must be sent to the dsp. if (is_3way && is_3way_mixer && media_3way_peer_tx->size_content() >= ptime * (audio_sample_rate(codec) / 1000) * 2) { // Fill the sample buffer with silence int len = ptime * (audio_sample_rate(codec) / 1000) * 2; memset(sample_buf, 0, len); play_pcm(sample_buf, len, true); } // Sleep ptime ms sleeptimer.tv_sec = 0; if (ptime >= 20) { sleeptimer.tv_nsec = ptime * 1000000 - 10000000; } else { // With a thread schedule of 10ms // granularity, this will schedule the // thread every 10ms. sleeptimer.tv_nsec = 5000000; } nanosleep(&sleeptimer, NULL); } } while (adu == NULL || (adu->getSize() <= 0)); if (stop_running) { if (adu) delete adu; break; } if (adu) { // adu is created by ccRTP, but we have to delete it, // so report it to MEMMAN MEMMAN_NEW(const_cast(adu)); } // Check for a codec change map::const_iterator it_codec; it_codec = payload2codec.find(adu->getType()); t_audio_codec recvd_codec = CODEC_NULL; if (it_codec != payload2codec.end()) { recvd_codec = it_codec->second; } // Switch over to new SSRC if (last_seqnum == -1 || ssrc_current != adu->getSource().getID()) { if (recvd_codec != CODEC_NULL) { ssrc_current = adu->getSource().getID(); // An SSRC defines a sequence number space. So a new // SSRC starts with a new random sequence number last_seqnum = -1; log_file->write_header("t_audio_tx::run", LOG_NORMAL); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": play SSRC "); log_file->write_raw(ssrc_current); log_file->write_endl(); log_file->write_footer(); } else { // SSRC received had an unsupported codec // Discard. // KLUDGE: for now this supports a scenario where a // far-end starts ZRTP negotiation by sending CN // packets with a separate SSRC while ZRTP is disabled // in Twinkle. Twinkle will then receive the CN packets // and discard them here as CN is an unsupported codec. log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": SSRC received ("); log_file->write_raw(adu->getSource().getID()); log_file->write_raw(") has unsupported codec "); log_file->write_raw(adu->getType()); log_file->write_endl(); log_file->write_footer(); MEMMAN_DELETE(const_cast(adu)); delete adu; continue; } } map::const_iterator it_decoder; it_decoder = map_audio_decoder.find(recvd_codec); if (it_decoder != map_audio_decoder.end()) { if (codec != recvd_codec) { codec = recvd_codec; get_line()->ci_set_recv_codec(codec); ui->cb_async_recv_codec_changed(get_line()->get_line_number(), codec); log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": codec change to "); log_file->write_raw(ui->format_codec(codec)); log_file->write_endl(); log_file->write_footer(); } } else { if (adu->getType() == pt_telephone_event || adu->getType() == pt_telephone_event_alt) { recvd_dtmf = true; } else { if (codec != CODEC_UNSUPPORTED) { codec = CODEC_UNSUPPORTED; get_line()->ci_set_recv_codec(codec); ui->cb_async_recv_codec_changed( get_line()->get_line_number(), codec); log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": payload type "); log_file->write_raw(adu->getType()); log_file->write_raw(" not supported\n"); log_file->write_footer(); } last_seqnum = adu->getSeqNum(); MEMMAN_DELETE(const_cast(adu)); delete adu; continue; } } // DTMF event if (recvd_dtmf) { // NOTE: the DTMF tone will be detected here // while there might still be data in the jitter // buffer. If the jitter buffer was already sent // to the DSP, then the DSP will continue to play // out the buffer sound samples. if (dtmf_previous_timestamp != rtp_timestamp) { // A new DTMF tone has been received. dtmf_previous_timestamp = rtp_timestamp; t_rtp_telephone_event *e = (t_rtp_telephone_event *)adu->getData(); ui->cb_async_dtmf_detected(get_line()->get_line_number(), e->get_event()); // Log DTMF event log_file->write_header("t_audio_tx::run"); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": detected DTMF event - "); log_file->write_raw(e->get_event()); log_file->write_endl(); log_file->write_footer(); } recvd_dtmf = false; last_seqnum = adu->getSeqNum(); MEMMAN_DELETE(const_cast(adu)); delete adu; continue; } // Discard invalide payload sizes if (!map_audio_decoder[codec]->valid_payload_size( adu->getSize(), SAMPLE_BUF_SIZE / 2)) { log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": RTP payload size ("); log_file->write_raw((unsigned long)(adu->getSize())); log_file->write_raw(" bytes) invalid for \n"); log_file->write_raw(ui->format_codec(codec)); log_file->write_footer(); last_seqnum = adu->getSeqNum(); MEMMAN_DELETE(const_cast(adu)); delete adu; continue; } unsigned short recvd_ptime; recvd_ptime = map_audio_decoder[codec]->get_ptime(adu->getSize()); // Log a change of ptime if (ptime != recvd_ptime) { log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": ptime changed from "); log_file->write_raw(ptime); log_file->write_raw(" ms to "); log_file->write_raw(recvd_ptime); log_file->write_raw(" ms\n"); log_file->write_footer(); ptime = recvd_ptime; } // Check for lost packets // This must be done before decoding the received samples as the // speex decoder has its own PLC algorithm for which it needs the decoding // state before decoding the new samples. seq16_t seq_recvd(adu->getSeqNum()); seq16_t seq_last(static_cast(last_seqnum)); if (last_seqnum != -1 && seq_recvd - seq_last > 1) { // Packets have been lost uint16 num_lost = (seq_recvd - seq_last) - 1; log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": "); log_file->write_raw(num_lost); log_file->write_raw(" RTP packets lost.\n"); log_file->write_footer(); if (num_lost <= conceal_num) { // Conceal packet loss conceal(num_lost); } clear_conceal_buf(); } // Determine if resampling is needed due to dynamic change to // codec with other sample rate. short downsample_factor = 1; short upsample_factor = 1; if (audio_sample_rate(codec) > sc_sample_rate) { downsample_factor = audio_sample_rate(codec) / sc_sample_rate; } else if (audio_sample_rate(codec) < sc_sample_rate) { upsample_factor = sc_sample_rate / audio_sample_rate(codec); } // Create sample buffer. If no resampling is needed, the sample // buffer from the audio_tx object can be used directly. // Otherwise a temporary sample buffers is created that will // be resampled to the object's sample buffer later. short *sb; int sb_size; if (downsample_factor > 1) { sb_size = SAMPLE_BUF_SIZE / 2 * downsample_factor; sb = new short[sb_size]; MEMMAN_NEW_ARRAY(sb); } else if (upsample_factor > 1) { sb_size = SAMPLE_BUF_SIZE / 2; sb = new short[SAMPLE_BUF_SIZE / 2]; MEMMAN_NEW_ARRAY(sb); } else { sb_size = SAMPLE_BUF_SIZE / 2; sb = (short *)sample_buf; } // Decode the audio unsigned char *payload = const_cast(adu->getData()); short sample_size; // size in bytes sample_size = 2 * map_audio_decoder[codec]->decode(payload, adu->getSize(), sb, sb_size); // Resample if needed if (downsample_factor > 1) { short *p = sb; sb = (short *)sample_buf; for (int i = 0; i < sample_size / 2; i += downsample_factor) { sb[i / downsample_factor] = p[i]; } MEMMAN_DELETE_ARRAY(p); delete [] p; sample_size /= downsample_factor; } else if (upsample_factor > 1) { short *p = sb; sb = (short *)sample_buf; for (int i = 0; i < sample_size / 2; i++) { for (int j = 0; j < upsample_factor; j++) { sb[i * upsample_factor + j] = p[i]; } } MEMMAN_DELETE_ARRAY(p); delete [] p; sample_size *= upsample_factor; } // If the decoder deliverd 0 bytes, then it failed if (sample_size == 0) { last_seqnum = adu->getSeqNum(); MEMMAN_DELETE(const_cast(adu)); delete adu; continue; } // Discard packet if we are lacking behind. This happens if the // soundcard plays at a rate less than the requested sample rate. if (rtp_session->isWaiting(&(adu->getSource()))) { uint32 last_ts = rtp_session->getLastTimestamp(&(adu->getSource())); uint32 diff; diff = last_ts - rtp_timestamp; if (diff > (uint32_t)(JITTER_BUF_SIZE(sc_sample_rate) / AUDIO_SAMPLE_SIZE) * 8) { log_file->write_header("t_audio_tx::run", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": discard delayed packet.\n"); log_file->write_raw("Timestamp: "); log_file->write_raw(rtp_timestamp); log_file->write_raw(", Last timestamp: "); log_file->write_raw((long unsigned int)last_ts); log_file->write_endl(); log_file->write_footer(); last_seqnum = adu->getSeqNum(); MEMMAN_DELETE(const_cast(adu)); delete adu; continue; } } play_pcm(sample_buf, sample_size); retain_for_concealment(sample_buf, sample_size); last_seqnum = adu->getSeqNum(); MEMMAN_DELETE(const_cast(adu)); delete adu; // No sleep is done here but in the loop waiting // for a new packet. If a packet is already available // it can be send to the sound card immediately so // the play-out buffer keeps filled. // If the play-out buffer gets empty you hear a // crack in the sound. #ifdef HAVE_SPEEX // store decoded output for (optional) echo cancellation if (audio_session->get_do_echo_cancellation()) { if (audio_session->get_echo_captured_last()) { speex_echo_playback(audio_session->get_speex_echo_state(), (spx_int16_t *) sb); audio_session->set_echo_captured_last(false);; } } #endif } phone->remove_prohibited_thread(); ui->remove_prohibited_thread(); is_running = false; } void t_audio_tx::set_pt_telephone_event(int pt, int pt_alt) { pt_telephone_event = pt; pt_telephone_event_alt = pt_alt; } t_line *t_audio_tx::get_line(void) const { return audio_session->get_line(); } void t_audio_tx::join_3way(bool mixer, t_audio_tx *peer_tx, t_audio_rx *peer_rx) { mtx_3way.lock(); if (is_3way) { log_file->write_header("t_audio_tx::join_3way"); log_file->write_raw("ERROR: audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(" - 3way is already active.\n"); log_file->write_footer(); mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_tx::join_3way"); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": join 3-way.\n"); if (mixer) { log_file->write_raw("Role is: mixer.\n"); } else { log_file->write_raw("Role is: non-mixing.\n"); } if (peer_tx) { log_file->write_raw("A peer transmitter already exists.\n"); } else { log_file->write_raw("A peer transmitter does not exist.\n"); } if (peer_rx) { log_file->write_raw("A peer receiver already exists.\n"); } else { log_file->write_raw("A peer receiver does not exist.\n"); } log_file->write_footer(); peer_tx_3way = peer_tx; peer_rx_3way = peer_rx; is_3way_mixer = mixer; is_3way = true; // Create buffers for mixing mix_buf_3way = new unsigned char[SAMPLE_BUF_SIZE]; MEMMAN_NEW_ARRAY(mix_buf_3way); // See comments in audio_rx.cpp for the size of this buffer. media_3way_peer_tx = new t_media_buffer(JITTER_BUF_SIZE(sc_sample_rate)); MEMMAN_NEW(media_3way_peer_tx); mtx_3way.unlock(); } void t_audio_tx::set_peer_tx_3way(t_audio_tx *peer_tx) { mtx_3way.lock(); if (!is_3way) { mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_tx::set_peer_tx_3way"); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); if (peer_tx) { log_file->write_raw(": set peer transmitter.\n"); } else { log_file->write_raw(": erase peer transmitter.\n"); } if (is_3way_mixer) { log_file->write_raw("Role is: mixer.\n"); } else { log_file->write_raw("Role is: non-mixing.\n"); } log_file->write_footer(); peer_tx_3way = peer_tx; mtx_3way.unlock(); } void t_audio_tx::set_peer_rx_3way(t_audio_rx *peer_rx) { mtx_3way.lock(); if (!is_3way) { mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_tx::set_peer_rx_3way"); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); if (peer_rx) { log_file->write_raw(": set peer receiver.\n"); } else { log_file->write_raw(": erase peer receiver.\n"); } if (is_3way_mixer) { log_file->write_raw("Role is: mixer.\n"); } else { log_file->write_raw("Role is: non-mixing.\n"); } log_file->write_footer(); peer_rx_3way = peer_rx; mtx_3way.unlock(); } void t_audio_tx::set_mixer_3way(bool mixer) { mtx_3way.lock(); if (!is_3way) { mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_tx::set_mixer_3way"); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); if (mixer) { log_file->write_raw(": change role to: mixer.\n"); } else { log_file->write_raw(": change role to: non-mixing.\n"); } log_file->write_footer(); is_3way_mixer = mixer; mtx_3way.unlock(); } void t_audio_tx::stop_3way(void) { mtx_3way.lock(); if (!is_3way) { log_file->write_header("t_audio_tx::stop_3way"); log_file->write_raw("ERROR: audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(" - 3way is not active.\n"); log_file->write_footer(); mtx_3way.unlock(); return; } // Logging log_file->write_header("t_audio_tx::stop_3way"); log_file->write_raw("Audio tx line "); log_file->write_raw(get_line()->get_line_number()+1); log_file->write_raw(": stop 3-way.\n"); log_file->write_footer(); is_3way = false; is_3way_mixer = false; if (media_3way_peer_tx) { MEMMAN_DELETE(media_3way_peer_tx); delete media_3way_peer_tx; media_3way_peer_tx = NULL; } if (mix_buf_3way) { MEMMAN_DELETE_ARRAY(mix_buf_3way); delete [] mix_buf_3way; mix_buf_3way = NULL; } mtx_3way.unlock(); } void t_audio_tx::post_media_peer_tx_3way(unsigned char *media, int len, unsigned short peer_sample_rate) { mtx_3way.lock(); if (!is_3way || !is_3way_mixer) { mtx_3way.unlock(); return; } if (peer_sample_rate != sc_sample_rate) { // Resample media from peer to sample rate of this transmitter int output_len = (len / 2) * sc_sample_rate / peer_sample_rate; short *output_buf = new short[output_len]; MEMMAN_NEW_ARRAY(output_buf); int resample_len = resample((short *)media, len / 2, peer_sample_rate, output_buf, output_len, sc_sample_rate); media_3way_peer_tx->add((unsigned char *)output_buf, resample_len * 2); MEMMAN_DELETE_ARRAY(output_buf); delete [] output_buf; } else { media_3way_peer_tx->add(media, len); } mtx_3way.unlock(); } bool t_audio_tx::get_is_3way_mixer(void) const { return is_3way_mixer; } twinkle-1.4.2/src/audio/rtp_telephone_event.cpp0000644000175000001440000000443311127714055016564 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "cassert" #include "rtp_telephone_event.h" #include void t_rtp_telephone_event::set_event(unsigned char _event) { event = _event; } void t_rtp_telephone_event::set_volume(unsigned char _volume) { volume = _volume; } void t_rtp_telephone_event::set_reserved(bool _reserved) { reserved = _reserved; } void t_rtp_telephone_event::set_end(bool _end) { end = _end; } void t_rtp_telephone_event::set_duration(unsigned short _duration) { duration = htons(_duration); } unsigned char t_rtp_telephone_event::get_event(void) const { return event; } unsigned char t_rtp_telephone_event::get_volume(void) const { return volume; } bool t_rtp_telephone_event::get_reserved(void) const { return reserved; } bool t_rtp_telephone_event::get_end(void) const { return end; } unsigned short t_rtp_telephone_event::get_duration(void) const { return ntohs(duration); } unsigned char char2dtmf_ev(char sym) { if (sym >= '0' && sym <= '9') return (sym - '0' + TEL_EV_DTMF_0); if (sym >= 'A' && sym <= 'D') return (sym - 'A' + TEL_EV_DTMF_A); if (sym >= 'a' && sym <= 'd') return (sym- 'a' + TEL_EV_DTMF_A); if (sym == '*') return TEL_EV_DTMF_STAR; if (sym == '#') return TEL_EV_DTMF_POUND; assert(false); } char dtmf_ev2char(unsigned char ev) { if (ev <= TEL_EV_DTMF_9) { return ev + '0' - TEL_EV_DTMF_0; } if (ev >= TEL_EV_DTMF_A && ev <= TEL_EV_DTMF_D) { return ev + 'A' - TEL_EV_DTMF_A; } if (ev == TEL_EV_DTMF_STAR) return '*'; if (ev == TEL_EV_DTMF_POUND) return '#'; assert(false); } twinkle-1.4.2/src/redirect.h0000644000175000001440000000376011127714046012662 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_REDIRECT #define _H_REDIRECT #include #include "user.h" #include "parser/hdr_contact.h" #include "sockets/url.h" using namespace std; class t_redirector { private: // Total number of contacts in try and done lists int num_contacts; // Contacts to try list try_contacts; // Contacts already tried, but unsuccesful list done_contacts; // Original destination t_url org_dest; // Maximum number of redirections that will be tried int max_redirections; bool contact_already_added(const t_contact_param contact) const; // Constructor without parameter should not be used. t_redirector(); public: t_redirector(const t_url &_org_dest, int _max_redirections); // Get the next contact to try // Returns false if there is no next contact bool get_next_contact(t_contact_param &contact); // Add contacts. The passed contacts will be sorted on decreasing // q-value before adding. // Contacts that are already in the try list or are tried already // will not be added. // If the maximum number of redirections is reached then all contacts // exceeding the maximum will be discarded. void add_contacts(const list &contacts); }; #endif twinkle-1.4.2/src/epa.h0000644000175000001440000001316611127714046011627 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Event Publication Agent (EPA) [RFC 3903] */ #ifndef _EPA_H #define _EPA_H #include #include #include "id_object.h" #include "phone_user.h" #include "sockets/url.h" #include "parser/sip_body.h" #include "protocol.h" using namespace std; /** Event Publication Agent (EPA) [RFC 3903] */ class t_epa { public: /** State of the EPA */ enum t_epa_state { EPA_UNPUBLISHED, /**< The event has not been published. */ EPA_PUBLISHED, /**< The event has been published. */ EPA_FAILED, /**< Failed to publish the event. */ }; private: /** * Queue of pending outgoing PUBLISH requests. A next PUBLISH * will only be sent after the previous PUBLISH has been * answered. */ queue queue_publish; /** * Enqueue a request. * @param r [in] Request to enqueue. */ void enqueue_request(t_request *r); protected: /** Phone user for whom publications are issued. */ t_phone_user *phone_user; /** EPA state. */ t_epa_state epa_state; /** Detailed failure message when @ref epa_state == @ref EPA_FAILED */ string failure_msg; /** * Entity tag associated with the publication. * For an initial publication there is no entity tag yet. */ string etag; /** Event for which the event state is published. */ string event_type; /** Request-URI for the publish request. */ t_url request_uri; /** Timer indicating when a publication must be refreshed. */ t_object_id id_publication_timeout; /** Expiry duration (sec) of a publication. */ unsigned long publication_expiry; /** Default duration for a publication/ */ unsigned long default_duration; /** Indicates if an unpublish is in progress. */ bool is_unpublishing; /** Cached body of last publication. */ t_sip_body *cached_body; /** Log the publication details */ void log_publication(void) const; /** * Remove a pending request. Pass one of the client request pointers. * @param cr [in] Client request to remove. */ void remove_client_request(t_client_request **cr); /** * Create a PUBLISH request. * @param expires [in] Expiry time in seconds. * @param body [in] Body for the request. The body will be destroyed when * the request will be destroyed. */ virtual t_request *create_publish(unsigned long expires, t_sip_body *body) const; /** * Send request. * @param r [in] Request to send. * @param tuid [in] Transaction user id. */ void send_request(t_request *r, t_tuid tuid) const; /** * Send the next PUBLISH request from the queue. * If the queue is empty, then this method does nothing. */ void send_publish_from_queue(void); /** * Start a publication timer. * @param timer [in] Type of publication timer. * @param duration [in] Duration of timer in ms */ void start_timer(t_publish_timer timer, long duration); /** * Stop a publication timer. * @param timer [in] Type of publication timer. */ void stop_timer(t_publish_timer timer); public: /** Pending request */ t_client_request *req_out; /** Constructor. */ t_epa(t_phone_user *pu, const string &_event_type, const t_url _request_uri); /** Destructor. */ virtual ~t_epa(); /** @name Getters */ //@{ t_epa_state get_epa_state(void) const; string get_failure_msg(void) const; t_phone_user *get_phone_user(void) const; //@} /** * Get the user profile of the user. * @return The user profile. */ t_user *get_user_profile(void) const; /** * Receive PUBLISH response. * @param r [in] Received response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return The return value indicates if processing is finished. */ virtual bool recv_response(t_response *r, t_tuid tuid, t_tid tid); /** * Match response with a pending publish. * @param r [in] The response. * @param tuid [in] Transaction user id. * @return True if the response matches, otherwise false. */ virtual bool match_response(t_response *r, t_tuid tuid) const; /** * Process timeouts * @param timer [in] Type of publication timer. * @return The return value indicates if processing is finished. */ virtual bool timeout(t_publish_timer timer); /** * Match timer id with a running timer. * @param timer [in] Type of publication timer. * @return True, if id matches, otherwise false. */ virtual bool match_timer(t_publish_timer timer, t_object_id id_timer) const; /** * Publish event state. * @param expired [in] Duration of publication in seconds. * @param body [in] Body for PUBLISH request. * @note The body will be deleted when the PUBLISH has been sent. * The caller of this method should *not* delete the body. */ virtual void publish(unsigned long expires, t_sip_body *body); /** Terminate publication. */ virtual void unpublish(void); /** Refresh publication. */ virtual void refresh_publication(void); /** Clear all state */ virtual void clear(void); }; #endif twinkle-1.4.2/src/timekeeper.h0000644000175000001440000001736711127714046013223 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TIMEKEEPER_H #define _TIMEKEEPER_H #include #include "id_object.h" #include "protocol.h" #include "transaction.h" #include "threads/mutex.h" #include "threads/sema.h" using namespace std; // Forward declarations class t_phone; class t_line; class t_subscription; /** Timer type */ enum t_timer_type { TMR_TRANSACTION, /**< Transaction timer */ TMR_PHONE, /**< Timer associated with the phone */ TMR_LINE, /**< Timer associated with a line */ TMR_SUBSCRIBE, /**< Subscription timer */ TMR_PUBLISH, /**< Publication timer */ TMR_STUN_TRANSACTION /**< STUN timer */ }; //////////////////////////////////////////////////////////////// // General timer. //////////////////////////////////////////////////////////////// // Instances should be created from subclasses. class t_timer : public t_id_object { private: long duration; // milliseconds long relative_duration; // milliseconds public: t_timer(long dur); virtual ~t_timer() {} // This method is invoked on expiry // Subclasses should implent the action to be taken. virtual void expired(void) = 0; long get_duration(void) const; long get_relative_duration(void) const; void set_relative_duration(long d); virtual t_timer *copy(void) const = 0; virtual t_timer_type get_type(void) const = 0; // Get the name of the timer (for debugging purposes) virtual string get_name(void) const = 0; }; //////////////////////////////////////////////////////////////// // Transaction timer //////////////////////////////////////////////////////////////// class t_tmr_transaction : public t_timer { private: unsigned short transaction_id; t_sip_timer sip_timer; public: t_tmr_transaction(long dur, t_sip_timer tmr, unsigned short tid); void expired(void); t_timer *copy(void) const; t_timer_type get_type(void) const; unsigned short get_tid(void) const; t_sip_timer get_sip_timer(void) const; string get_name(void) const; }; //////////////////////////////////////////////////////////////// // Phone timer //////////////////////////////////////////////////////////////// class t_tmr_phone : public t_timer { private: t_phone *the_phone; t_phone_timer phone_timer; public: t_tmr_phone(long dur, t_phone_timer ptmr, t_phone *p); void expired(void); t_timer *copy(void) const; t_timer_type get_type(void) const; t_phone_timer get_phone_timer(void) const; t_phone *get_phone(void) const; string get_name(void) const; }; //////////////////////////////////////////////////////////////// // Line timer //////////////////////////////////////////////////////////////// class t_tmr_line : public t_timer { private: t_object_id line_id; t_line_timer line_timer; t_object_id dialog_id; public: t_tmr_line(long dur, t_line_timer ltmr, t_object_id lid, t_object_id d); void expired(void); t_timer *copy(void) const; t_timer_type get_type(void) const; t_line_timer get_line_timer(void) const; t_object_id get_line_id(void) const; t_object_id get_dialog_id(void) const; string get_name(void) const; }; //////////////////////////////////////////////////////////////// // Subscribe timer //////////////////////////////////////////////////////////////// class t_tmr_subscribe : public t_timer { private: t_subscribe_timer subscribe_timer; t_object_id line_id; t_object_id dialog_id; string sub_event_type; string sub_event_id; public: t_tmr_subscribe(long dur, t_subscribe_timer stmr, t_object_id lid, t_object_id d, const string &event_type, const string &event_id); void expired(void); t_timer *copy(void) const; t_timer_type get_type(void) const; t_subscribe_timer get_subscribe_timer(void) const; t_object_id get_line_id(void) const; t_object_id get_dialog_id(void) const; string get_sub_event_type(void) const; string get_sub_event_id(void) const; string get_name(void) const; }; /** Publication timer */ class t_tmr_publish : public t_timer { private: t_publish_timer publish_timer; /**< Type of timer */ string event_type; /**< Event type of publication */ public: t_tmr_publish(long dur, t_publish_timer ptmr, const string &_event_type); void expired(void); t_timer *copy(void) const; t_timer_type get_type(void) const; t_publish_timer get_publish_timer(void) const; string get_name(void) const; }; //////////////////////////////////////////////////////////////// // STUN transaction timer //////////////////////////////////////////////////////////////// class t_tmr_stun_trans : public t_timer { private: unsigned short transaction_id; t_stun_timer stun_timer; public: t_tmr_stun_trans(long dur, t_stun_timer tmr, unsigned short tid); void expired(void); t_timer *copy(void) const; t_timer_type get_type(void) const; unsigned short get_tid(void) const; t_stun_timer get_stun_timer(void) const; string get_name(void) const; }; //////////////////////////////////////////////////////////////// // Timekeeper //////////////////////////////////////////////////////////////// // A timekeeper keeps track of multiple timers per thread. // Only one single thread should call the methods of a single // timekeeper. Multiple threads using the same timekeeper will // cause havoc. class t_timekeeper { private: // List of running timers in order of timeout. As there // is only 1 real timer running on the OS. Each timer gets // a duration relative to its predecessor in the list. list timer_list; // Mutex to synchronize timekeeper actions. t_mutex mutex; // Indicate if current timer was stopped, but not removed // to prevent race conditions. Expiry of a stopped timer // will not trigger any actions. bool stopped; // Indicate if the current timer expired while the // mutex was locked. bool timer_expired; // Every method should start with locking the timekeeper // and end with unlocking. The unlocking method will check // if a timer expired during the locked state. If so, then // the expiry will be processed. void lock(void); void unlock(void); // Start the timekeeper from the thread that will handle // the SIGALRM signal. Start must be called before the // timekeeper can be used. void start(void (*timeout_handler)(int)); // Start a timer. The timer id is returned. This id is // needed to stop a timer. Pointer t should not be used // or deleted after starting. When the timer expires or // is stopped it will be deleted. void start_timer(t_timer *t); void stop_timer(t_object_id id); public: // The timeout_handler must be a signal handler for SIGALRM t_timekeeper(); ~t_timekeeper(); // Report that the current timer has expired. void report_expiry(void); // Get remaining time of a running timer. // Returns 0 if the timer is not running anymore. unsigned long get_remaining_time(t_object_id timer_id); // Main loop to be run in a separate thread void run(void); }; // Entry function for timekeeper thread void *timekeeper_main(void *arg); // Entry function of the thread waiting for SIGALRM // A dedicated thread is started to catch the SIGALRM signal and take // the appropriate action. All threads must block the SIGALRM signal. void *timekeeper_sigwait(void *arg); #endif twinkle-1.4.2/src/log.h0000644000175000001440000000636211127714046011643 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _LOG_H #define _LOG_H #include #include #include "threads/mutex.h" #include "threads/sema.h" #include "threads/thread.h" using namespace std; #define LOG_FILENAME "twinkle.log" // Severity of a log message enum t_log_severity { LOG_INFO, LOG_WARNING, LOG_CRITICAL, LOG_DEBUG }; // Message class enum t_log_class { LOG_NORMAL, LOG_SIP, LOG_STUN, LOG_MEMORY }; class t_log { private: /** Maximum length of a logged string (bytes) */ static const string::size_type MAX_LEN_LOG_STRING = 1024; string log_filename; ofstream *log_stream; // Mutex for exclusive acces to the log file t_mutex mtx_log; // Indicates if logging is disabled bool log_disabled; bool log_report_disabled; // Indicates if the user should be informed about log updates bool inform_user; // Indicates if new data for the log viewer is available t_semaphore *sema_logview; // Thread for updating the log viewer t_thread *thr_logview; // Move the current log file to the .old log file bool move_current_to_old(void); public: t_log(); ~t_log(); // Write a report with header and footer void write_report(const string &report, const string &func_name); // normal, info void write_report(const string &report, const string &func_name, t_log_class log_class, t_log_severity severity = LOG_INFO); // Write header // This locks the mtx_log. So you must call write footer to release // the log again! void write_header(const string &func_name); // class normal, severity info void write_header(const string &func_name, t_log_class log_class, t_log_severity severity = LOG_INFO); // Write footer // This unlocks the mtx_log. void write_footer(void); // Write raw data void write_raw(const string &raw); void write_raw(int raw); void write_raw(unsigned int raw); void write_raw(unsigned short raw); void write_raw(unsigned long raw); void write_raw(long raw); void write_bool(bool raw); // Write end of line void write_endl(void); // Return the full path name of the log file string get_filename(void) const; // Enable/disable user informs on updates void enable_inform_user(bool on); // Block till log information is available for log viewer void wait_for_log(void); }; extern t_log *log_file; #endif twinkle-1.4.2/src/utils/0000777000175000001440000000000011151327752012127 500000000000000twinkle-1.4.2/src/utils/file_utils.h0000644000175000001440000000460111127714046014353 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * File utilities */ #ifndef _FILE_UTILS_H #define _FILE_UTILS_H #include using namespace std; namespace utils { /** Separator to split parts in a file path. */ #define PATH_SEPARATOR '/' /** * Copy a file. * @param from [in] Absolute path of file to copy. * @param to [in] Absolute path of destination file. * @return true if copy succeeded, otherwise false. */ bool filecopy(const string &from, const string &to); /** * Strip the path to a file from an absolute file name. * @return The remaining file name without the full path. */ string strip_path_from_filename(const string &filename); /** * Get path to a file from an absolute file name. * @return The path name. */ string get_path_from_filename(const string &filename); /** * Get the extension from a file name. * @return The extension (without the initial dot). * @return Empty string if the file name does not have an extension. */ string get_extension_from_filename(const string &filename); /** * Apply a glob expression to a filename. * E.g. /tmp/twinkle with glob *.txt gives /tmp/twinkle.txt * /tmp/twinkle with README* give /tmp/READMEtwinkle.txt * @param filename [in] The filename. * @param glob [in] The glob expression to apply. * @return The modified filename. */ string apply_glob_to_filename(const string &filename, const string &glob); /** * Get the absolute path of the current working directory. * @return The absolute path of the current working directory. * @return Empty string if the current working directory cannot be determined. */ string get_working_dir(void); }; // namespace #endif twinkle-1.4.2/src/utils/record_file.h0000644000175000001440000000762211127714046014477 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * File to store data records. */ #ifndef _RECORD_FILE_H #define _RECORD_FILE_H #include #include #include #include #include #include #include #include "translator.h" #include "util.h" #include "threads/mutex.h" using namespace std; namespace utils { /** A single record in a file. */ class t_record { public: virtual ~t_record() {}; /** * Create a record to write to a file. * @param v [out] Vector of fields of record. * @return true, if record is succesfully created. * @return false, otherwise. */ virtual bool create_file_record(vector &v) const = 0; /** * Populate from a file record. * @param v [in] Vector containing the fields of the record. * @return true, if record is succesfully populated. * @return false, if file record could not be parsed. */ virtual bool populate_from_file_record(const vector &v) = 0; }; /** * A file containing records with a fixed number of fields. * @param R Subclass of @ref t_record */ template< class R > class t_record_file { private: /** Separator to separate fields in a file record. */ char field_separator; /** Header string to write as comment at start of file. */ string header; /** Name of the file containing the records. */ string filename; /** * Split a record into separate fields. * @param record [in] A complete record. * @param v [out] Vector of fields. */ void split_record(const string &record, vector &v) const; /** * Join fields of a record into a string. * Separator and comment symbols will be escaped. * @param v [in] Vector of fields. * @return Joined fields. */ string join_fields(const vector &v) const; protected: /** Mutex to protect concurrent access/ */ mutable t_recursive_mutex mtx_records; /** Records in the file. */ list records; /** * Add a record to the file. * @param record [in] Record to add. */ virtual void add_record(const R &record); public: /** Constructor. */ t_record_file(); /** Constructor. */ t_record_file(const string &_header, char _field_separator, const string &_filename); /** Destructor. */ virtual ~t_record_file() {}; /** @name Setters */ //@{ void set_header(const string &_header); void set_separator(char _separator); void set_filename(const string &_filename); //@} /** @name Getters */ //@{ list *get_records(); //@} /** * Load records from file. * @param error_msg [out] Error message on failure return. * @return true, if file was read succesfully. * @return false, if it fails. error_msg is an error to be given to * the user. */ virtual bool load(string &error_msg); /** * Save records to file. * @param error_msg [out] Error message on failure return. * @return true, if file was saved succesfully. * @return false, if it fails. error_msg is an error to be given to * the user. */ virtual bool save(string &error_msg) const; typedef typename list::const_iterator record_const_iterator; typedef typename list::iterator record_iterator; }; #include "record_file.hpp" }; // namespace #endif twinkle-1.4.2/src/utils/mime_database.h0000644000175000001440000000462211127714046014772 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Mime database * Conversion between mime types, file content and file extensions. */ #ifndef _MIME_DATABASE_H #define _MIME_DATABASE_H #include #include #include #include "record_file.h" using namespace std; namespace utils { /** Record from the mime database. */ class t_mime_db_record : public utils::t_record { public: string mimetype; /**< Mimetype, e.g. text/plain */ string file_glob; /**< File glob expression */ virtual bool create_file_record(vector &v) const; virtual bool populate_from_file_record(const vector &v); }; /** * The mime database. * The default location for the mime database is /usr/share/mime/globs */ class t_mime_database : public utils::t_record_file { private: /** Mapping between mimetypes and file globs. */ map map_mime2glob_; /** Handle on the magic number database. */ magic_t mime_magic_; protected: virtual void add_record(const t_mime_db_record &record); public: /** Constructor */ t_mime_database(); /** Destructor */ ~t_mime_database(); /** * Get a glob expression for a mimetype. * @param mimetype [in] The mimetype. * @return Glob expression associated with the mimetype. Empty string * if no glob expression can be found. */ string get_glob(const string &mimetype) const; /** * Get the mimetype of a file. * @param filename [in] Name of the file. * @return The mimetype or empty string if no mimetype can be determined. */ string get_mimetype(const string &filename) const; }; }; // namespace extern utils::t_mime_database *mime_database; #endif twinkle-1.4.2/src/utils/mime_database.cpp0000644000175000001440000000542011133434464015322 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mime_database.h" #include #include "log.h" #include "sys_settings.h" using namespace utils; ////////////////////////// // class t_mime_db_record ////////////////////////// bool t_mime_db_record::create_file_record(vector &v) const { // The mime database is read only. So this function should // never be called. assert(false); return false; } bool t_mime_db_record::populate_from_file_record(const vector &v) { // Check number of fields if (v.size() != 2) return false; mimetype = v[0]; file_glob = v[1]; return true; } ////////////////////////// // class t_mime_database ////////////////////////// t_mime_database::t_mime_database() { set_separator(':'); set_filename(sys_config->get_mime_shared_database()); mime_magic_ = magic_open(MAGIC_MIME | MAGIC_ERROR); if (mime_magic_ == (magic_t)NULL) { log_file->write_report("Failed to open magic number database", "t_mime_database::t_mime_database", LOG_NORMAL, LOG_WARNING); return; } magic_load(mime_magic_, NULL); } t_mime_database::~t_mime_database() { magic_close(mime_magic_); } void t_mime_database::add_record(const t_mime_db_record &record) { map_mime2glob_.insert(make_pair(record.mimetype, record.file_glob)); } string t_mime_database::get_glob(const string &mimetype) const { map::const_iterator it = map_mime2glob_.find(mimetype); if (it != map_mime2glob_.end()) { return it->second; } return ""; } string t_mime_database::get_mimetype(const string &filename) const { const char *mime_desc = magic_file(mime_magic_, filename.c_str()); if (!mime_desc) return ""; // Sometimes the magic libary adds additional info to the // returned mime type. Strip this info. string mime_type(mime_desc); string::size_type end_of_mime = mime_type.find_first_not_of( "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQSTUVWXYZ" "0123456789-.!%*_+`'~/"); if (end_of_mime != string::npos) { mime_type = mime_type.substr(0, end_of_mime); } return mime_type; } twinkle-1.4.2/src/utils/Makefile.am0000644000175000001440000000032411134651232014070 00000000000000AM_CPPFLAGS = -Wall $(XML2_CFLAGS) -I$(top_srcdir)/src noinst_LIBRARIES = libutils.a libutils_a_SOURCES =\ file_utils.cpp\ mime_database.cpp\ file_utils.h\ mime_database.h\ record_file.h\ record_file.hpp twinkle-1.4.2/src/utils/Makefile.in0000644000175000001440000003737511151323411014113 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/utils DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libutils_a_AR = $(AR) $(ARFLAGS) libutils_a_LIBADD = am_libutils_a_OBJECTS = file_utils.$(OBJEXT) mime_database.$(OBJEXT) libutils_a_OBJECTS = $(am_libutils_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libutils_a_SOURCES) DIST_SOURCES = $(libutils_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = -Wall $(XML2_CFLAGS) -I$(top_srcdir)/src noinst_LIBRARIES = libutils.a libutils_a_SOURCES = \ file_utils.cpp\ mime_database.cpp\ file_utils.h\ mime_database.h\ record_file.h\ record_file.hpp all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/utils/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/utils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libutils.a: $(libutils_a_OBJECTS) $(libutils_a_DEPENDENCIES) -rm -f libutils.a $(libutils_a_AR) libutils.a $(libutils_a_OBJECTS) $(libutils_a_LIBADD) $(RANLIB) libutils.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mime_database.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/utils/file_utils.cpp0000644000175000001440000000565211134636630014715 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "file_utils.h" #include "util.h" #include #include #include #include #include #include using namespace std; using namespace utils; bool utils::filecopy(const string &from, const string &to) { ifstream from_file(from.c_str()); if (!from_file) { return false; } ofstream to_file(to.c_str()); if (!to_file) { return false; } to_file << from_file.rdbuf(); if (!to_file.good() || !from_file.good()) { return false; } return true; } string utils::strip_path_from_filename(const string &filename) { vector v = split_on_last(filename, PATH_SEPARATOR); return v.back(); } string utils::get_path_from_filename(const string &filename) { vector v = split_on_last(filename, PATH_SEPARATOR); if (v.size() == 1) { // There is no path. return ""; } return v.front(); } string utils::get_extension_from_filename(const string &filename) { vector v = split_on_last(filename, '.'); if (v.size() == 1) { // There is no file extension. return ""; } else { return v.back(); } } string utils::apply_glob_to_filename(const string &filename, const string &glob) { string name = strip_path_from_filename(filename); string path = get_path_from_filename(filename); string new_name = glob; string::size_type idx = new_name.find('*'); if (idx == string::npos) { // The glob expression does not contain a wild card to replace. return filename; } new_name.replace(new_name.begin() + idx, new_name.begin() + idx + 1, name); string new_filename = path; if (!new_filename.empty()) { new_filename += PATH_SEPARATOR; } new_filename += new_name; return new_filename; } string get_working_dir(void) { size_t buf_size = 1024; char *buf = (char*)malloc(buf_size); char *dir = NULL; while (true) { if ((dir = getcwd(buf, buf_size)) != NULL) break; if (errno != ERANGE) break; // The buffer is too small. // Avoid eternal looping. if (buf_size > 8192) break; // Increase the buffer size free(buf); buf_size *= 2; buf = (char*)malloc(buf_size); } string result; if (dir) result = dir; free(buf); return result; } twinkle-1.4.2/src/utils/record_file.hpp0000644000175000001440000001035511134635174015036 00000000000000/* Copyright (C) 2005-2007 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define COMMENT_SYMBOL '#' template< class R > void t_record_file::split_record(const string &record, vector &v) const { v = split_escaped(record, field_separator); for (vector::iterator it = v.begin(); it != v.end(); ++it) { *it = unescape(*it); } } template< class R > string t_record_file::join_fields(const vector &v) const { string s; for (vector::const_iterator it = v.begin(); it != v.end(); ++it) { if (it != v.begin()) s += field_separator; // Escape comment symbol. if (!it->empty() && it->at(0) == COMMENT_SYMBOL) s += '\\'; s += escape(*it, field_separator); } return s; } template< class R > void t_record_file::add_record(const R &record) { records.push_back(record); } template< class R > t_record_file::t_record_file(): field_separator('|') {} template< class R > t_record_file::t_record_file(const string &_header, char _field_separator, const string &_filename) : header(_header), field_separator(_field_separator), filename(_filename) {} template< class R > void t_record_file::set_header(const string &_header) { header = _header; } template< class R > void t_record_file::set_separator(char _separator) { field_separator = _separator; } template< class R > void t_record_file::set_filename(const string &_filename) { filename = _filename; } template< class R > list *t_record_file::get_records() { return &records; } template< class R > bool t_record_file::load(string &error_msg) { struct stat stat_buf; mtx_records.lock(); records.clear(); // Check if file exists if (filename.empty() || stat(filename.c_str(), &stat_buf) != 0) { // There is no file. mtx_records.unlock(); return true; } // Open call ile ifstream file(filename.c_str()); if (!file) { error_msg = TRANSLATE("Cannot open file for reading: %1"); error_msg = replace_first(error_msg, "%1", filename); mtx_records.unlock(); return false; } // Read and parse history file. while (!file.eof()) { string line; getline(file, line); // Check if read operation succeeded if (!file.good() && !file.eof()) { error_msg = TRANSLATE("File system error while reading file %1 ."); error_msg = replace_first(error_msg, "%1", filename); mtx_records.unlock(); return false; } line = trim(line); // Skip empty lines if (line.size() == 0) continue; // Skip comment lines if (line[0] == COMMENT_SYMBOL) continue; // Add record. Skip records that cannot be parsed. R record; vector v; split_record(line, v); if (record.populate_from_file_record(v)) { add_record(record); } } mtx_records.unlock(); return true; } template< class R > bool t_record_file::save(string &error_msg) const { if (filename.empty()) return false; mtx_records.lock(); // Open file ofstream file(filename.c_str()); if (!file) { error_msg = TRANSLATE("Cannot open file for writing: %1"); error_msg = replace_first(error_msg, "%1", filename); mtx_records.unlock(); return false; } // Write file header file << "# " << header << endl; // Write records for (record_const_iterator i = records.begin(); i != records.end(); ++i) { vector v; if (i->create_file_record(v)) { file << join_fields(v); file << endl; } } mtx_records.unlock(); if (!file.good()) { error_msg = TRANSLATE("File system error while writing file %1 ."); error_msg = replace_first(error_msg, "%1", filename); return false; } return true; } twinkle-1.4.2/src/client_request.h0000644000175000001440000000655211127714046014111 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** @file * Bind request with TU and transaction */ #ifndef _CLIENT_REQUEST_H #define _CLIENT_REQUEST_H #include "protocol.h" #include "redirect.h" #include "user.h" #include "transaction_layer.h" #include "threads/mutex.h" #include "parser/request.h" #include "stun/stun.h" using namespace std; /** Object for storing a request together with its Transaction User id and transaction id. */ class t_client_request { private: static t_mutex mtx_next_tuid; /**< Protect updates on @ref next_tuid */ static t_tuid next_tuid; /**< Next transaction user id to handout. */ // A client request is either a SIP or a STUN request t_request *request; /**< SIP request. */ StunMessage *stun_request; /**< STUN request. */ t_tuid tuid; /**< Transaction user id. */ t_tid tid; /**< Transaction id. */ /** Number of references to this object (#dialogs). */ int ref_count; public: /** Redirector for 3XX redirections. */ t_redirector redirector; /** * Constructor. * A copy of the request is stored in the client_request object. * @param user The user profile of the user sending the request. * @param r SIP request. * @param _tid Transaction id. */ t_client_request(t_user *user, t_request *r, const t_tid _tid); /** * Constructor. * A copy of the request is stored in the client_request object. * @param user The user profile of the user sending the request. * @param r STUN request. * @param _tid Transaction id. */ t_client_request(t_user *user, StunMessage *r, const t_tid _tid); /** Destructor. */ ~t_client_request(); /** * Create a copy of the client request. * @return Copy of the client request. * @note: The request inside the client request is copied. */ t_client_request *copy(void); /** * Get a pointer to the SIP request. * @return Pointer to the SIP request. */ t_request *get_request(void) const; /** * Get a pointer to the STUN request. * @return Pointer to the STUN request. */ StunMessage *get_stun_request(void) const; /** Get the transaction user id. */ t_tuid get_tuid(void) const; /** Get the transaction id. */ t_tid get_tid(void) const; /** Set the transaction id. */ void set_tid(t_tid _tid); /** * Create a new tuid and set tid. * @param _tid The new tid to set. */ void renew(t_tid _tid); /** Get the reference count. */ int get_ref_count(void) const; /** * Increment reference count. * @return The reference count after increment. */ int inc_ref_count(void); /** * Decrement reference count. * @returns The reference count after decrement. */ int dec_ref_count(void); }; #endif twinkle-1.4.2/src/transaction_layer.cpp0000644000175000001440000001721111127714055015131 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "events.h" #include "transaction_layer.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_trans_layer; extern bool end_app; void t_transaction_layer::recvd_response(t_response *r, t_tuid tuid, t_tid tid) { lock(); switch(r->get_class()) { case R_1XX: recvd_provisional(r, tuid, tid); break; case R_2XX: recvd_success(r, tuid, tid); break; case R_3XX: recvd_redirect(r, tuid, tid); break; case R_4XX: recvd_client_error(r, tuid, tid); break; case R_5XX: recvd_server_error(r, tuid, tid); break; case R_6XX: recvd_global_error(r, tuid, tid); break; default: assert(false); break; } post_process_response(r, tuid, tid); unlock(); } void t_transaction_layer::recvd_request(t_request *r, t_tid tid, t_tid tid_cancel_target) { bool fatal; string reason; t_response *resp; lock(); // Return a 400 response if the SIP headers are wrong if (!r->is_valid(fatal, reason)) { resp = r->create_response(R_400_BAD_REQUEST, reason); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; unlock(); return; } // Return a 400 response if the SIP body contained a parse error if (r->body && r->body->invalid) { resp = r->create_response(R_400_BAD_REQUEST, "Invalid SIP body."); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; unlock(); return; } // If a message exceeded the maximum message size, than the body // is not parsed by the listener. if (r->hdr_content_length.is_populated() && r->hdr_content_length.length > 0 && !r->body) { resp = r->create_response(R_513_MESSAGE_TOO_LARGE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; unlock(); return; } // RFC 3261 8.2.3 // Return a 415 response if content encoding is not supported if (r->body && r->hdr_content_encoding.is_populated()) { for (list::iterator it = r->hdr_content_encoding.coding_list.begin(); it != r->hdr_content_encoding.coding_list.end(); ++it) { if (!CONTENT_ENCODING_SUPPORTED(it->content_coding)) { resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE); SET_HDR_ACCEPT_ENCODING(resp->hdr_accept_encoding); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; unlock(); return; } } } // Check if URI scheme is supported if (r->uri.get_scheme() != "sip") { resp = r->create_response(R_416_UNSUPPORTED_URI_SCHEME); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; unlock(); return; } switch(r->method) { case INVITE: recvd_invite(r, tid); break; case ACK: recvd_ack(r, tid); break; case CANCEL: recvd_cancel(r, tid, tid_cancel_target); break; case BYE: recvd_bye(r, tid); break; case OPTIONS: recvd_options(r, tid); break; case REGISTER: recvd_register(r, tid); break; case PRACK: recvd_prack(r, tid); break; case SUBSCRIBE: recvd_subscribe(r, tid); break; case NOTIFY: recvd_notify(r, tid); break; case REFER: recvd_refer(r, tid); break; case INFO: recvd_info(r, tid); break; case MESSAGE: recvd_message(r, tid); break; default: resp = r->create_response(R_501_NOT_IMPLEMENTED); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; break; } post_process_request(r, tid, tid_cancel_target); unlock(); } void t_transaction_layer::recvd_async_response(t_event_async_response *event) { lock(); switch (event->get_response_type()) { case t_event_async_response::RESP_REFER_PERMISSION: recvd_refer_permission(event->get_bool_response()); break; default: // Ignore other responses break; } unlock(); } void t_transaction_layer::send_request(t_user *user_config, t_request *r, t_tuid tuid) { evq_trans_mgr->push_user(user_config, (t_sip_message *)r, tuid, 0); } void t_transaction_layer::send_request(t_user *user_config, StunMessage *r, t_tuid tuid) { // The transaction manager will determine the destination IP and port, // so they can be left to zero in the event. evq_trans_mgr->push_stun_request(user_config, r, TYPE_STUN_SIP, tuid, 0, 0, 0); } void t_transaction_layer::send_response(t_response *r, t_tuid tuid, t_tid tid) { evq_trans_mgr->push_user((t_sip_message *)r, tuid, tid); } void t_transaction_layer::run(void) { t_event *event; t_event_user *ev_user; t_event_timeout *ev_timeout; t_event_failure *ev_failure; t_event_stun_response *ev_stun_resp; t_event_async_response *ev_async_resp; t_event_broken_connection *ev_broken_connection; t_sip_message *msg; StunMessage *stun_msg; t_tid tid; t_tid tid_cancel; t_tuid tuid; bool quit = false; while (!quit) { event = evq_trans_layer->pop(); switch (event->get_type()) { case EV_USER: ev_user = (t_event_user *)event; tid = ev_user->get_tid(); tuid = ev_user->get_tuid(); tid_cancel = ev_user->get_tid_cancel_target(); msg = ev_user->get_msg(); switch(msg->get_type()) { case MSG_REQUEST: recvd_request((t_request *)msg, tid, tid_cancel); break; case MSG_RESPONSE: recvd_response((t_response *)msg, tuid, tid); break; default: assert(false); break; } break; case EV_TIMEOUT: ev_timeout = dynamic_cast(event); handle_event_timeout(ev_timeout); break; case EV_FAILURE: ev_failure = (t_event_failure *)event; tid = ev_failure->get_tid(); lock(); failure(ev_failure->get_failure(), tid); unlock(); break; case EV_STUN_RESPONSE: ev_stun_resp = (t_event_stun_response *)event; tid = ev_stun_resp->get_tid(); tuid = ev_stun_resp->get_tuid(); stun_msg = ev_stun_resp->get_msg(); recvd_stun_resp(stun_msg, tuid, tid); break; case EV_ASYNC_RESPONSE: ev_async_resp = dynamic_cast(event); recvd_async_response(ev_async_resp); break; case EV_BROKEN_CONNECTION: ev_broken_connection = dynamic_cast(event); handle_broken_connection(ev_broken_connection); break; case EV_QUIT: quit = true; break; default: // other types of event are not expected assert(false); break; } MEMMAN_DELETE(event); delete event; } } void t_transaction_layer::lock(void) const { // Prohibited threads may not lock the transaction layer assert(!is_prohibited_thread()); // The user interface and transaction layer threads both call // functions on the transaction layer. By locking the UI mutex // first, a deadlock can never occur as the UI also takes the // UI lock first and then the transaction layer lock. // During shutdown of Twinkle the GUI has exited already and // a lock on an exited QApplication causes a segmentation fault. // Therefore the lock on the UI should not be taken during shutdown. if (!end_app) ui->lock(); tl_mutex.lock(); } void t_transaction_layer::unlock(void) const { tl_mutex.unlock(); if (!end_app) ui->unlock(); } twinkle-1.4.2/src/auth.cpp0000644000175000001440000001356311127714055012357 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "auth.h" #include "log.h" #include "protocol.h" #include "user.h" #include "userintf.h" #include "util.h" extern string user_host; t_cr_cache_entry:: t_cr_cache_entry(const t_url &_to, const t_credentials &_cr, const string &_passwd, bool _proxy) : to(_to) { credentials = _cr; passwd = _passwd; proxy = _proxy; } list::iterator t_auth::find_cache_entry( const t_url &_to, const string &realm, bool proxy) { for (list::iterator i = cache.begin(); i != cache.end(); i++) { // RFC 3261 22.1 // Only the realm determines the protection space. // So the to-uri must not need to be compared as for HTTP // i.e. check i->to == _to must not be done. // As realm strings are globally unique there is no need // to check if the credentials are for a 407 or 401 response. // i.e. check i->proxy == proxy is not needed. if (i->credentials.digest_response.realm == realm) { return i; } } return cache.end(); } void t_auth::update_cache(const t_url &to, const t_credentials &cr, const string &passwd, bool proxy) { list::iterator i, j; i = find_cache_entry(to, cr.digest_response.realm, proxy); if (i == cache.end()) { if (cache.size() > AUTH_CACHE_SIZE) { cache.erase(cache.begin()); } cache.push_back(t_cr_cache_entry(to, cr, passwd, proxy)); } else { i->credentials = cr; i->passwd = passwd; // Move cache entry to end of the cache. // TODO: this can be more efficient by checking if the // entry is already at the end. t_cr_cache_entry e = *i; cache.erase(i); cache.push_back(e); } } bool t_auth::auth_failed(t_request *r, const t_challenge &c, bool proxy) const { if (c.digest_challenge.stale) { log_file->write_report("Stale nonce value.", "t_auth::auth_failed"); return false; } if (proxy) { return r->hdr_proxy_authorization.contains( c.digest_challenge.realm, r->uri); } else { return r->hdr_authorization.contains( c.digest_challenge.realm, r->uri); } } void t_auth::remove_credentials(t_request *r, const t_challenge &c, bool proxy) const { if (proxy) { r->hdr_proxy_authorization.remove_credentials( c.digest_challenge.realm, r->uri); } else { r->hdr_authorization.remove_credentials( c.digest_challenge.realm, r->uri); } } t_auth::t_auth() { re_register = false; } bool t_auth::authorize(t_user *user_config, t_request *r, t_response *resp) { string username; string passwd; list::iterator i; t_challenge c; bool proxy; assert(resp->must_authenticate()); if (resp->code == R_401_UNAUTHORIZED) { c = resp->hdr_www_authenticate.challenge; proxy = false; } else { c = resp->hdr_proxy_authenticate.challenge; proxy = true; } // Only DIGEST is supported if (c.auth_scheme != AUTH_DIGEST) { log_file->write_header("t_auth::authorize"); log_file->write_raw("Unsupported authentication scheme: "); log_file->write_raw(c.auth_scheme); log_file->write_endl(); log_file->write_footer(); return false; } const t_digest_challenge &dc = c.digest_challenge; i = find_cache_entry(r->uri, dc.realm, proxy); if (auth_failed(r, c, proxy)) { // The current credentials are wrong. Remove them and // ask the user for a username and password. remove_credentials(r, c, proxy); } else { // Determine user name and password if (i != cache.end()) { username = i->credentials.digest_response.username; passwd = i->passwd; } else if (dc.realm == user_config->get_auth_realm() || user_config->get_auth_realm() == "") { username = user_config->get_auth_name(); passwd = user_config->get_auth_pass(); } if (dc.stale) { // The current credentials are stale. Remove them. remove_credentials(r, c, proxy); } } // Ask user for username/password if ((username == "" || passwd == "") && !re_register) { if (!ui->cb_ask_credentials(user_config, dc.realm, username, passwd)) { log_file->write_report("Asking user name and password failed.", "t_auth::authorize"); return false; } } // No valid username/passwd if (username == "" && passwd == "") { log_file->write_report("Incorrect user name and/or password.", "t_auth::authorize"); return false; } bool auth_success; string fail_reason; if (!proxy) { t_credentials cr; auth_success = r->www_authorize(c, user_config, username, passwd, 1, NEW_CNONCE, cr, fail_reason); if (auth_success) { update_cache(r->uri, cr, passwd, proxy); } } else { t_credentials cr; auth_success = r->proxy_authorize(c, user_config, username, passwd, 1, NEW_CNONCE, cr, fail_reason); if (auth_success) { update_cache(r->uri, cr, passwd, proxy); } } if (!auth_success) { log_file->write_report(fail_reason, "t_auth::authorize"); return false; } return true; } void t_auth::remove_from_cache(const string &realm) { if (realm.empty()) { cache.clear(); } else { list::iterator i = find_cache_entry(t_url(), realm); if (i != cache.end()) { cache.erase(i); } } } void t_auth::set_re_register(bool on) { re_register = on; } bool t_auth::get_re_register(void) const { return re_register; } twinkle-1.4.2/src/service.h0000644000175000001440000000477511127714046012530 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_SERVICE #define _H_SERVICE #include #include "user.h" #include "sockets/url.h" #include "threads/mutex.h" #define SVC_FILE_EXT ".svc" using namespace std; // Call forwarding types enum t_cf_type { CF_ALWAYS, CF_BUSY, CF_NOANSWER }; class t_service { private: // Protect operations on the service t_mutex mtx_service; t_user *user_config; // Call redirection (call forwarding) bool cf_always_active; list cf_always_dest; bool cf_busy_active; list cf_busy_dest; bool cf_noanswer_active; list cf_noanswer_dest; // Do not disturb // Note: CF_ALWAYS takes precedence over DND bool dnd_active; // Auto answer bool auto_answer_active; void lock(); void unlock(); t_service() {}; public: t_service(t_user *user); // All methods first lock the mtx_service mutex before executing // and unlock on return to guarantee the service data does not // get changed by other threads during execution. // General // Is more than 1 service active? // Different types of call forwarding counts as 1. bool multiple_services_active(void); // Call forwarding void enable_cf(t_cf_type cf_type, const list &cf_dest); void disable_cf(t_cf_type cf_type); bool get_cf_active(t_cf_type cf_type, list &dest); bool is_cf_active(void); // is any cf active? list get_cf_dest(t_cf_type cf_type); // Do not disturb void enable_dnd(void); void disable_dnd(void); bool is_dnd_active(void) const; // Auto answer void enable_auto_answer(bool on); bool is_auto_answer_active(void) const; // Read/write service settings to file bool read_config(string &error_msg); bool write_config(string &error_msg); }; #endif twinkle-1.4.2/src/redirect.cpp0000644000175000001440000000401611127714055013210 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "redirect.h" bool t_redirector::contact_already_added(const t_contact_param contact) const { for (list::const_iterator i = try_contacts.begin(); i != try_contacts.end(); i++) { if (i->uri == contact.uri) return true; } for (list::const_iterator i = done_contacts.begin(); i != done_contacts.end(); i++) { if (i->uri == contact.uri) return true; } if (contact.uri == org_dest) return true; return false; } t_redirector::t_redirector(const t_url &_org_dest, int _max_redirections) { num_contacts = 0; org_dest = _org_dest; max_redirections = _max_redirections; } bool t_redirector::get_next_contact(t_contact_param &contact) { if (try_contacts.empty()) return false; contact = try_contacts.front(); try_contacts.pop_front(); done_contacts.push_back(contact); return true; } void t_redirector::add_contacts(const list &contacts) { if (num_contacts >= max_redirections) return; list l = contacts; l.sort(); for (list::iterator i = l.begin(); i != l.end(); i++) { if (!contact_already_added(*i)) { try_contacts.push_back(*i); num_contacts++; if (num_contacts >= max_redirections) break; } } } twinkle-1.4.2/src/protocol.h0000644000175000001440000002703311127714046012721 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PROTOCOL_H #define _PROTOCOL_H #include "twinkle_config.h" #include "parser/hdr_supported.h" /** Carriage Return Line Feed */ #define CRLF "\r\n" /** TCP PING packet to be sent on a TCP connection. */ #define TCP_PING_PACKET CRLF CRLF /** Product name */ #define PRODUCT_NAME "Twinkle" /** Product version */ #define PRODUCT_VERSION VERSION /** * When a SIP message is created, some addresses will be filled in * by the sender thread as only this thread knows the source IP * address of an outgoing message. * The sender thread will look for occurrences of the AUTO_IP4_ADDRESS * and replace it with the source IP address. */ #define AUTO_IP4_ADDRESS "255.255.255.255" /** Display name for anonymous calling */ #define ANONYMOUS_DISPLAY "Anonymous" /** SIP-URI for anonymous calling */ #define ANONYMOUS_URI "sip:anonymous@anonymous.invalid" /** Types of failures. */ enum t_failure { FAIL_TIMEOUT, /**< Transaction timed out */ FAIL_TRANSPORT /**< Transport failure */ }; /** Call transfer types */ enum t_transfer_type { TRANSFER_BASIC, /**< Basic transfer (blind) */ TRANSFER_CONSULT, /**< Transfer with consultation (possibly attended) */ TRANSFER_OTHER_LINE /**< Transfer call to other line */ }; /** State of a call transfer at the referrer. */ enum t_refer_state { REFST_NULL, /**< No REFER in progress */ REFST_W4RESP, /**< REFER sent, waiting for response */ REFST_W4NOTIFY, /**< Response received, waiting for 1st NOTIFY */ REFST_PENDING, /**< REFER received, but not granted yet */ REFST_ACTIVE, /**< Referee granted refer */ }; /** Types of registration requests */ enum t_register_type { REG_REGISTER, REG_QUERY, REG_DEREGISTER, REG_DEREGISTER_ALL }; /** * RFC 3261 Annex A * SIP timers */ enum t_sip_timer { TIMER_T1, TIMER_T2, TIMER_T4, TIMER_A, TIMER_B, TIMER_C, TIMER_D, TIMER_E, TIMER_F, TIMER_G, TIMER_H, TIMER_I, TIMER_J, TIMER_K }; // All durations are in msec #define DURATION_T1 500 #define DURATION_T2 4000 #define DURATION_T4 5000 #define DURATION_A DURATION_T1 #define DURATION_B (64 * DURATION_T1) #define DURATION_C 180000 #define DURATION_D 32000 #define DURATION_E DURATION_T1 #define DURATION_F (64 * DURATION_T1) #define DURATION_G DURATION_T1 #define DURATION_H (64 * DURATION_T1) #define DURATION_I DURATION_T4 #define DURATION_J (64 * DURATION_T1) #define DURATION_K DURATION_T4 /** Time to keep an idle connection open before closing */ #define DUR_IDLE_CONNECTION (64 * DURATION_T1) /** UA (phone) timers */ enum t_phone_timer { PTMR_REGISTRATION, /**< Registration (failure) timeout */ PTMR_NAT_KEEPALIVE, /**< NAT binding refresh timeout for STUN */ PTMR_TCP_PING, /**< TCP ping interval */ }; /** UA (line) timers */ enum t_line_timer { LTMR_ACK_TIMEOUT, /**< Waiting for ACK */ LTMR_ACK_GUARD, /**< After this timer ACK is lost for good */ LTMR_INVITE_COMP, /**< After this timer INVITE transiction is considered complete. */ LTMR_NO_ANSWER, /**< This timer expires if the callee does not answer. The call will be torn down. */ LTMR_RE_INVITE_GUARD, /**< re-INVITE timeout */ LTMR_100REL_TIMEOUT, /**< Waiting for PRACK */ LTMR_100REL_GUARD, /**< After this timer PRACK is lost for good */ LTMR_GLARE_RETRY, /**< Waiting before retry re-INVITE after glare */ LTMR_CANCEL_GUARD, /**< Guard for situation where CANCEL has been responded to, but 487 on INVITE is never received. */ }; /** Subscription timers. */ enum t_subscribe_timer { STMR_SUBSCRIPTION, /**< Subscription timeout */ }; /** Publication timers. */ enum t_publish_timer { PUBLISH_TMR_PUBLICATION, /**< Publication timeout */ }; /** STUN timers. */ enum t_stun_timer { STUN_TMR_REQ_TIMEOUT, /**< Waiting for response */ }; /** No answer timer (ms) */ #define DUR_NO_ANSWER(u) ((u)->get_timer_noanswer() * 1000) /** @name Registration timers */ //@{ /** Registration duration (seconds) */ #define DUR_REGISTRATION(u) ((u)->get_registration_time()) /**< Re-register 5 seconds before expiry **/ #define RE_REGISTER_DELTA 5 /** Re-registration interval after reg. failure */ #define DUR_REG_FAILURE 30 //@} /** NAT keepalive timer (s) default value */ #define DUR_NAT_KEEPALIVE 30 /** Default TCP ping interval (s) */ #define DUR_TCP_PING 30 /** * re-INVITE guard timer (ms). This timer guards against the situation * where a UAC has sent a re-INVITE, received a 1XX but never receives * a final response. No timer for this is defined in RFC 3261 */ #define DUR_RE_INVITE_GUARD 10000 /** * Guard for situation where CANCEL has been * responded to, but 487 on INVITE is never eceived. * This situation is not defined by RFC 3261 */ #define DUR_CANCEL_GUARD (64 * DURATION_T1) // MWI timers (s) #define DUR_MWI(u) ((u)->get_mwi_subscription_time()) #define DUR_MWI_FAILURE 30 // Presence timers (s) #define DUR_PRESENCE(u) ((u)->get_pres_subscription_time()) #define DUR_PRESENCE_FAILURE 30 // RFC 3261 14.1 // Maximum values (10th of sec) for timers for retrying a re-INVITE after // a glare (491 response). #define MAX_GLARE_RETRY_NOT_OWN 20 #define MAX_GLARE_RETRY_OWN 40 // Calculate the glare retry duration (ms) #define DUR_GLARE_RETRY_NOT_OWN ((rand() % (MAX_GLARE_RETRY_NOT_OWN + 1)) * 100) #define DUR_GLARE_RETRY_OWN ((rand() % (MAX_GLARE_RETRY_OWN - \ MAX_GLARE_RETRY_NOT_OWN) + 1 + MAX_GLARE_RETRY_NOT_OWN)\ * 100) // RFC 3262 // PRACK timers #define DUR_100REL_TIMEOUT DURATION_T1 #define DUR_100REL_GUARD (64 * DURATION_T1) // refer subscription timer (s) // RFC 3515 does not define the length of the timer. // It should be long enough to notify the result of an INVITE. #define DUR_REFER_SUBSCRIPTION 60 // Used when refer is always permitted #define DUR_REFER_SUB_INTERACT 90 // Used when user has to grant permission // Minimum duration of a subscription #define MIN_DUR_SUBSCRIPTION 60 // Duration to wait before re-subscribing after termination of // a subscription #define DUR_RESUBSCRIBE 30 // After an unsubscribe has been sent, a NOTIFY will should come in. // In case the NOTIFY does not come, this guard timer (ms) will assure // that the subscription will be cleaned up. #define DUR_UNSUBSCRIBE_GUARD 4000 // RFC 3489 // STUN retransmission timer intervals (ms) // The RFC states that the interval should start at 100ms. But that // seems to short. We start at 200 and do 8 instead of 9 transmissions. #define DUR_STUN_START_INTVAL 200 #define DUR_STUN_MAX_INTVAL 1600 // Maximum number of transmissions #define STUN_MAX_TRANSMISSIONS 8 // RFC 3261 #ifndef RFC3261_COOKIE #define RFC3261_COOKIE "z9hG4bK" #endif // Max forwards RFC 3261 8.1.1.6 #define MAX_FORWARDS 70 // Length of tags in from and to headers #define TAG_LEN 5 // Create a new tag #define NEW_TAG random_token(TAG_LEN) // Length of call-id (before domain) #define CALL_ID_LEN 15 // Create a new call-id #define NEW_CALL_ID(u) (random_token(CALL_ID_LEN) + '@' + LOCAL_HOSTNAME) // Create a new sequence number fo CSeq header #define NEW_SEQNR rand() % 1000 + 1 // Length of cnonce #define CNONCE_LEN 10 // Create a cnonce #define NEW_CNONCE random_hexstr(CNONCE_LEN) /** Length of tuple id in PIDF documents. */ #define PIDF_TUPLE_ID_LEN 6 /** Create a new PIDF tuple id. */ #define NEW_PIDF_TUPLE_ID random_token(PIDF_TUPLE_ID_LEN) /** Character set encoding for outgoing text messages */ #define MSG_TEXT_CHARSET "utf-8" /** @name Definitions for akav1-md5 authentication. */ #define AKA_RANDLEN 16 #define AKA_AUTNLEN 16 #define AKA_CKLEN 16 #define AKA_IKLEN 16 #define AKA_AKLEN 6 #define AKA_OPLEN 16 #define AKA_RESLEN 8 #define AKA_SQNLEN 6 #define AKA_RESHEXLEN 16 #define AKA_AMFLEN 2 #define AKA_KLEN 16 // Set Allow header with methods that can be handled by the phone #define SET_HDR_ALLOW(h, u) { (h).add_method(INVITE); \ (h).add_method(ACK); \ (h).add_method(BYE); \ (h).add_method(CANCEL); \ (h).add_method(OPTIONS); \ if ((u)->get_ext_100rel() != EXT_DISABLED) {\ (h).add_method(PRACK);\ }\ (h).add_method(REFER); \ (h).add_method(NOTIFY); \ (h).add_method(SUBSCRIBE); \ (h).add_method(INFO); \ (h).add_method(MESSAGE); \ } // Set Supported header with supported extensions #define SET_HDR_SUPPORTED(h, u) { if ((u)->get_ext_replaces()) {\ (h).add_feature(EXT_REPLACES);\ }\ (h).add_feature(EXT_NOREFERSUB);\ } // Set Accept header with accepted body types #define SET_HDR_ACCEPT(h) { (h).add_media(t_media("application",\ "sdp")); } /** * Check if the content type of an instant message is supported * @param h [in] A SIP message. */ #define MESSAGE_CONTENT_TYPE_SUPPORTED(h)\ ((h).hdr_content_type.media.type == "application" ||\ (h).hdr_content_type.media.type == "audio" ||\ (h).hdr_content_type.media.type == "image" ||\ (h).hdr_content_type.media.type == "text" ||\ (h).hdr_content_type.media.type == "video") /** * Set Accept header with accepted body types for instant messaging. * @param h [inout] A SIP message. */ #define SET_MESSAGE_HDR_ACCEPT(h) { (h).add_media(t_media("application/*"));\ (h).add_media(t_media("audio/*"));\ (h).add_media(t_media("image/*"));\ (h).add_media(t_media("text/*"));\ (h).add_media(t_media("video/*")); } /** * Set Accept header with accepted body types for presence. * @param h [inout] A SIP message. */ #define SET_PRESENCE_HDR_ACCEPT(h) { (h).add_media(t_media("application",\ "pidf+xml")); } /** * Set Accept header with accepted body types for MWI. * @param h [inout] A SIP message. */ #define SET_MWI_HDR_ACCEPT(h) { (h).add_media(t_media("application",\ "simple-message-summary")); } /** * Set Accept-Encoding header with accepted encodings. * @param h [inout] A SIP message. */ #define SET_HDR_ACCEPT_ENCODING(h)\ { (h).add_coding(t_coding("identity")); } /** * Check if content encoding is supported * @param h [inout] A SIP message. */ #define CONTENT_ENCODING_SUPPORTED(ce)\ (cmp_nocase(ce, "identity") == 0) // Set Accept-Language header with accepted languages #define SET_HDR_ACCEPT_LANGUAGE(h)\ { (h).add_language(t_language("en")); } // Set User-Agent header #define SET_HDR_USER_AGENT(h) { (h).add_server(t_server(PRODUCT_NAME,\ PRODUCT_VERSION)); } // Set Server header #define SET_HDR_SERVER(h) { (h).add_server(t_server(PRODUCT_NAME,\ PRODUCT_VERSION)); } // Set Organization header #define SET_HDR_ORGANIZATION(h, u) { if ((u)->get_organization() != "") {\ (h).set_name((u)->get_organization()); }} // Check if an event is supported by Twinkle #define SIP_EVENT_SUPPORTED(e) ((e) == SIP_EVENT_REFER ||\ (e) == SIP_EVENT_MSG_SUMMARY ||\ (e) == SIP_EVENT_PRESENCE) // Add the supported events to the Allow-Events header #define ADD_SUPPORTED_SIP_EVENTS(h) { (h).add_event_type(SIP_EVENT_REFER);\ (h).add_event_type(SIP_EVENT_MSG_SUMMARY);\ (h).add_event_type(SIP_EVENT_PRESENCE); } #endif twinkle-1.4.2/src/cmd_socket.h0000644000175000001440000000351711127714046013174 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Twinkle listens on a local socket for external commands. */ #ifndef _H_CMD_SOCKET #define _H_CMD_SOCKET #include /** Name of the local socket. */ #define CMD_SOCKNAME ".cmdsock" using namespace std; namespace cmdsocket { /** * Listen on local socket for commands. * @param arg A local socket (@ref t_socket_local) */ void *listen_cmd(void *arg); /** * Send call command to the local socket. * @param destination The SIP destination to call. * @param immediate Indicates if the call should be made immediately * without asking the user for confirmation. */ void cmd_call(const string &destination, bool immediate); /** * Send a CLI command to the local socket. * @param cli_command The CLI command to send. * @param immediate Indicates if the call should be made immediately * without asking the user for confirmation. */ void cmd_cli(const string &cli_command, bool immediate); /** Send show command to the local socket. */ void cmd_show(void); /** Send hide command to the local socket. */ void cmd_hide(void); } #endif twinkle-1.4.2/src/userintf.cpp0000644000175000001440000024754311134641436013264 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "address_book.h" #include "events.h" #include "line.h" #include "log.h" #include "sys_settings.h" #include "translator.h" #include "userintf.h" #include "util.h" #include "user.h" #include "audio/rtp_telephone_event.h" #include "parser/parse_ctrl.h" #include "sockets/interfaces.h" #include "audits/memman.h" #include "utils/file_utils.h" #include "utils/mime_database.h" #define CLI_PROMPT "Twinkle> " #define CLI_MAX_HISTORY_LENGTH 1000 extern string user_host; extern t_event_queue *evq_trans_layer; using namespace utils; //////////////////////// // GNU Readline helpers //////////////////////// char ** tw_completion (const char *text, int start, int end); char * tw_command_generator (const char *text, int state); char ** tw_completion (const char *text, int start, int end) { char **matches; matches = (char **)NULL; if (start == 0) matches = rl_completion_matches (text, tw_command_generator); return (matches); } char * tw_command_generator (const char *text, int state) { static int len; static list::const_iterator i; if (!state){ len = strlen(text); i = ui->get_all_commands().begin(); } for (; i != ui->get_all_commands().end(); i++){ const char * s = i->c_str(); //cout << s << endl; if ( s && strncmp(s, text, len) == 0 ){ i++; return strdup(s); } } /* If no names matched, then return NULL. */ return ((char *)NULL); } char *tw_readline(const char *prompt) { static char *line = NULL; if (!line) { free(line); line = NULL; } line = readline(prompt); if (line && *line) { add_history(line); } return line; } ///////////////////////////// // Private ///////////////////////////// string t_userintf::expand_destination(t_user *user_config, const string &dst, const string &scheme) { assert(user_config); string s = dst; // Apply number conversion rules if applicable // Add domain if it is missing from a sip-uri if (s.find('@') == string::npos) { bool is_tel_uri = (s.substr(0, 4) == "tel:"); // Strip tel-scheme if (is_tel_uri) s = s.substr(4); // Remove white space s = remove_white_space(s); // Remove special phone symbols if (user_config->get_remove_special_phone_symbols() && looks_like_phone(s, user_config->get_special_phone_symbols())) { s = remove_symbols(s, user_config->get_special_phone_symbols()); } // Convert number according to the number conversion rules s = user_config->convert_number(s); if (is_tel_uri) { // Add tel-scheme again. s = "tel:" + s; } else if (s.substr(0, 4) != "sip:" && (user_config->get_use_tel_uri_for_phone() || scheme == "tel") && user_config->get_numerical_user_is_phone() && looks_like_phone(s, user_config->get_special_phone_symbols())) { // Add tel-scheme if a telephone number must be expanded // to a tel-uri according to user profile settings. s = "tel:" + s; } else { // Add domain s += '@'; s += user_config->get_domain(); } } // Add sip-scheme if a scheme is missing if (s.substr(0, 4) != "sip:" && s.substr(0, 4) != "tel:") { s = "sip:" + s; } // RFC 3261 19.1.1 // Add user=phone for telehpone numbers in a SIP-URI // If the SIP-URI contains a telephone number it SHOULD contain // the user=phone parameter. if (user_config->get_numerical_user_is_phone() && s.substr(0, 4) == "sip:") { t_url u(s); if (u.get_user_param().empty() && u.user_looks_like_phone(user_config->get_special_phone_symbols())) { s += ";user=phone"; } } return s; } void t_userintf::expand_destination(t_user *user_config, const string &dst, string &display, string &dst_url) { display.clear(); dst_url.clear(); if (dst.empty()) { return; } // If there is a display name then the url part is between angle // brackets. if (dst[dst.size() - 1] != '>') { dst_url = expand_destination(user_config, dst); return; } // Find start of url string::size_type i = dst.rfind('<'); if (i == string::npos) { // It seems the string is invalid. return; } dst_url = expand_destination(user_config, dst.substr(i + 1, dst.size() - i - 2)); if (i > 0) { display = unquote(trim(dst.substr(0, i))); } } void t_userintf::expand_destination(t_user *user_config, const string &dst, t_display_url &display_url) { string url_str; expand_destination(user_config, dst, display_url.display, url_str); display_url.url.set_url(url_str); } void t_userintf::expand_destination(t_user *user_config, const string &dst, t_display_url &display_url, string &subject, string &dst_no_headers) { string headers; dst_no_headers = dst; t_url u(dst); // Split headers from URI if (u.is_valid()) { // destination is a valid URI. Strip off the headers if any headers = u.get_headers(); // Cut off headers // Note that a separator (?) will be in front of the // headers string if (!headers.empty()) { string::size_type i = dst.find(headers); if (i != string::npos) { dst_no_headers = dst.substr(0, i - 1); } } expand_destination(user_config, dst_no_headers, display_url); } else { // destination may be a short URI. // Split at a '?' to find any headers. // NOTE: this is not fool proof. A user name may contain a '?' vector l = split_on_first(dst, '?'); dst_no_headers = l[0]; expand_destination(user_config, dst_no_headers, display_url); if (display_url.is_valid() && l.size() == 2) { headers = l[1]; } } // Parse headers to find subject header subject.clear(); if (!headers.empty()) { try { list parse_errors; t_sip_message *m = t_parser::parse_headers(headers, parse_errors); if (m->hdr_subject.is_populated()) { subject = m->hdr_subject.subject; } MEMMAN_DELETE(m); delete m; } catch (int) { // ignore invalid headers } } } bool t_userintf::parse_args(const list command_list, list &al) { t_command_arg arg; bool parsed_flag = false; al.clear(); arg.flag = 0; arg.value = ""; for (list::const_iterator i = command_list.begin(); i != command_list.end(); i++) { if (i == command_list.begin()) continue; const string &s = *i; if (s[0] == '-') { if (s.size() == 1) return false; if (parsed_flag) al.push_back(arg); arg.flag = s[1]; if (s.size() > 2) { arg.value = unquote(s.substr(2)); al.push_back(arg); arg.flag = 0; arg.value = ""; parsed_flag = false; } else { arg.value = ""; parsed_flag = true; } } else { if (parsed_flag) { arg.value = unquote(s); } else { arg.flag = 0; arg.value = unquote(s); } al.push_back(arg); parsed_flag = false; arg.flag = 0; arg.value = ""; } } // Last parsed argument was a flag only if (parsed_flag) al.push_back(arg); return true; } bool t_userintf::exec_invite(const list command_list, bool immediate) { list al; string display; string subject; string destination; bool hide_user = false; if (!parse_args(command_list, al)) { exec_command("help call"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 'd': display = i->value; break; case 's': subject = i->value; break; case 'h': hide_user = true; break; case 0: destination = i->value; break; default: exec_command("help call"); return false; break; } } return do_invite(destination, display, subject, immediate, hide_user); } bool t_userintf::do_invite(const string &destination, const string &display, const string &subject, bool immediate, bool anonymous) { t_url dest_url(expand_destination(active_user, destination)); if (!dest_url.is_valid()) { exec_command("help call"); return false; } t_url vm_url(expand_destination(active_user, active_user->get_mwi_vm_address())); if (dest_url != vm_url) { // Keep call information for redial last_called_url = dest_url; last_called_display = display; last_called_subject = subject; last_called_profile = active_user->get_profile_name(); last_called_hide_user = anonymous; } phone->pub_invite(active_user, dest_url, display, subject, anonymous); return true; } bool t_userintf::exec_redial(const list command_list) { if (can_redial()) { do_redial(); return true; } return false; } void t_userintf::do_redial(void) { t_user *user_config = phone->ref_user_profile(last_called_profile); phone->pub_invite(user_config, last_called_url, last_called_display, last_called_subject, last_called_hide_user); } bool t_userintf::exec_answer(const list command_list) { do_answer(); return true; } void t_userintf::do_answer(void) { cb_stop_call_notification(phone->get_active_line()); phone->pub_answer(); } bool t_userintf::exec_answerbye(const list command_list) { do_answerbye(); return true; } void t_userintf::do_answerbye(void) { unsigned short line = phone->get_active_line(); switch (phone->get_line_substate(line)) { case LSSUB_INCOMING_PROGRESS: do_answer(); break; case LSSUB_OUTGOING_PROGRESS: case LSSUB_ESTABLISHED: do_bye(); break; default: break; } } bool t_userintf::exec_reject(const list command_list) { do_reject(); return true; } void t_userintf::do_reject(void) { cb_stop_call_notification(phone->get_active_line()); phone->pub_reject(); cout << endl; cout << "Line " << phone->get_active_line() + 1 << ": call rejected.\n"; cout << endl; } bool t_userintf::exec_redirect(const list command_list, bool immediate) { list al; list dest_list; int num_redirections = 0; bool show_status = false; bool action_present = false; bool enable = true; bool type_present = false; t_cf_type cf_type = CF_ALWAYS; if (!parse_args(command_list, al)) { exec_command("help redirect"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 's': show_status = true; break; case 't': if (i->value == "always") { cf_type = CF_ALWAYS; } else if (i->value == "busy") { cf_type = CF_BUSY; } else if (i->value == "noanswer") { cf_type = CF_NOANSWER; } else { exec_command("help redirect"); return false; } type_present = true; break; case 'a': if (i->value == "on") { enable = true; } else if (i->value == "off") { enable = false; } else { exec_command("help redirect"); return false; } action_present = true; break; case 0: dest_list.push_back(i->value); num_redirections++; break; default: exec_command("help redirect"); return false; break; } } if (type_present && enable && (num_redirections == 0 || num_redirections > 5)) { exec_command("help redirect"); return false; } if (!type_present && action_present && enable) { exec_command("help redirect"); return false; } if (!type_present && !action_present && (num_redirections == 0 || num_redirections > 5)) { exec_command("help redirect"); return false; } do_redirect(show_status, type_present, cf_type, action_present, enable, num_redirections, dest_list, immediate); return true; } void t_userintf::do_redirect(bool show_status, bool type_present, t_cf_type cf_type, bool action_present, bool enable, int num_redirections, const list &dest_strlist, bool immediate) { list dest_list; for (list::const_iterator i = dest_strlist.begin(); i != dest_strlist.end(); i++) { t_display_url du; du.url = expand_destination(active_user, *i); du.display.clear(); if (!du.is_valid()) return; dest_list.push_back(du); } if (show_status) { list cf_dest; // call forwarding destinations cout << endl; cout << "Redirect always: "; if (phone->ref_service(active_user)->get_cf_active(CF_ALWAYS, cf_dest)) { for (list::iterator i = cf_dest.begin(); i != cf_dest.end(); i++) { if (i != cf_dest.begin()) cout << ", "; cout << i->encode(); } } else { cout << "not active"; } cout << endl; cout << "Redirect busy: "; if (phone->ref_service(active_user)->get_cf_active(CF_BUSY, cf_dest)) { for (list::iterator i = cf_dest.begin(); i != cf_dest.end(); i++) { if (i != cf_dest.begin()) cout << ", "; cout << i->encode(); } } else { cout << "not active"; } cout << endl; cout << "Redirect noanswer: "; if (phone->ref_service(active_user)->get_cf_active(CF_NOANSWER, cf_dest)) { for (list::iterator i = cf_dest.begin(); i != cf_dest.end(); i++) { if (i != cf_dest.begin()) cout << ", "; cout << i->encode(); } } else { cout << "not active"; } cout << endl; cout << endl; return; } // Enable/disable permanent redirections if (type_present) { if (enable) { phone->ref_service(active_user)->enable_cf(cf_type, dest_list); cout << "Redirection enabled.\n\n"; } else { phone->ref_service(active_user)->disable_cf(cf_type); cout << "Redirection disabled.\n\n"; } return; } else { if (action_present) { if (!enable) { phone->ref_service(active_user)->disable_cf(CF_ALWAYS); phone->ref_service(active_user)->disable_cf(CF_BUSY); phone->ref_service(active_user)->disable_cf(CF_NOANSWER); cout << "All redirections disabled.\n\n"; return; } return; } } // Redirect current call cb_stop_call_notification(phone->get_active_line()); phone->pub_redirect(dest_list, 302); cout << endl; cout << "Line " << phone->get_active_line() + 1 << ": call redirected.\n"; cout << endl; } bool t_userintf::exec_dnd(const list command_list) { list al; bool show_status = false; bool toggle = true; bool enable = false; if (!parse_args(command_list, al)) { exec_command("help dnd"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 's': show_status = true; break; case 'a': if (i->value == "on") { enable = true; } else if (i->value == "off") { enable = false; } else { exec_command("help dnd"); return false; } toggle = false; break; default: exec_command("help dnd"); return false; break; } } do_dnd(show_status, toggle, enable); return true; } void t_userintf::do_dnd(bool show_status, bool toggle, bool enable) { if (show_status) { cout << endl; cout << "Do not disturb: "; if (phone->ref_service(active_user)->is_dnd_active()) { cout << "active"; } else { cout << "not active"; } cout << endl; return; } if (toggle) { enable = !phone->ref_service(active_user)->is_dnd_active(); } if (enable) { phone->ref_service(active_user)->enable_dnd(); cout << "Do not disturb enabled.\n\n"; return; } else { phone->ref_service(active_user)->disable_dnd(); cout << "Do not disturb disabled.\n\n"; return; } } bool t_userintf::exec_auto_answer(const list command_list) { list al; bool show_status = false; bool toggle = true; bool enable = false; if (!parse_args(command_list, al)) { exec_command("help auto_answer"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 's': show_status = true; break; case 'a': if (i->value == "on") { enable = true; } else if (i->value == "off") { enable = false; } else { exec_command("help auto_answer"); return false; } toggle = false; break; default: exec_command("help auto_answer"); return false; break; } } do_auto_answer(show_status, toggle, enable); return true; } void t_userintf::do_auto_answer(bool show_status, bool toggle, bool enable) { if (show_status) { cout << endl; cout << "Auto answer: "; if (phone->ref_service(active_user)->is_auto_answer_active()) { cout << "active"; } else { cout << "not active"; } cout << endl; return; } if (toggle) { enable = !phone->ref_service(active_user)->is_auto_answer_active(); } if (enable) { phone->ref_service(active_user)->enable_auto_answer(true); cout << "Auto answer enabled.\n\n"; return; } else { phone->ref_service(active_user)->enable_auto_answer(false); cout << "Auto answer disabled.\n\n"; return; } } bool t_userintf::exec_bye(const list command_list) { do_bye(); return true; } void t_userintf::do_bye(void) { phone->pub_end_call(); } bool t_userintf::exec_hold(const list command_list) { do_hold(); return true; } void t_userintf::do_hold(void) { phone->pub_hold(); } bool t_userintf::exec_retrieve(const list command_list) { do_retrieve(); return true; } void t_userintf::do_retrieve(void) { phone->pub_retrieve(); } bool t_userintf::exec_refer(const list command_list, bool immediate) { list al; string destination; bool dest_set = false; t_transfer_type transfer_type = TRANSFER_BASIC; if (!parse_args(command_list, al)) { exec_command("help transfer"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 'c': if (transfer_type != TRANSFER_BASIC) { exec_command("help transfer"); return false; } transfer_type = TRANSFER_CONSULT; if (!i->value.empty()) { destination = i->value; dest_set = true; } break; case 'l': if (transfer_type != TRANSFER_BASIC) { exec_command("help transfer"); return false; } transfer_type = TRANSFER_OTHER_LINE; break; case 0: destination = i->value; dest_set = true; break; default: exec_command("help transfer"); return false; break; } } if (!dest_set && transfer_type == TRANSFER_BASIC) { exec_command("help transfer"); return false; } return do_refer(destination, transfer_type, immediate); } bool t_userintf::do_refer(const string &destination, t_transfer_type transfer_type, bool immediate) { t_url dest_url; if (transfer_type == TRANSFER_BASIC || (transfer_type == TRANSFER_CONSULT && !destination.empty())) { dest_url.set_url(expand_destination(active_user, destination)); if (!dest_url.is_valid()) { exec_command("help transfer"); return false; } } unsigned short active_line; unsigned short other_line; unsigned short line_to_be_transferred; switch (transfer_type) { case TRANSFER_BASIC: phone->pub_refer(dest_url, ""); break; case TRANSFER_CONSULT: if (destination.empty()) { active_line = phone->get_active_line(); if (!phone->is_line_transfer_consult(active_line, line_to_be_transferred)) { // There is no call to transfer return false; } phone->pub_refer(line_to_be_transferred, active_line); } else { phone->pub_setup_consultation_call(dest_url, ""); } break; case TRANSFER_OTHER_LINE: active_line = phone->get_active_line(); other_line = (active_line == 0 ? 1 : 0); phone->pub_refer(active_line, other_line); break; } return true; } bool t_userintf::exec_conference(const list command_list) { do_conference(); return true; } void t_userintf::do_conference(void) { if (phone->join_3way(0, 1)) { cout << endl; cout << "Started 3-way conference.\n"; cout << endl; } else { cout << endl; cout << "Failed to start 3-way conference.\n"; cout << endl; } } bool t_userintf::exec_mute(const list command_list) { list al; bool show_status = false; bool toggle = true; bool enable = true; if (!parse_args(command_list, al)) { exec_command("help mute"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 's': show_status = true; break; case 'a': if (i->value == "on") { enable = true; } else if (i->value == "off") { enable = false; } else { exec_command("help mute"); return false; } toggle = false; break; default: exec_command("help mute"); return false; break; } } do_mute(show_status, toggle, enable); return true; } void t_userintf::do_mute(bool show_status, bool toggle, bool enable) { if (show_status) { cout << endl; cout << "Line is "; if (phone->is_line_muted(phone->get_active_line())) { cout << "muted."; } else { cout << "not muted."; } cout << endl; return; } if (toggle) enable = !phone->is_line_muted(phone->get_active_line()); if (enable) { phone->mute(enable); cout << "Line muted.\n\n"; return; } else { phone->mute(enable); cout << "Line unmuted.\n\n"; return; } } bool t_userintf::exec_dtmf(const list command_list) { list al; string digits; bool raw_mode = false; if (phone->get_line_state(phone->get_active_line()) == LS_IDLE) { return false; } if (!parse_args(command_list, al)) { exec_command("help dtmf"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 'r': raw_mode = true; if (!i->value.empty()) digits = i->value; break; case 0: digits = i->value; break; default: exec_command("help dtmf"); return false; break; } } if (!raw_mode) { digits = str2dtmf(digits); } if (digits == "") { exec_command("help dtmf"); return false; } do_dtmf(digits); return true; } void t_userintf::do_dtmf(const string &digits) { const t_call_info call_info = phone->get_call_info(phone->get_active_line()); throttle_dtmf_not_supported = false; if (!call_info.dtmf_supported) return; for (string::const_iterator i = digits.begin(); i != digits.end(); i++) { if (VALID_DTMF_SYM(*i)) { phone->pub_send_dtmf(*i, call_info.dtmf_inband, call_info.dtmf_info); } } } bool t_userintf::exec_register(const list command_list) { list al; bool reg_all_profiles = false; if (!parse_args(command_list, al)) { exec_command("help register"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 'a': reg_all_profiles = true; break; default: exec_command("help register"); return false; break; } } do_register(reg_all_profiles); return true; } void t_userintf::do_register(bool reg_all_profiles) { if (reg_all_profiles) { list user_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { phone->pub_registration(*i, REG_REGISTER, DUR_REGISTRATION(*i)); } } else { phone->pub_registration(active_user, REG_REGISTER, DUR_REGISTRATION(active_user)); } } bool t_userintf::exec_deregister(const list command_list) { list al; bool dereg_all_devices = false; bool dereg_all_profiles = false; if (!parse_args(command_list, al)) { exec_command("help deregister"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 'a': dereg_all_profiles = true; break; case 'd': dereg_all_devices = true; break; default: exec_command("help deregister"); return false; break; } } do_deregister(dereg_all_profiles, dereg_all_devices); return true; } void t_userintf::do_deregister(bool dereg_all_profiles, bool dereg_all_devices) { t_register_type dereg_type = REG_DEREGISTER; if (dereg_all_devices) { dereg_type = REG_DEREGISTER_ALL; } if (dereg_all_profiles) { list user_list = phone->ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { phone->pub_registration(*i, dereg_type); } } else { phone->pub_registration(active_user, dereg_type); } } bool t_userintf::exec_fetch_registrations(const list command_list) { do_fetch_registrations(); return true; } void t_userintf::do_fetch_registrations(void) { phone->pub_registration(active_user, REG_QUERY); } bool t_userintf::exec_options(const list command_list, bool immediate) { list al; string destination; bool dest_set = false; if (!parse_args(command_list, al)) { exec_command("help options"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 0: destination = i->value; dest_set = true; break; default: exec_command("help options"); return false; break; } } if (!dest_set) { if (phone->get_line_state(phone->get_active_line()) == LS_IDLE) { exec_command("help options"); return false; } } return do_options(dest_set, destination, immediate); } bool t_userintf::do_options(bool dest_set, const string &destination, bool immediate) { if (!dest_set) { phone->pub_options(); } else { t_url dest_url; dest_url.set_url(expand_destination(active_user, destination)); if (!dest_url.is_valid()) { exec_command("help options"); return false; } phone->pub_options(active_user, dest_url); } return true; } bool t_userintf::exec_line(const list command_list) { list al; int line = 0; if (!parse_args(command_list, al)) { exec_command("help line"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 0: line = atoi(i->value.c_str()); break; default: exec_command("help line"); return false; break; } } if (line < 0 || line > 2) { exec_command("help line"); return false; } do_line(line); return true; } void t_userintf::do_line(int line) { if (line == 0) { cout << endl; cout << "Active line is: " << phone->get_active_line()+1 << endl; cout << endl; return; } int current = phone->get_active_line(); if (line == current + 1) { cout << endl; cout << "Line " << current + 1 << " is already active.\n"; cout << endl; return; } phone->pub_activate_line(line - 1); if (phone->get_active_line() == current) { cout << endl; cout << "Current call cannot be put on-hold.\n"; cout << "Cannot switch to another line now.\n"; cout << endl; } else { cout << endl; cout << "Line " << phone->get_active_line()+1 << " is now active.\n"; cout << endl; } } bool t_userintf::exec_user(const list command_list) { list al; string profile_name; if (!parse_args(command_list, al)) { exec_command("help user"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 0: profile_name = i->value; break; default: exec_command("help user"); return false; break; } } do_user(profile_name); return true; } void t_userintf::do_user(const string &profile_name) { list user_list = phone->ref_users(); if (profile_name.empty()) { // Show all users cout << endl; for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if (*i == active_user) { cout << "* "; } else { cout << " "; } cout << (*i)->get_profile_name(); cout << "\n "; cout << (*i)->get_display(false); cout << " get_name(); cout << "@" << (*i)->get_domain() << ">\n"; } cout << endl; return; } for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { if ((*i)->get_profile_name() == profile_name) { active_user = (*i); cout << endl; cout << profile_name; cout << " activated.\n"; cout << endl; return; } } cout << endl; cout << "Unknown user profile: "; cout << profile_name; cout << endl << endl; } bool t_userintf::exec_zrtp(const list command_list) { list al; t_zrtp_cmd zrtp_cmd = ZRTP_ENCRYPT; if (!parse_args(command_list, al)) { exec_command("help zrtp"); return false; } if (al.size() != 1) { exec_command("help zrtp"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 0: if (i->value == "encrypt") { zrtp_cmd = ZRTP_ENCRYPT; } else if (i->value == "go-clear") { zrtp_cmd = ZRTP_GO_CLEAR; } else if (i->value == "confirm-sas") { zrtp_cmd = ZRTP_CONFIRM_SAS; } else if (i->value == "reset-sas") { zrtp_cmd = ZRTP_RESET_SAS; } else { exec_command("help zrtp"); return false; } break; default: exec_command("help zrtp"); return false; break; } } do_zrtp(zrtp_cmd); return true; } void t_userintf::do_zrtp(t_zrtp_cmd zrtp_cmd) { switch (zrtp_cmd) { case ZRTP_ENCRYPT: phone->pub_enable_zrtp(); break; case ZRTP_GO_CLEAR: phone->pub_zrtp_request_go_clear(); break; case ZRTP_CONFIRM_SAS: phone->pub_confirm_zrtp_sas(); break; case ZRTP_RESET_SAS: phone->pub_reset_zrtp_sas_confirmation(); break; default: assert(false); } } bool t_userintf::exec_message(const list command_list) { list al; string display; string subject; string filename; string destination; string text; if (!parse_args(command_list, al)) { exec_command("help message"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 's': subject = i->value; break; case 'f': filename = i->value; break; case 'd': display = i->value; break; case 0: if (destination.empty()) { destination = i->value; } else { text = i->value; } break; default: exec_command("help message"); return false; break; } } if (destination.empty() || (text.empty() && filename.empty())) { exec_command("help message"); return false; } im::t_msg msg(text, im::MSG_DIR_OUT, im::TXT_PLAIN); msg.subject = subject; if (!filename.empty()) { t_media media("application/octet-stream"); string mime_type = mime_database->get_mimetype(filename); if (!mime_type.empty()) { media = t_media(mime_type); } msg.set_attachment(filename, media, strip_path_from_filename(filename)); } return do_message(destination, display, msg); } bool t_userintf::do_message(const string &destination, const string &display, const im::t_msg &msg) { t_url dest_url(expand_destination(active_user, destination)); if (!dest_url.is_valid()) { exec_command("help message"); return false; } (void)phone->pub_send_message(active_user, dest_url, display, msg); return true; } bool t_userintf::exec_presence(const list command_list) { list al; t_presence_state::t_basic_state basic_state = t_presence_state::ST_BASIC_OPEN; if (!parse_args(command_list, al)) { exec_command("help presence"); return false; } for (list::iterator i = al.begin(); i != al.end(); i++) { switch (i->flag) { case 'b': if (i->value == "online") { basic_state = t_presence_state::ST_BASIC_OPEN; } else if (i->value == "offline") { basic_state = t_presence_state::ST_BASIC_CLOSED; } else { exec_command("help presence"); return false; } break; default: exec_command("help presence"); return false; break; } } do_presence(basic_state); return true; } void t_userintf::do_presence(t_presence_state::t_basic_state basic_state) { phone->pub_publish_presence(active_user, basic_state); } bool t_userintf::exec_quit(const list command_list) { do_quit(); return true; } void t_userintf::do_quit(void) { end_interface = true; } bool t_userintf::exec_help(const list command_list) { list al; if (!parse_args(command_list, al)) { exec_command("help help"); return false; } if (al.size() > 1) { exec_command("help help"); return false; } do_help(al); return true; } void t_userintf::do_help(const list &al) { if (al.size() == 0) { cout << endl; cout << "call Call someone\n"; cout << "answer Answer an incoming call\n"; cout << "answerbye Answer an incoming call or end a call\n"; cout << "reject Reject an incoming call\n"; cout << "redirect Redirect an incoming call\n"; cout << "transfer Transfer a standing call\n"; cout << "bye End a call\n"; cout << "hold Put a call on-hold\n"; cout << "retrieve Retrieve a held call\n"; cout << "conference Join 2 calls in a 3-way conference\n"; cout << "mute Mute a line\n"; cout << "dtmf Send DTMF\n"; cout << "redial Repeat last call\n"; cout << "register Register your phone at a registrar\n"; cout << "deregister De-register your phone at a registrar\n"; cout << "fetch_reg Fetch registrations from registrar\n"; cout << "options\t\tGet capabilities of another SIP endpoint\n"; cout << "line Toggle between phone lines\n"; cout << "dnd Do not disturb\n"; cout << "auto_answer Auto answer\n"; cout << "user Show users / set active user\n"; #ifdef HAVE_ZRTP cout << "zrtp ZRTP command for voice encryption\n"; #endif cout << "message\t\tSend an instant message\n"; cout << "presence Publish your presence state\n"; cout << "quit Quit\n"; cout << "help Get help on a command\n"; cout << endl; return; } bool ambiguous; string c = complete_command(tolower(al.front().value), ambiguous); if (c == "call") { cout << endl; cout << "Usage:\n"; cout << "\tcall [-s subject] [-d display] [-h] dst\n"; cout << "Description:\n"; cout << "\tCall someone.\n"; cout << "Arguments:\n"; cout << "\t-s subject Add a subject header to the INVITE\n"; cout << "\t-d display Add display name to To-header\n"; cout << "\t-h Hide your identity\n"; cout << "\tdst SIP uri of party to invite\n"; cout << endl; return; } if (c == "answer") { cout << endl; cout << "Usage:\n"; cout << "\tanswer\n"; cout << "Description:\n"; cout << "\tAnswer an incoming call.\n"; cout << endl; return; } if (c == "answerbye") { cout << endl; cout << "Usage:\n"; cout << "\tanswerbye\n"; cout << "Description:\n"; cout << "\tWith this command you can answer an incoming call or\n"; cout << "\tend an established call.\n"; cout << endl; return; } if (c == "reject") { cout << endl; cout << "Usage:\n"; cout << "\treject\n"; cout << "Description:\n"; cout << "\tReject an incoming call. A 603 Decline response\n"; cout << "\twill be sent.\n"; cout << endl; return; } if (c == "redirect") { cout << endl; cout << "Usage:\n"; cout << "\tredirect [-s] [-t type] [-a on|off] [dst ... dst]\n"; cout << "Description:\n"; cout << "\tRedirect an incoming call. A 302 Moved Temporarily\n"; cout << "\tresponse will be sent.\n"; cout << "\tYou can redirect the current incoming call by specifying\n"; cout << "\tone or more destinations without any other arguments.\n"; cout << "Arguments:\n"; cout << "\t-s Show which redirections are active.\n"; cout << "\t-t type\t Type for permanent redirection of calls.\n"; cout << "\t Values: always, busy, noanswer.\n"; cout << "\t-a on|off Enable/disable permanent redirection.\n"; cout << "\t The default action is 'on'.\n"; cout << "\t You can disable all redirections with the\n"; cout << "\t 'off' action and no type.\n"; cout << "\tdst SIP uri where the call should be redirected.\n"; cout << "\t You can specify up to 5 destinations.\n"; cout << "\t The destinations will be tried in sequence.\n"; cout << "Examples:\n"; cout << "\tRedirect current incoming call to michel@twinklephone.com\n"; cout << "\tredirect michel@twinklephone.com\n"; cout << endl; cout << "\tRedirect busy calls permanently to michel@twinklephone.com\n"; cout << "\tredirect -t busy michel@twinklephone.com\n"; cout << endl; cout << "\tDisable redirection of busy calls.\n"; cout << "\tredirect -t busy -a off\n"; cout << endl; return; } if (c == "transfer") { cout << endl; cout << "Usage:\n"; cout << "\ttransfer [-c] [-l] [dst]\n"; cout << "Description:\n"; cout << "\tTransfer a standing call to another destination.\n"; cout << "\tFor a transfer with consultation, first use the -c flag with a\n"; cout << "\tdestination. This sets up the consultation call. When the\n"; cout << "\tconsulted party agrees, give the command with the -c flag once\n"; cout << "\tmore, but now without a destination. This transfers the call.\n"; cout << "Arguments:\n"; cout << "\t-c Consult destination before transferring call.\n"; cout << "\t-l Transfer call to party on other line.\n"; cout << "\tdst SIP uri of transfer destination\n"; cout << endl; return; } if (c == "bye") { cout << endl; cout << "Usage:\n"; cout << "\tbye\n"; cout << "Description:\n"; cout << "\tEnd a call.\n"; cout << "\tFor a stable call a BYE will be sent.\n"; cout << "\tIf the invited party did not yet sent a final answer,\n"; cout << "\tthen a CANCEL will be sent.\n"; cout << endl; return; } if (c == "hold") { cout << endl; cout << "Usage:\n"; cout << "\thold\n"; cout << "Description:\n"; cout << "\tPut the current call on the acitve line on-hold.\n"; cout << endl; return; } if (c == "retrieve") { cout << endl; cout << "Usage:\n"; cout << "\tretrieve\n"; cout << "Description:\n"; cout << "\tRetrieve a held call on the active line.\n"; cout << endl; return; } if (c == "conference") { cout << endl; cout << "Usage:\n"; cout << "\tconference\n"; cout << "Description:\n"; cout << "\tJoin 2 calls in a 3-way conference. Before you give this\n"; cout << "\tcommand you must have a call on each line.\n"; cout << endl; return; } if (c == "mute") { cout << endl; cout << "Usage:\n"; cout << "\tmute [-s] [-a on|off]\n"; cout << "Description:\n"; cout << "\tMute/unmute the active line.\n"; cout << "\tYou can hear the other side of the line, but they cannot\n"; cout << "\thear you.\n"; cout << "Arguments:\n"; cout << "\t-s Show if line is muted.\n"; cout << "\t-a on|off Mute/unmute.\n"; cout << "Notes:\n"; cout << "\tWithout any arguments you can toggle the status.\n"; cout << endl; return; } if (c == "dtmf") { cout << endl; cout << "Usage:\n"; cout << "\tdtmf digits\n"; cout << "Description:\n"; cout << "\tSend the digits as out-of-band DTMF telephone events "; cout << "(RFC 2833).\n"; cout << "\tThis command can only be given when a call is "; cout << "established.\n"; cout << "Arguments:\n"; cout << "\t-r Raw mode: do not convert letters to digits.\n"; cout << "\tdigits 0-9 | A-D | * | #\n"; cout << "Example:\n"; cout << "\tdtmf 1234#\n"; cout << "\tdmtf movies\n"; cout << "Notes:\n"; cout << "\tThe overdecadic digits A-D can only be sent in raw mode.\n"; cout << endl; return; } if (c == "redial") { cout << endl; cout << "Usage:\n"; cout << "\tredial\n"; cout << "Description:\n"; cout << "\tRepeat last call.\n"; cout << endl; return; } if (c == "register") { cout << endl; cout << "Usage:\n"; cout << "\tregister\n"; cout << "Description:\n"; cout << "\tRegister your phone at a registrar.\n"; cout << "Arguments:\n"; cout << "\t-a Register all enabled user profiles.\n"; cout << endl; return; } if (c == "deregister") { cout << endl; cout << "Usage:\n"; cout << "\tderegister [-a]\n"; cout << "Description:\n"; cout << "\tDe-register your phone at a registrar.\n"; cout << "Arguments:\n"; cout << "\t-a De-register all enabled user profiles.\n"; cout << "\t-d De-register all devices.\n"; cout << endl; return; } if (c == "fetch_reg") { cout << endl; cout << "Usage:\n"; cout << "\tfetch_reg\n"; cout << "Description:\n"; cout << "\tFetch current registrations from registrar.\n"; cout << endl; return; } if (c == "options") { cout << endl; cout << "Usage:\n"; cout << "\toptions [dst]\n"; cout << "Description:\n"; cout << "\tGet capabilities of another SIP endpoint.\n"; cout << "\tIf no destination is passed as an argument, then\n"; cout << "\tthe capabilities of the far-end in the current call\n"; cout << "\ton the active line are requested.\n"; cout << "Arguments:\n"; cout << "\tdst SIP uri of end-point\n"; cout << endl; return; } if (c == "line") { cout << endl; cout << "Usage:\n"; cout << "\tline [lineno]\n"; cout << "Description:\n"; cout << "\tIf no argument is passed then the current active "; cout << "line is shown\n"; cout << "\tOtherwise switch to another line. If the current active\n"; cout << "\thas a call, then this call will be put on-hold.\n"; cout << "\tIf the new active line has a held call, then this call\n"; cout << "\twill be retrieved.\n"; cout << "Arguments:\n"; cout << "\tlineno Switch to another line (values = "; cout << "1,2)\n"; cout << endl; return; } if (c == "dnd") { cout << endl; cout << "Usage:\n"; cout << "\tdnd [-s] [-a on|off]\n"; cout << "Description:\n"; cout << "\tEnable/disable the do not disturb service.\n"; cout << "\tIf dnd is enabled then a 480 Temporarily Unavailable "; cout << "response is given\n"; cout << "\ton incoming calls.\n"; cout << "Arguments:\n"; cout << "\t-s Show if dnd is active.\n"; cout << "\t-a on|off Enable/disable dnd.\n"; cout << "Notes:\n"; cout << "\tWithout any arguments you can toggle the status.\n"; cout << endl; return; } if (c == "auto_answer") { cout << endl; cout << "Usage:\n"; cout << "\tauto_answer [-s] [-a on|off]\n"; cout << "Description:\n"; cout << "\tEnable/disable the auto answer service.\n"; cout << "Arguments:\n"; cout << "\t-s Show if auto answer is active.\n"; cout << "\t-a on|off Enable/disable auto answer.\n"; cout << "Notes:\n"; cout << "\tWithout any arguments you can toggle the status.\n"; cout << endl; return; } if (c == "user") { cout << endl; cout << "Usage:\n"; cout << "\tuser [profile name]\n"; cout << "Description:\n"; cout << "\tMake a user profile the active profile.\n"; cout << "\tCommands like 'invite' are executed for the active profile.\n"; cout << "\tWithout an argument this command lists all users. The active\n"; cout << "\tuser will be marked with '*'.\n"; cout << "Arguments:\n"; cout << "\tprofile name The user profile to activate.\n"; cout << endl; return; } #ifdef HAVE_ZRTP if (c == "zrtp") { cout << endl; cout << "Usage:\n"; cout << "\tzrtp \n"; cout << "Description:\n"; cout << "\tExecute a ZRTP command.\n"; cout << "ZRTP commands:\n"; cout << "\tencrypt Start ZRTP negotiation for encryption.\n"; cout << "\tgo-clear Send ZRTP go-clear request.\n"; cout << "\tconfirm-sas Confirm the SAS value.\n"; cout << "\treset-sas Reset SAS confirmation.\n"; cout << endl; return; } #endif if (c == "message") { cout << endl; cout << "Usage:\n"; cout << "\tmessage [-s subject] [-f file name] [-d display] dst [text]\n"; cout << "Description:\n"; cout << "\tSend an instant message.\n"; cout << "Arguments:\n"; cout << "\t-s subject Subject of the message.\n"; cout << "\t-f file name File name of the file to send.\n"; cout << "\t-d display Add display name to To-header\n"; cout << "\tdst SIP uri of party to message\n"; cout << "\ttext Message text to send. Surround with double quotes\n"; cout << "\t\t\twhen your text contains whitespace.\n"; cout << "\t\t\tWhen you send a file, then the text is ignored.\n"; cout << endl; return; } if (c == "presence") { cout << endl; cout << "Usage:\n"; cout << "\tpresence -b [online|offline]\n"; cout << "Description:\n"; cout << "\tPublish your presence state to a presence agent\n"; cout << "Arguments:\n"; cout << "\t-b A basic presence state: online or offline\n"; cout << endl; return; } if (c == "quit") { cout << endl; cout << "Usage:\n"; cout << "\tquit\n"; cout << "Description:\n"; cout << "\tQuit.\n"; cout << endl; return; } if (c == "help") { cout << endl; cout << "Usage:\n"; cout << "\thelp [command]\n"; cout << "Description:\n"; cout << "\tShow help on a command.\n"; cout << "Arguments:\n"; cout << "\tcommand Command you want help with\n"; cout << endl; return; } cout << endl; cout << "\nUnknown command\n\n"; cout << endl; } ///////////////////////////// // Public ///////////////////////////// t_userintf::t_userintf(t_phone *_phone) { phone = _phone; end_interface = false; tone_gen = NULL; active_user = NULL; use_stdout = true; throttle_dtmf_not_supported = false; thr_process_events = NULL; all_commands.push_back("invite"); all_commands.push_back("call"); all_commands.push_back("answer"); all_commands.push_back("answerbye"); all_commands.push_back("reject"); all_commands.push_back("redirect"); all_commands.push_back("bye"); all_commands.push_back("hold"); all_commands.push_back("retrieve"); all_commands.push_back("refer"); all_commands.push_back("transfer"); all_commands.push_back("conference"); all_commands.push_back("mute"); all_commands.push_back("dtmf"); all_commands.push_back("redial"); all_commands.push_back("register"); all_commands.push_back("deregister"); all_commands.push_back("fetch_reg"); all_commands.push_back("options"); all_commands.push_back("line"); all_commands.push_back("dnd"); all_commands.push_back("auto_answer"); all_commands.push_back("user"); #ifdef HAVE_ZRTP all_commands.push_back("zrtp"); #endif all_commands.push_back("message"); all_commands.push_back("presence"); all_commands.push_back("quit"); all_commands.push_back("exit"); all_commands.push_back("q"); all_commands.push_back("x"); all_commands.push_back("help"); all_commands.push_back("h"); all_commands.push_back("?"); } t_userintf::~t_userintf() { if (tone_gen) { MEMMAN_DELETE(tone_gen); delete tone_gen; } if (thr_process_events) { evq_ui_events.push_quit(); thr_process_events->join(); log_file->write_report("thr_process_events stopped.", "t_userintf::~t_userintf", LOG_NORMAL, LOG_DEBUG); MEMMAN_DELETE(thr_process_events); delete thr_process_events; } } string t_userintf::complete_command(const string &c, bool &ambiguous) { ambiguous = false; string full_command; for (list::const_iterator i = all_commands.begin(); i != all_commands.end(); i++) { // If there is an exact match, then this is the command. // This allows a one command to be a prefix of another command. if (c == *i) { ambiguous = false; return c; } if (c.size() < i->size() && c == i->substr(0, c.size())) { if (full_command != "") { ambiguous = true; // Do not return here, as there might still be // an exact match. } full_command = *i; } } if (ambiguous) return ""; return full_command; } bool t_userintf::exec_command(const string &command_line, bool immediate) { vector v = split_ws(command_line, true); if (v.size() == 0) return false; bool ambiguous; string command = complete_command(tolower(v[0]), ambiguous); if (ambiguous) { if (use_stdout) { cout << endl; cout << "Ambiguous command\n"; cout << endl; } return false; } list l(v.begin(), v.end()); if (command == "invite") return exec_invite(l, immediate); if (command == "call") return exec_invite(l, immediate); if (command == "answer") return exec_answer(l); if (command == "answerbye") return exec_answerbye(l); if (command == "reject") return exec_reject(l); if (command == "redirect") return exec_redirect(l, immediate); if (command == "bye") return exec_bye(l); if (command == "hold") return exec_hold(l); if (command == "retrieve") return exec_retrieve(l); if (command == "refer") return exec_refer(l, immediate); if (command == "transfer") return exec_refer(l, immediate); if (command == "conference") return exec_conference(l); if (command == "mute") return exec_mute(l); if (command == "dtmf") return exec_dtmf(l); if (command == "redial") return exec_redial(l); if (command == "register") return exec_register(l); if (command == "deregister") return exec_deregister(l); if (command == "fetch_reg") return exec_fetch_registrations(l); if (command == "options") return exec_options(l, immediate); if (command == "line") return exec_line(l); if (command == "dnd") return exec_dnd(l); if (command == "auto_answer") return exec_auto_answer(l); if (command == "user") return exec_user(l); #ifdef HAVE_ZRTP if (command == "zrtp") return exec_zrtp(l); #endif if (command == "message") return exec_message(l); if (command == "presence") return exec_presence(l); if (command == "quit") return exec_quit(l); if (command == "exit") return exec_quit(l); if (command == "x") return exec_quit(l); if (command == "q") return exec_quit(l); if (command == "help") return exec_help(l); if (command == "h") return exec_help(l); if (command == "?") return exec_help(l); if (use_stdout) { cout << endl; cout << "Unknown command\n"; cout << endl; } return false; } string t_userintf::format_sip_address(t_user *user_config, const string &display, const t_url &uri) const { string s; if (uri.encode() == ANONYMOUS_URI) { return TRANSLATE("Anonymous"); } s = display; if (display != "") s += " <"; string number; if (uri.get_scheme() == "tel") { number = uri.get_host(); } else { number = uri.get_user(); } if (user_config->get_display_useronly_phone() && uri.is_phone(user_config->get_numerical_user_is_phone(), user_config->get_special_phone_symbols())) { // Display telephone number only s += user_config->convert_number(number); } else { // Display full URI // Convert the username according to the number conversion // rules. t_url u(uri); string username = user_config->convert_number(number); if (username != number) { if (uri.get_scheme() == "tel") { u.set_host(username); } else { u.set_user(username); } } s += u.encode_no_params_hdrs(false); } if (display != "") s += ">"; return s; } list t_userintf::format_warnings(const t_hdr_warning &hdr_warning) const { string s; list l; for (list::const_iterator i = hdr_warning.warnings.begin(); i != hdr_warning.warnings.end(); i++) { s = TRANSLATE("Warning:"); s += " "; s += int2str(i->code); s += ' '; s += i->text; s += " ("; s += i->host; if (i->port > 0) s += int2str(i->port, ":%d"); s += ')'; l.push_back(s); } return l; } string t_userintf::format_codec(t_audio_codec codec) const { switch (codec) { case CODEC_NULL: return "null"; case CODEC_UNSUPPORTED: return "???"; case CODEC_G711_ALAW: return "g711a"; case CODEC_G711_ULAW: return "g711u"; case CODEC_GSM: return "gsm"; case CODEC_SPEEX_NB: return "spx-nb"; case CODEC_SPEEX_WB: return "spx-wb"; case CODEC_SPEEX_UWB: return "spx-uwb"; case CODEC_ILBC: return "ilbc"; case CODEC_G726_16: return "g726-16"; case CODEC_G726_24: return "g726-24"; case CODEC_G726_32: return "g726-32"; case CODEC_G726_40: return "g726-40"; default: return "???"; } } void t_userintf::run(void) { // Start asynchronous event processor thr_process_events = new t_thread(process_events_main, NULL); MEMMAN_NEW(thr_process_events); list user_list = phone->ref_users(); active_user = user_list.front(); cout << PRODUCT_NAME << " " << PRODUCT_VERSION << ", " << PRODUCT_DATE; cout << endl; cout << "Copyright (C) 2005-2009 " << PRODUCT_AUTHOR << endl; cout << endl; cout << "Users:"; exec_command("user"); cout << "Local IP: " << user_host << endl; cout << endl; restore_state(); // Initialize phone functions phone->init(); //Initialize GNU readline functions rl_attempted_completion_function = tw_completion; using_history(); read_history(sys_config->get_history_file().c_str()); stifle_history(CLI_MAX_HISTORY_LENGTH); while (!end_interface) { char *command_line = tw_readline(CLI_PROMPT); if (!command_line){ cout << endl; break; } exec_command(command_line); } // Terminate phone functions write_history(sys_config->get_history_file().c_str()); phone->terminate(); save_state(); cout << endl; } void t_userintf::process_events(void) { t_event *event; t_event_ui *ui_event; bool quit = false; while (!quit) { event = evq_ui_events.pop(); switch (event->get_type()) { case EV_UI: ui_event = dynamic_cast(event); assert(ui_event); ui_event->exec(this); break; case EV_QUIT: quit = true; break; default: assert(false); break; } MEMMAN_DELETE(event); delete event; } } void t_userintf::save_state(void) { string err_msg; sys_config->set_redial_url(last_called_url); sys_config->set_redial_display(last_called_display); sys_config->set_redial_subject(last_called_subject); sys_config->set_redial_profile(last_called_profile); sys_config->set_redial_hide_user(last_called_hide_user); sys_config->write_config(err_msg); } void t_userintf::restore_state(void) { last_called_url = sys_config->get_redial_url(); last_called_display = sys_config->get_redial_display(); last_called_subject = sys_config->get_redial_subject(); last_called_profile = sys_config->get_redial_profile(); last_called_hide_user = sys_config->get_redial_hide_user(); } void t_userintf::lock(void) { assert(!is_prohibited_thread()); // TODO: lock for CLI } void t_userintf::unlock(void) { // TODO: lock for CLI } string t_userintf::select_network_intf(void) { string ip; list *l = get_interfaces(); // As memman has no hooks in the socket routines, report it here. MEMMAN_NEW(l); if (l->size() == 0) { // cout << "Cannot find a network interface\n"; cout << "Cannot find a network interface. Twinkle will use\n" "127.0.0.1 as the local IP address. When you connect to\n" "the network you have to restart Twinkle to use the correct\n" "IP address.\n"; MEMMAN_DELETE(l); delete l; return "127.0.0.1"; } if (l->size() == 1) { ip = l->front().get_ip_addr(); } else { size_t num = 1; cout << "Multiple network interfaces found.\n"; for (list::iterator i = l->begin(); i != l->end(); i++) { cout << num << ") " << i->name << ": "; cout << i->get_ip_addr() << endl; num++; } cout << endl; size_t selection = 0; while (selection < 1 || selection > l->size()) { cout << "Which interface do you want to use (enter number): "; string choice; getline(cin, choice); selection = atoi(choice.c_str()); } num = 1; for (list::iterator i = l->begin(); i != l->end(); i++) { if (num == selection) { ip = i->get_ip_addr(); break; } num++; } } MEMMAN_DELETE(l); delete l; return ip; } bool t_userintf::select_user_config(list &config_files) { // In CLI mode, simply select the default config file config_files.clear(); config_files.push_back(USER_CONFIG_FILE); return true; } void t_userintf::cb_incoming_call(t_user *user_config, int line, const t_request *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "incoming call\n"; cout << "From:\t\t"; string from_party = format_sip_address(user_config, r->hdr_from.get_display_presentation(), r->hdr_from.uri); cout << from_party << endl; if (r->hdr_organization.is_populated()) { cout << "Organization:\t" << r->hdr_organization.name << endl; } cout << "To:\t\t"; cout << format_sip_address(user_config, r->hdr_to.display, r->hdr_to.uri) << endl; if (r->hdr_referred_by.is_populated()) { cout << "Referred-by:\t"; cout << format_sip_address(user_config, r->hdr_referred_by.display, r->hdr_referred_by.uri); cout << endl; } if (r->hdr_subject.is_populated()) { cout << "Subject:\t" << r->hdr_subject.subject << endl; } cout << endl; cout.flush(); cb_notify_call(line, from_party); } void t_userintf::cb_call_cancelled(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "far end cancelled call.\n"; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_far_end_hung_up(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "far end ended call.\n"; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_answer_timeout(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "answer timeout.\n"; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_sdp_answer_not_supported(int line, const string &reason) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "SDP answer from far end not supported.\n"; cout << reason << endl; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_sdp_answer_missing(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "SDP answer from far end missing.\n"; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_unsupported_content_type(int line, const t_sip_message *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "Unsupported content type in answer from far end.\n"; cout << r->hdr_content_type.media.type << "/"; cout << r->hdr_content_type.media.subtype << endl; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_ack_timeout(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "no ACK received, call will be terminated.\n"; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_100rel_timeout(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": "; cout << "no PRACK received, call will be terminated.\n"; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_prack_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": PRACK failed.\n"; cout << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); cb_stop_call_notification(line); } void t_userintf::cb_provisional_resp_invite(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": received "; cout << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_cancel_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": cancel failed.\n"; cout << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_call_answered(t_user *user_config, int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": far end answered call.\n"; cout << r->code << ' ' << r->reason << endl; cout << "To: "; cout << format_sip_address(user_config, r->hdr_to.display, r->hdr_to.uri) << endl; if (r->hdr_organization.is_populated()) { cout << "Organization: " << r->hdr_organization.name << endl; } cout << endl; cout.flush(); } void t_userintf::cb_call_failed(t_user *user_config, int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call failed.\n"; cout << r->code << ' ' << r->reason << endl; // Warnings if (r->hdr_warning.is_populated()) { list l = format_warnings(r->hdr_warning); for (list::iterator i = l.begin(); i != l.end(); i++) { cout << *i << endl; } } // Redirection response if (r->get_class() == R_3XX && r->hdr_contact.is_populated()) { list l = r->hdr_contact.contact_list; l.sort(); cout << "You can try the following contacts:\n"; for (list::iterator i = l.begin(); i != l.end(); i++) { cout << format_sip_address(user_config, i->display, i->uri) << endl; } } // Unsupported extensions if (r->code == R_420_BAD_EXTENSION) { cout << r->hdr_unsupported.encode(); } cout << endl; cout.flush(); } void t_userintf::cb_stun_failed_call_ended(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call failed.\n"; cout << endl; cout.flush(); } void t_userintf::cb_call_ended(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call ended.\n"; cout.flush(); } void t_userintf::cb_call_established(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call established.\n"; cout << endl; cout.flush(); } void t_userintf::cb_options_response(const t_response *r) { cout << endl; cout << "OPTIONS response received: "; cout << r->code << ' ' << r->reason << endl; cout << "Capabilities of " << r->hdr_to.uri.encode() << endl; cout << "Accepted body types\n"; if (r->hdr_accept.is_populated()) { cout << "\t" << r->hdr_accept.encode(); } else { cout << "\tUnknown\n"; } cout << "Accepted encodings\n"; if (r->hdr_accept_encoding.is_populated()) { cout << "\t" << r->hdr_accept_encoding.encode(); } else { cout << "\tUnknown\n"; } cout << "Accepted languages\n"; if (r->hdr_accept_language.is_populated()) { cout << "\t" << r->hdr_accept_language.encode(); } else { cout << "\tUnknown\n"; } cout << "Allowed requests\n"; if (r->hdr_allow.is_populated()) { cout << "\t" << r->hdr_allow.encode(); } else { cout << "\tUnknown\n"; } cout << "Supported extensions\n"; if (r->hdr_supported.is_populated()) { if (r->hdr_supported.features.empty()) { cout << "\tNone\n"; } else { cout << "\t" << r->hdr_supported.encode(); } } else { cout << "\tUnknown\n"; } cout << "End point type\n"; bool endpoint_known = false; if (r->hdr_server.is_populated()) { cout << "\t" << r->hdr_server.encode(); endpoint_known = true; } if (r->hdr_user_agent.is_populated()) { // Some end-point put a User-Agent header in the response // instead of a Server header. cout << "\t" << r->hdr_user_agent.encode(); endpoint_known = true; } if (!endpoint_known) { cout << "\tUnknown\n"; } cout << endl; cout.flush(); } void t_userintf::cb_reinvite_success(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": re-INVITE successful.\n"; cout << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_reinvite_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": re-INVITE failed.\n"; cout << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_retrieve_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; // The status code from the response has already been reported // by cb_reinvite_failed. cout << endl; cout << "Line " << line + 1 << ": retrieve failed.\n"; cout << endl; cout.flush(); } void t_userintf::cb_invalid_reg_resp(t_user *user_config, const t_response *r, const string &reason) { cout << endl; cout << user_config->get_profile_name(); cout << ", registration failed: " << r->code << ' ' << r->reason << endl; cout << reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_register_success(t_user *user_config, const t_response *r, unsigned long expires, bool first_success) { // Only report success if this is the first success in a sequence if (!first_success) return; cout << endl; cout << user_config->get_profile_name(); cout << ": registration succeeded (expires = " << expires << " seconds)\n"; // Date at registrar if (r->hdr_date.is_populated()) { cout << "Registrar "; cout << r->hdr_date.encode() << endl; } cout << endl; cout.flush(); } void t_userintf::cb_register_failed(t_user *user_config, const t_response *r, bool first_failure) { // Only report the first failure in a sequence of failures if (!first_failure) return; cout << endl; cout << user_config->get_profile_name(); cout << ", registration failed: " << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_register_stun_failed(t_user *user_config, bool first_failure) { // Only report the first failure in a sequence of failures if (!first_failure) return; cout << endl; cout << user_config->get_profile_name(); cout << ", registration failed: STUN failure"; cout << endl; cout.flush(); } void t_userintf::cb_deregister_success(t_user *user_config, const t_response *r) { cout << endl; cout << user_config->get_profile_name(); cout << ", de-registration succeeded: " << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_deregister_failed(t_user *user_config, const t_response *r) { cout << endl; cout << user_config->get_profile_name(); cout << ", de-registration failed: " << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_fetch_reg_failed(t_user *user_config, const t_response *r) { cout << endl; cout << user_config->get_profile_name(); cout << ", fetch registrations failed: " << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_fetch_reg_result(t_user *user_config, const t_response *r) { cout << endl; cout << user_config->get_profile_name(); const list &l = r->hdr_contact.contact_list; if (l.size() == 0) { cout << ": you are not registered\n"; } else { cout << ": you have the following registrations\n"; for (list::const_iterator i = l.begin(); i != l.end(); i++) { cout << i->encode() << endl; } } cout << endl; cout.flush(); } void t_userintf::cb_register_inprog(t_user *user_config, t_register_type register_type) { switch (register_type) { case REG_REGISTER: // Do not report a register refreshment if (phone->get_is_registered(user_config)) return; // Do not report an automatic register re-attempt if (phone->get_last_reg_failed(user_config)) return; cout << endl; cout << user_config->get_profile_name(); cout << ": registering phone...\n"; break; case REG_DEREGISTER: cout << endl; cout << user_config->get_profile_name(); cout << ": deregistering phone...\n"; break; case REG_DEREGISTER_ALL: cout << endl; cout << user_config->get_profile_name(); cout << ": deregistering all phones..."; break; case REG_QUERY: cout << endl; cout << user_config->get_profile_name(); cout << ": fetching registrations..."; break; default: assert(false); } cout << endl; cout.flush(); } void t_userintf::cb_redirecting_request(t_user *user_config, int line, const t_contact_param &contact) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": redirecting request to:\n"; cout << format_sip_address(user_config, contact.display, contact.uri) << endl; cout << endl; cout.flush(); } void t_userintf::cb_redirecting_request(t_user *user_config, const t_contact_param &contact) { cout << endl; cout << "Redirecting request to: "; cout << format_sip_address(user_config, contact.display, contact.uri) << endl; cout << endl; cout.flush(); } void t_userintf::cb_play_ringtone(int line) { if (!sys_config->get_play_ringtone()) return; if (tone_gen) { tone_gen->stop(); MEMMAN_DELETE(tone_gen); delete tone_gen; } // Determine ring tone string ringtone_file = phone->get_ringtone(line); tone_gen = new t_tone_gen(ringtone_file, sys_config->get_dev_ringtone()); MEMMAN_NEW(tone_gen); // If ring tone does not exist, then fall back to system default. if (!tone_gen->is_valid() && ringtone_file != FILE_RINGTONE) { MEMMAN_DELETE(tone_gen); delete tone_gen; tone_gen = new t_tone_gen(FILE_RINGTONE, sys_config->get_dev_ringtone()); MEMMAN_NEW(tone_gen); } // Play ring tone tone_gen->start_play_thread(true, INTERVAL_RINGTONE); } void t_userintf::cb_play_ringback(t_user *user_config) { if (!sys_config->get_play_ringback()) return; if (tone_gen) { tone_gen->stop(); MEMMAN_DELETE(tone_gen); delete tone_gen; } // Determine ring back tone string ringback_file; if (!user_config->get_ringback_file().empty()) { ringback_file = user_config->get_ringback_file(); } else if (!sys_config->get_ringback_file().empty()) { ringback_file = sys_config->get_ringback_file(); } else { // System default ringback_file = FILE_RINGBACK; } tone_gen = new t_tone_gen(ringback_file, sys_config->get_dev_speaker()); MEMMAN_NEW(tone_gen); // If ring back tone does not exist, then fall back to system default. if (!tone_gen->is_valid() && ringback_file != FILE_RINGBACK) { MEMMAN_DELETE(tone_gen); delete tone_gen; tone_gen = new t_tone_gen(FILE_RINGBACK, sys_config->get_dev_speaker()); MEMMAN_NEW(tone_gen); } // Play ring back tone tone_gen->start_play_thread(true, INTERVAL_RINGBACK); } void t_userintf::cb_stop_tone(int line) { // Only stop the tone if the current line is the active line if (line != phone->get_active_line()) return; if (!tone_gen) return; tone_gen->stop(); MEMMAN_DELETE(tone_gen); delete tone_gen; tone_gen = NULL; } void t_userintf::cb_notify_call(int line, string from_party) { // Play ringtone if the call is received on the active line if (line == phone->get_active_line() && !phone->is_line_auto_answered(line)) { cb_play_ringtone(line); } } void t_userintf::cb_stop_call_notification(int line) { cb_stop_tone(line); } void t_userintf::cb_dtmf_detected(int line, char dtmf_event) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": DTMF detected: "; if (VALID_DTMF_EV(dtmf_event)) { cout << dtmf_ev2char(dtmf_event) << endl; } else { cout << "invalid DTMF telephone event (" << (int)dtmf_event << endl; } cout << endl; cout.flush(); } void t_userintf::cb_async_dtmf_detected(int line, char dtmf_event) { if (line >= NUM_USER_LINES) return; t_event_ui *event = new t_event_ui(TYPE_UI_CB_DTMF_DETECTED); MEMMAN_NEW(event); event->set_line(line); event->set_dtmf_event(dtmf_event); evq_ui_events.push(event); } void t_userintf::cb_send_dtmf(int line, char dtmf_event) { // No feed back in CLI } void t_userintf::cb_async_send_dtmf(int line, char dtmf_event) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_SEND_DTMF); MEMMAN_NEW(event); event->set_line(line); event->set_dtmf_event(dtmf_event); evq_ui_events.push(event); } void t_userintf::cb_dtmf_not_supported(int line) { if (line >= NUM_USER_LINES) return; if (throttle_dtmf_not_supported) return; cout << endl; cout << "Line " << line + 1 << ": far end does not support DTMF events.\n"; cout << endl; cout.flush(); // Throttle subsequent call backs throttle_dtmf_not_supported = true; } void t_userintf::cb_dtmf_supported(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": far end supports DTMF telephone event.\n"; cout << endl; cout.flush(); } void t_userintf::cb_line_state_changed(void) { // Nothing to do for CLI } void t_userintf::cb_async_line_state_changed(void) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_LINE_STATE_CHANGED); MEMMAN_NEW(event); evq_ui_events.push(event); } void t_userintf::cb_send_codec_changed(int line, t_audio_codec codec) { // No feedback in CLI } void t_userintf::cb_recv_codec_changed(int line, t_audio_codec codec) { // No feedback in CLI } void t_userintf::cb_async_recv_codec_changed(int line, t_audio_codec codec) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_RECV_CODEC_CHANGED); MEMMAN_NEW(event); event->set_line(line); event->set_codec(codec); evq_ui_events.push(event); } void t_userintf::cb_notify_recvd(int line, const t_request *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": received notification.\n"; cout << "Event: " << r->hdr_event.event_type << endl; cout << "State: " << r->hdr_subscription_state.substate << endl; if (r->hdr_subscription_state.substate == SUBSTATE_TERMINATED) { cout << "Reason: " << r->hdr_subscription_state.reason << endl; } t_response *sipfrag = (t_response *)((t_sip_body_sipfrag *)r->body)->sipfrag; cout << "Progress: " << sipfrag->code << ' ' << sipfrag->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_refer_failed(int line, const t_response *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": refer request failed.\n"; cout << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_refer_result_success(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call succesfully referred.\n"; cout << endl; cout.flush(); } void t_userintf::cb_refer_result_failed(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call refer failed.\n"; cout << endl; cout.flush(); } void t_userintf::cb_refer_result_inprog(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": call refer in progress.\n"; cout << "No further notifications will be received.\n"; cout << endl; cout.flush(); } void t_userintf::cb_call_referred(t_user *user_config, int line, t_request *r) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": transferring call to "; cout << format_sip_address(user_config, r->hdr_refer_to.display, r->hdr_refer_to.uri); cout << endl; if (r->hdr_referred_by.is_populated()) { cout << "Tranfer requested by "; cout << format_sip_address(user_config, r->hdr_referred_by.display, r->hdr_referred_by.uri); cout << endl; } cout << endl; cout.flush(); } void t_userintf::cb_retrieve_referrer(t_user *user_config, int line) { if (line >= NUM_USER_LINES) return; const t_call_info call_info = phone->get_call_info(line); cout << endl; cout << "Line " << line + 1 << ": call transfer failed.\n"; cout << "Retrieving call: \n"; cout << "From: "; cout << format_sip_address(user_config, call_info.from_display, call_info.from_uri); cout << endl; if (!call_info.from_organization.empty()) { cout << " " << call_info.from_organization; cout << endl; } cout << "To: "; cout << format_sip_address(user_config, call_info.to_display, call_info.to_uri); cout << endl; if (!call_info.to_organization.empty()) { cout << " " << call_info.to_organization; cout << endl; } cout << "Subject: "; cout << call_info.subject; cout << endl << endl; cout.flush(); } void t_userintf::cb_consultation_call_setup(t_user *user_config, int line) { if (line >= NUM_USER_LINES) return; const t_call_info call_info = phone->get_call_info(line); cout << endl; cout << "Line " << line + 1 << ": setup consultation call.\n"; cout << "From: "; cout << format_sip_address(user_config, call_info.from_display, call_info.from_uri); cout << endl; if (!call_info.from_organization.empty()) { cout << " " << call_info.from_organization; cout << endl; } cout << "To: "; cout << format_sip_address(user_config, call_info.to_display, call_info.to_uri); cout << endl; if (!call_info.to_organization.empty()) { cout << " " << call_info.to_organization; cout << endl; } cout << "Subject: "; cout << call_info.subject; cout << endl << endl; cout.flush(); } void t_userintf::cb_stun_failed(t_user *user_config, int err_code, const string &err_reason) { cout << endl; cout << user_config->get_profile_name(); cout << ", STUN request failed: "; cout << err_code << " " << err_reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_stun_failed(t_user *user_config) { cout << endl; cout << user_config->get_profile_name(); cout << ", STUN request failed.\n"; cout << endl; cout.flush(); } bool t_userintf::cb_ask_user_to_redirect_invite(t_user *user_config, const t_url &destination, const string &display) { // Cannot ask user for permission in CLI, so deny redirection. return false; } bool t_userintf::cb_ask_user_to_redirect_request(t_user *user_config, const t_url &destination, const string &display, t_method method) { // Cannot ask user for permission in CLI, so deny redirection. return false; } bool t_userintf::cb_ask_credentials(t_user *user_config, const string &realm, string &username, string &password) { // Cannot ask user for username/password in CLI return false; } void t_userintf::cb_ask_user_to_refer(t_user *user_config, const t_url &refer_to_uri, const string &refer_to_display, const t_url &referred_by_uri, const string &referred_by_display) { // Cannot ask user for permission in CLI, so deny REFER send_refer_permission(false); } void t_userintf::send_refer_permission(bool permission) { evq_trans_layer->push_refer_permission_response(permission); } void t_userintf::cb_show_msg(const string &msg, t_msg_priority prio) { cout << endl; switch (prio) { case MSG_NO_PRIO: break; case MSG_INFO: cout << "Info: "; break; case MSG_WARNING: cout << "Warning: "; break; case MSG_CRITICAL: cout << "Critical: "; break; default: cout << "???: "; } cout << msg << endl; cout << endl; cout.flush(); } bool t_userintf::cb_ask_msg(const string &msg, t_msg_priority prio) { // Cannot ask questions in CLI mode. // Print message and return false cb_show_msg(msg, prio); return false; } void t_userintf::cb_display_msg(const string &msg, t_msg_priority prio) { // In CLI mode this is the same as cb_show_msg cb_show_msg(msg, prio); } void t_userintf::cb_async_display_msg(const string &msg, t_msg_priority prio) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_DISPLAY_MSG); MEMMAN_NEW(event); event->set_display_msg(msg, prio); evq_ui_events.push(event); } void t_userintf::cb_log_updated(bool log_zapped) { // In CLI mode there is no log viewer. } void t_userintf::cb_call_history_updated(void) { // In CLI mode there is no call history viewer. } void t_userintf::cb_missed_call(int num_missed_calls) { // In CLI mode there is no missed call indication. } void t_userintf::cb_nat_discovery_progress_start(int num_steps) { cout << endl; cout << "Firewall/NAT discovery in progress.\n"; cout << "Please wait.\n"; cout << endl; } void t_userintf::cb_nat_discovery_finished(void) { // Nothing to do in CLI mode. } void t_userintf::cb_nat_discovery_progress_step(int step) { // Nothing to do in CLI mode. } bool t_userintf::cb_nat_discovery_cancelled(void) { // User cannot cancel NAT discovery in CLI mode. return false; } void t_userintf::cb_line_encrypted(int line, bool encrypted, const string &cipher_mode) { if (line >= NUM_USER_LINES) return; cout << endl; if (encrypted) { cout << "Line " << line + 1 << ": audio encryption enabled ("; cout << cipher_mode << ").\n"; } else { cout << "Line " << line + 1 << ": audio encryption disabled.\n"; } cout << endl; cout.flush(); } void t_userintf::cb_async_line_encrypted(int line, bool encrypted, const string &cipher_mode) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_LINE_ENCRYPTED); MEMMAN_NEW(event); event->set_line(line); event->set_encrypted(encrypted); event->set_cipher_mode(cipher_mode); evq_ui_events.push(event); } void t_userintf::cb_show_zrtp_sas(int line, const string &sas) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": ZRTP SAS = " << sas << endl; cout << "Confirm the SAS if it is correct.\n"; cout << endl; cout.flush(); } void t_userintf::cb_async_show_zrtp_sas(int line, const string &sas) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_SHOW_ZRTP_SAS); MEMMAN_NEW(event); event->set_line(line); event->set_zrtp_sas(sas); evq_ui_events.push(event); } void t_userintf::cb_zrtp_confirm_go_clear(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": remote user disabled encryption.\n"; cout << endl; cout.flush(); phone->pub_zrtp_go_clear_ok(line); } void t_userintf::cb_async_zrtp_confirm_go_clear(int line) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_ZRTP_CONFIRM_GO_CLEAR); MEMMAN_NEW(event); event->set_line(line); evq_ui_events.push(event); } void t_userintf::cb_zrtp_sas_confirmed(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": SAS confirmed.\n"; cout << endl; cout.flush(); } void t_userintf::cb_zrtp_sas_confirmation_reset(int line) { if (line >= NUM_USER_LINES) return; cout << endl; cout << "Line " << line + 1 << ": SAS confirmation reset.\n"; cout << endl; cout.flush(); } void t_userintf::cb_update_mwi(void) { // Nothing to do in CLI mode. } void t_userintf::cb_mwi_subscribe_failed(t_user *user_config, t_response *r, bool first_failure) { // Only report the first failure in a sequence of failures if (!first_failure) return; cout << endl; cout << user_config->get_profile_name(); cout << ", MWI subscription failed: " << r->code << ' ' << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_mwi_terminated(t_user *user_config, const string &reason) { cout << endl; cout << user_config->get_profile_name(); cout << ", MWI subscription terminated: " << reason << endl; cout << endl; cout.flush(); } bool t_userintf::cb_message_request(t_user *user_config, t_request *r) { cout << endl; cout << "Received message\n"; cout << "From:\t\t"; string from_party = format_sip_address(user_config, r->hdr_from.get_display_presentation(), r->hdr_from.uri); cout << from_party << endl; if (r->hdr_organization.is_populated()) { cout << "Organization:\t" << r->hdr_organization.name << endl; } cout << "To:\t\t"; cout << format_sip_address(user_config, r->hdr_to.display, r->hdr_to.uri) << endl; if (r->hdr_subject.is_populated()) { cout << "Subject:\t" << r->hdr_subject.subject << endl; } cout << endl; if (r->body && r->body->get_type() == BODY_PLAIN_TEXT) { t_sip_body_plain_text *sb = dynamic_cast(r->body); cout << sb->text << endl; } else if (r->body && r->body->get_type() == BODY_HTML_TEXT) { t_sip_body_html_text *sb = dynamic_cast(r->body); cout << sb->text << endl; } else { cout << "Unsupported content type.\n"; } cout << endl; cout.flush(); // There are no session in CLI mode, so all messages are accepted. return true; } void t_userintf::cb_message_response(t_user *user_config, t_response *r, t_request *req) { if (r->is_success()) return; cout << endl; cout << "Failed to send MESSAGE.\n"; cout << r->code << " " << r->reason << endl; cout << endl; cout.flush(); } void t_userintf::cb_im_iscomposing_request(t_user *user_config, t_request *r, im::t_composing_state state, time_t refresh) { // Nothing to do in CLI mode return; } void t_userintf::cb_im_iscomposing_not_supported(t_user *user_config, t_response *r) { // Nothing to do in CLI mode return; } bool t_userintf::get_last_call_info(t_url &url, string &display, string &subject, t_user **user_config, bool &hide_user) const { if (!last_called_url.is_valid()) return false; url = last_called_url; display = last_called_display; subject = last_called_subject; *user_config = phone->ref_user_profile(last_called_profile); hide_user = last_called_hide_user; return *user_config != NULL; } bool t_userintf::can_redial(void) const { return last_called_url.is_valid() && phone->ref_user_profile(last_called_profile) != NULL; } void t_userintf::cmd_call(const string &destination, bool immediate) { string s = "invite "; s += destination; exec_command(s); } void t_userintf::cmd_quit(void) { exec_command("quit"); } void t_userintf::cmd_quit_async(void) { t_event_ui *event = new t_event_ui(TYPE_UI_CB_QUIT); MEMMAN_NEW(event); evq_ui_events.push(event); } void t_userintf::cmd_cli(const string &command, bool immediate) { exec_command(command, immediate); } void t_userintf::cmd_show(void) { // Do nothing in CLI mode. } void t_userintf::cmd_hide(void) { // Do nothing in CLI mode. } string t_userintf::get_name_from_abook(t_user *user_config, const t_url &u) { return ab_local->find_name(user_config, u); } void *process_events_main(void *arg) { ui->process_events(); return NULL; } const list& t_userintf::get_all_commands(void) { return all_commands; } twinkle-1.4.2/src/sequence_number.h0000644000175000001440000000752411127714046014243 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Sequence number operations. */ #ifndef _SEQUENCE_NUMBER_H #define _SEQUENCE_NUMBER_H #include /** * Sequence numbers. * Sequence numbers with comparison operators that deal with sequence number * roll-overs using serial number arithmetic. * See http://en.wikipedia.org/wiki/Serial_Number_Arithmetic * * @param U The unsigned int type for the sequence number. * @param S The corresponsing signed int type having the same width. */ template< typename U, typename S > class sequence_number_t { private: /** * The sequence number. */ U _number; public: /** * Constructor. * @param number The sequence number. */ explicit sequence_number_t(U number) : _number(number) {}; /** * Get the sequence number. * @return The sequence number. */ U get_number(void) const { return _number; } /** * Cast to the sequence number. */ operator U(void) const { return get_number(); } /** * Calculate the distance to another sequence number. * @param number The sequence number to which the distance must be calculated. * @return The distance. */ S distance(const sequence_number_t &number) const { return static_cast(_number - number.get_number()); } /** * Calculate the distance to another distance sequence number. * @param number The sequence number to which the distance must be calculated. * @return The distance. */ S operator-(const sequence_number_t &number) const { return distance(number); } /** * Less-than comparison. * @param number The sequence number to compare with. * @return true, if this sequence number is less than number. * @return false, otherwise. */ bool operator<(const sequence_number_t &number) const { return (distance(number) < 0); } /** * Less-than-equal comparison. * @param number The sequence number to compare with. * @return true, if this sequence number is less than or equal to number. * @return false, otherwise. */ bool operator<=(const sequence_number_t &number) const { return (distance(number) <= 0); } /** * Equality comparison. * @param number The sequence number to compare with. * @return true, if this sequence number is equal to number. * @return false, otherwise. */ bool operator==(const sequence_number_t &number) const { return (number.get_number() == _number); } /** * Greater-than comparison. * @param number The sequence number to compare with. * @return true, if this sequence number is greater than number. * @return false, otherwise. */ bool operator>(const sequence_number_t &number) const { return (distance(number) > 0); } /** * Greater-than-equal comparison. * @param number The sequence number to compare with. * @return true, if this sequence number is greater than or equal to number. * @return false, otherwise. */ bool operator>=(const sequence_number_t &number) const { return (distance(number) >= 0); } }; /** * 16-bit sequence number */ typedef sequence_number_t seq16_t; /** * 32-bit sequence number */ typedef sequence_number_t seq32_t; #endif twinkle-1.4.2/src/phone_user.h0000644000175000001440000003475211146337135013236 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // State of active phone user #ifndef _PHONE_USER_H #define _PHONE_USER_H #include #include #include "auth.h" #include "protocol.h" #include "service.h" #include "transaction_layer.h" #include "user.h" #include "im/msg_session.h" #include "mwi/mwi.h" #include "mwi/mwi_dialog.h" #include "parser/request.h" #include "parser/response.h" #include "stun/stun.h" #include "presence/buddy.h" using namespace std; using namespace im; // Forward declarations class t_client_request; class t_presence_epa; class t_phone_user { private: t_user *user_config; // State // Indicates that this user is active. A non-active user // is not removed from the user list as some transactions may // still need the user info after the user got de-activated. bool active; // Requests outside a dialog t_client_request *r_options; t_client_request *r_register; t_client_request *r_deregister; t_client_request *r_query_register; t_client_request *r_message; // STUN request t_client_request *r_stun; /** * Pending MESSAGE requests. * Twinkle will only send one message at a time per user. * This satisfies the requirements in RFC 3428 8. * NOTE: as an optimization a message queue per destination * could be kept. This way a pending message for one destination * will not block a message for another destination. */ list pending_messages; /** @name Registration data */ //@{ string register_call_id; /**< Call-ID for REGISTER requests. */ unsigned long register_seqnr; /**< Last seqnr issued. */ bool is_registered; /**< Indicates if user is registered. */ unsigned long registration_time; /**< Expiration in seconds */ bool last_reg_failed; /** Indicates if last registration failed. */ /** Destination of last REGISTER */ t_ip_port register_ip_port; /** Service Route, collected from REGISTER responses */ list service_route; //@} // A STUN request can be triggered by the following events: // // * Registration // * MWI subscription. // // These events should take place after the STUN transaction has // finished. The following indicators indicate which events should // take place. bool register_after_stun; bool mwi_subscribe_after_stun; bool stun_binding_inuse_registration; bool stun_binding_inuse_mwi; // Authorizor t_auth authorizor; // MWI dialog t_mwi_dialog *mwi_dialog; /** * Indicates if MWI must be automatically resubscribed to, if the * subscription terminates with a reason telling that resubscription * is possible. */ bool mwi_auto_resubscribe; /** Buddy list for presence susbcriptions. */ t_buddy_list *buddy_list; /** Event publication agent for presence */ t_presence_epa *presence_epa; /** * Resend the request: a new sequence number will be assigned and a new via * header created (new transaction). * @param req [in] The request to resend. * @param is_register [in] indicates if this request is a register * @param cr [in] is the current client request wrapper for this request. * @note In case of a REGISTER, the internal register seqnr will be increased. */ void resend_request(t_request *req, bool is_register, t_client_request *cr); /** @name Handle responses. */ //@{ /** * Process a repsonse on a registration request. * @param r [in] The response. * @param re_register [out] Indicates if an automatic re-registration needs * to be done. */ void handle_response_register(t_response *r, bool &re_register); /** * Process a response on a de-registration request. * @param r [in] The response. */ void handle_response_deregister(t_response *r); /** * Process a response on a registration query request. * @param r [in] The response. */ void handle_response_query_register(t_response *r); /** * Process a response on an OPTIONS request. * @param r [in] The response. */ void handle_response_options(t_response *r); /** * Process a response on a MESSAGE request. * @param r [in] The response. */ void handle_response_message(t_response *r); //@} /** Send a NAT keep alive packet. */ void send_nat_keepalive(void); /** Send a TCP ping packet. */ void send_tcp_ping(void); /** Handle MWI dialog termination. */ void cleanup_mwi_dialog(void); /** Cleanup registration data for STUN and NAT keep alive. */ void cleanup_registration_data(void); public: /** @name Timers */ //@{ unsigned short id_registration; /**< Registration timeout */ unsigned short id_nat_keepalive; /**< NAT keepalive interval */ unsigned short id_tcp_ping; /**< TCP ping timer */ unsigned short id_resubscribe_mwi; /**< MWI re-subscribe after failure */ //@} /** Supplementary services */ t_service *service; /** Message Waiting Indication data. */ t_mwi mwi; /** @name STUN data */ //@{ bool use_stun; /**< Indicates if STUN must be used. */ bool use_nat_keepalive; /**< Send NAT keepalive ? */ unsigned long stun_public_ip_sip; /**< Public IP for SIP */ unsigned short stun_public_port_sip; /**< Public port for SIP */ /** Number of presence subscriptions using the STUN binding. */ unsigned short stun_binding_inuse_presence; /**< Subscribe to presence after STUN transaction completed. */ bool presence_subscribe_after_stun; //@} /** * The constructor will create a copy of profile. * @param profile [in] User profile of this phone user. */ t_phone_user(const t_user &profile); /** Destructor. */ ~t_phone_user(); /** Send STUN request. */ void send_stun_request(void); /** Cleanup STUN data if not in use anymore. */ void cleanup_stun_data(void); /** Stop sending NAT keep alives when not necessary anymore. */ void cleanup_nat_keepalive(void); /** * Synchronize the sending of NAT keep alives with the user config. * Start sending if keep alives are enabled but currently not being * sent. */ void sync_nat_keepalive(void); /** Stop sending TCP ping packets when not necessary anumore. */ void cleanup_tcp_ping(void); /** @name Getters */ //@{ t_user *get_user_profile(void); t_buddy_list *get_buddy_list(void); t_presence_epa *get_presence_epa(void); //@} // Handle responses for out-of-dialog requests void handle_response_out_of_dialog(t_response *r, t_tuid tuid, t_tid tid); void handle_response_out_of_dialog(StunMessage *r, t_tuid tuid); /** * Send a registration, de-registration or query registration request. * @param register_type [in] Type of registration request. * @param re_register [in] Indicates if this registration request is a re-registration. * @param expires [in] Epxiry time to put in registration request. * @note If needed a STUN request is sent before doing a registration. */ void registration(t_register_type register_type, bool re_register, unsigned long expires = 0); // OPTIONS outside dialog void options(const t_url &to_uri, const string &to_display = ""); /** @name MWI */ //@{ /** Subscribe to MWI. */ void subscribe_mwi(void); /** Unsusbcribe to MWI. */ void unsubscribe_mwi(void); /** * Check if an MWI subscription is established. * @return true, if an MWI subscription is established. * @return false, otherwise */ bool is_mwi_subscribed(void) const; /** * Check if an MWI dialog does exist. * @return true, if there is no MWI subscription dialog. * @return false, otherwise */ bool is_mwi_terminated(void) const; /** * Process an unsollicited NOTIFY for MWI. * @param r [in] The NOTIFY request. * @param tid [in] Transaction identifier of the NOTIFY transaction. */ void handle_mwi_unsollicited(t_request *r, t_tid tid); //@} /** @name Presence */ //@{ /** Subscribe to presence of buddies in buddy list. */ void subscribe_presence(void); /** Unsusbcribe to presence of buddies in buddy list. */ void unsubscribe_presence(void); /** * Check if all presence subscriptions are terminated. * @return true, if all presence subscriptions are terminated. * @return false, otherwise */ bool is_presence_terminated(void) const; /** * Publish presence. * @param basic_state [in] The basic presence state to publish. */ void publish_presence(t_presence_state::t_basic_state basic_state); /** Unpublish presence. */ void unpublish_presence(void); //@} /** * Send a text message. * @param to_uri [in] Destination URI of recipient. * @param to_display [in] Display name of recipient. * @param msg [in] The message to send. * @return True if sending succeeded, otherwise false. */ bool send_message(const t_url &to_uri, const string &to_display, const t_msg &message); /** * @param to_uri [in] Destination URI of recipient. * @param to_display [in] Display name of recipient. * @param state [in] Message composing state. * @param refresh [in] The refresh interval in seconds (when state is active). * @return True if sending succeeded, false otherwise. * @note For the idle state, the value of refresh has no meaning. */ bool send_im_iscomposing(const t_url &to_uri, const string &to_display, const string &state, time_t refresh); /** * Process incoming MESSAGE request. * @param r [in] The MESSAGE request. * @param tid [in] Transaction id of the request transaction. */ void recvd_message(t_request *r, t_tid tid); /** * Process incoming NOTIFY reqeust. * @param r [in] The NOTIFY request. * @param tid [in] Transaction id of the request transaction. */ void recvd_notify(t_request *r, t_tid tid); /** @name Process timeouts */ //@{ /** * Process phone timer expiry. * @param timer [in] Type of expired phone timer. */ void timeout(t_phone_timer timer); /** * Proces subscribe timer expiry. * @param timer [in] Type of expired subscribe timer. * @param id_timer [in] Id of expired timer. */ void timeout_sub(t_subscribe_timer timer, t_object_id id_timer); /** * Proces publish timer expiry. * @param timer [in] Type of expired subscribe timer. * @param id_timer [in] Id of expired timer. */ void timeout_publish(t_publish_timer timer, t_object_id id_timer); //@} /** Handle a broken persistent connection. */ void handle_broken_connection(void); /** Match subscribe timeout with a subcription * @param timer [in] Type of expired subscribe timer. * @param id_timer [in] Id of expired timer. * @return True if timer matches a subscription owned by the phone user. * @return False, otherwise. */ bool match_subscribe_timer(t_subscribe_timer timer, t_object_id id_timer) const; /** Match publish timeout with a subcription * @param timer [in] Type of expired publish timer. * @param id_timer [in] Id of expired timer. * @return True if timer matches a publication owned by the phone user. * @return False, otherwise. */ bool match_publish_timer(t_publish_timer timer, t_object_id id_timer) const; /** * Start the re-subscribe timer after an MWI subscription failure. * @param duration [in] Duration before trying a re-subscribe (s) */ void start_resubscribe_mwi_timer(unsigned long duration); /** Stop MWI re=subscribe timer. */ void stop_resubscribe_mwi_timer(void); /** * Create request. * Headers that are the same for each request * are already populated: Via, From, Max-Forwards, User-Agent. * All possible destinations for a failover are calculated. * @param m [in] Request method. * @param request_uri [in] Request-URI. * @return The created request. */ t_request *create_request(t_method m, const t_url &request_uri) const; // Create a response to an OPTIONS request // Argument 'in-dialog' indicates if the OPTIONS response is // sent within a dialog. t_response *create_options_response(t_request *r, bool in_dialog = false) const; // Get registration status bool get_is_registered(void) const; bool get_last_reg_failed(void) const; /** * Get local IP address for SIP. * @param auto_ip [in] IP address to use if no IP address has been determined through * some NAT procedure. * @return The IP address. */ string get_ip_sip(const string &auto_ip) const; /** * Get local port for SIP. * @return SIP port. */ unsigned short get_public_port_sip(void) const; /** * Get the service route. * @return The service route. */ list get_service_route(void) const; // Try to match message with phone user bool match(t_response *r, t_tuid tuid) const; bool match(t_request *r) const; bool match(StunMessage *r, t_tuid tuid) const; /** * Authorize the request based on the challenge in the response * @param r [inout] The request to be authorized. * @param resp [in] The response containing the challenge (401/407). * @param True if authorization succeeds, false otherwise. * @post On succesful return the request r contains the correct authorization * header (based on 401/407 response). */ bool authorize(t_request *r, t_response *resp); /** * Resend the request: a new sequence number will be assigned and a new via * header created (new transaction). * @param req [in] The request to resend. * @param cr [in] is the current client request wrapper for this request. * @note In case of a REGISTER, the internal register seqnr will be increased. */ void resend_request(t_request *req, t_client_request *cr); /** * Remove cached credentials for a particular realm. * @param realm [in] The realm. */ void remove_cached_credentials(const string &realm); /** * Check if this phone user is active. * @return True if phone user is active, false otherwise. */ bool is_active(void) const; /** * Activate phone user. * @param user [in] The user profile of the user. * @note The passed user profile will replace the current user profile * owned by phone user. During the deactivated state the profile may * have been update. */ void activate(const t_user &user); /** Deactivate phone user. */ void deactivate(void); }; #endif twinkle-1.4.2/src/id_object.cpp0000644000175000001440000000234711127714055013336 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "id_object.h" // Initialization of static members t_mutex t_id_object::mtx_next_id; t_object_id t_id_object::next_id = 1; t_id_object::t_id_object() { mtx_next_id.lock(); id = next_id++; if (next_id == 65535) next_id = 1; mtx_next_id.unlock(); } t_object_id t_id_object::get_object_id() { return id; } void t_id_object::generate_new_id() { mtx_next_id.lock(); id = next_id++; if (next_id == 65535) next_id = 1; mtx_next_id.unlock(); } twinkle-1.4.2/src/epa.cpp0000644000175000001440000003133411127714055012157 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "epa.h" #include "log.h" #include "phone.h" #include "timekeeper.h" #include "util.h" #include "audits/memman.h" extern t_phone *phone; extern t_event_queue *evq_timekeeper; extern string local_hostname; ///////////// // PRIVATE ///////////// void t_epa::enqueue_request(t_request *r) { log_file->write_header("t_epa::enqueue_request", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Enqueue request\n"); log_publication(); log_file->write_footer(); queue_publish.push(r); } ///////////// // PROTECTED ///////////// void t_epa::log_publication() const { log_file->write_raw("Event: "); log_file->write_raw(event_type); log_file->write_raw(", URI: "); log_file->write_raw(request_uri.encode()); log_file->write_raw(", SIP-ETag: "); log_file->write_raw(etag); log_file->write_endl(); } void t_epa::remove_client_request(t_client_request **cr) { if ((*cr)->dec_ref_count() == 0) { MEMMAN_DELETE(*cr); delete *cr; } *cr = NULL; } t_request *t_epa::create_publish(unsigned long expires, t_sip_body *body) const { t_user *user_config = phone_user->get_user_profile(); t_request *r = phone_user->create_request(PUBLISH, request_uri); // Call-ID r->hdr_call_id.set_call_id(NEW_CALL_ID(user_config)); // CSeq r->hdr_cseq.set_method(PUBLISH); r->hdr_cseq.set_seqnr(NEW_SEQNR); // To r->hdr_to.set_uri(user_config->create_user_uri(false)); r->hdr_to.set_display(user_config->get_display(false)); // RFC 3903 4 Expires r->hdr_expires.set_time(expires); // RFC 3903 4 Event r->hdr_event.set_event_type(event_type); // SIP-If-Match if (!etag.empty()) { r->hdr_sip_if_match.set_etag(etag); } // Body if (body) { r->body = body; r->hdr_content_type.set_media(body->get_media()); } return r; } void t_epa::send_request(t_request *r, t_tuid tuid) const { phone->send_request(phone_user->get_user_profile(), r, tuid); } void t_epa::send_publish_from_queue(void) { // If there is a PUBLISH in the queue, then send it while (!queue_publish.empty()) { log_file->write_header("t_epa::send_publish_from_queue", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Get PUBLISH from queue.\n"); log_publication(); log_file->write_footer(); t_request *req = queue_publish.front(); queue_publish.pop(); // Update the SIP-If-Match header to the current entity tag if (!etag.empty()) { req->hdr_sip_if_match.set_etag(etag); } else { req->hdr_sip_if_match.clear(); } if (req->hdr_expires.time == 0) { if (epa_state != EPA_PUBLISHED) { log_file->write_header("t_epa::send_publish_from_queue", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Nothing published, discard unpublish\n"); log_publication(); log_file->write_footer(); MEMMAN_DELETE(req); delete req; continue; } is_unpublishing = true; } else { is_unpublishing = false; } stop_timer(PUBLISH_TMR_PUBLICATION); req_out = new t_client_request(phone_user->get_user_profile(), req, 0); MEMMAN_NEW(req_out); send_request(req, req_out->get_tuid()); MEMMAN_DELETE(req); delete req; break; } } void t_epa::start_timer(t_publish_timer timer, long duration) { t_tmr_publish *t = NULL; switch(timer) { case PUBLISH_TMR_PUBLICATION: t = new t_tmr_publish(duration, timer, event_type); MEMMAN_NEW(t); id_publication_timeout = t->get_object_id(); break; default: assert(false); } evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_epa::stop_timer(t_publish_timer timer) { unsigned short *id; switch(timer) { case PUBLISH_TMR_PUBLICATION: id = &id_publication_timeout; break; default: assert(false); } if (*id != 0) evq_timekeeper->push_stop_timer(*id); *id = 0; } ////////// // PUBLIC ////////// t_epa::t_epa(t_phone_user *pu, const string &_event_type, const t_url _request_uri) : phone_user(pu), epa_state(EPA_UNPUBLISHED), event_type(_event_type), request_uri(_request_uri), id_publication_timeout(0), publication_expiry(3600), default_duration(3600), is_unpublishing(false), cached_body(NULL), req_out(NULL) {} t_epa::~t_epa() { clear(); } t_epa::t_epa_state t_epa::get_epa_state(void) const { return epa_state; } string t_epa::get_failure_msg(void) const { return failure_msg; } t_phone_user *t_epa::get_phone_user(void) const { return phone_user; } t_user *t_epa::get_user_profile(void) const { return phone_user->get_user_profile(); } bool t_epa::recv_response(t_response *r, t_tuid tuid, t_tid tid) { // Discard response if it does not match a pending request if (!req_out) return true; t_request *req = req_out->get_request(); if (r->hdr_cseq.method != req->method) return true; // Ignore provisional responses if (r->is_provisional()) return true; if (r->is_success()) { // RFC 3903 11.3 // A 2XX response must contain a SIP-ETag header if (r->hdr_sip_etag.is_populated()) { etag = r->hdr_sip_etag.etag; } else { log_file->write_report("SIP-ETag header missing from PUBLISH 2XX response.", "t_epa::recv_response", LOG_NORMAL, LOG_WARNING); etag.clear(); } // RFC 3903 1.1.1 says that the Expires header is mandatory // in a 2XX response. Some SIP servers do not include this // however. To interoperate with such servers, assume that // the granted expiry time equals the requested expiry time. if (!r->hdr_expires.is_populated()) { r->hdr_expires.set_time( req->hdr_expires.time); log_file->write_header("t_epa::recv_response", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Mandatory Expires header missing.\n"); log_file->write_raw("Assuming expires = "); log_file->write_raw(r->hdr_expires.time); log_file->write_endl(); log_publication(); log_file->write_footer(); } // If some faulty server sends a non-zero expiry time in // a response on an unsubscribe request, then ignore // the expiry time. if (r->hdr_expires.time == 0 || is_unpublishing) { // Unpublish succeeded. stop_timer(PUBLISH_TMR_PUBLICATION); etag.clear(); is_unpublishing = false; epa_state = EPA_UNPUBLISHED; log_file->write_header("t_epa::recv_response", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unpublish successful.\n"); log_publication(); log_file->write_footer(); } else { log_file->write_header("t_epa::recv_response"); log_file->write_raw("Publication sucessful.\n"); log_publication(); log_file->write_footer(); // Start/refresh publish timer stop_timer(PUBLISH_TMR_PUBLICATION); unsigned long dur = r->hdr_expires.time; dur -= dur / 10; start_timer(PUBLISH_TMR_PUBLICATION, dur * 1000); epa_state = EPA_PUBLISHED; } remove_client_request(&req_out); send_publish_from_queue(); return true; } // Authentication if (r->must_authenticate()) { if (phone_user->authorize(req, r)) { phone_user->resend_request(req, req_out); return true; } // Authentication failed // Handle the 401/407 as a normal failure response } // PUBLISH failed if (is_unpublishing) { // Unpublish failed. // There is nothing we can do about that. Just clear // the internal publication. stop_timer(PUBLISH_TMR_PUBLICATION); etag.clear(); is_unpublishing = false; epa_state = EPA_UNPUBLISHED; log_file->write_header("t_epa::recv_response", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unpublish failed.\n"); log_publication(); log_file->write_footer(); remove_client_request(&req_out); return true; } if (r->code == R_423_INTERVAL_TOO_BRIEF) { if (!r->hdr_min_expires.is_populated()) { // Violation of RFC 3261 10.3 item 7 log_file->write_report("Min-Expires header missing from 423 response.", "t_epa::recv_response", LOG_NORMAL, LOG_WARNING); } else if (r->hdr_min_expires.time <= publication_expiry) { // Wrong Min-Expires time string s = "Min-Expires ("; s += ulong2str(r->hdr_min_expires.time); s += ") is smaller than the requested "; s += "time ("; s += ulong2str(publication_expiry); s += ")"; log_file->write_report(s, "t_epa::recv_response", LOG_NORMAL, LOG_WARNING); } else { // Publish with the advised interval remove_client_request(&req_out); if (etag.empty()) { // Initial publication. publish(r->hdr_min_expires.time, cached_body); } else { publication_expiry = r->hdr_min_expires.time; refresh_publication(); } return true; } } else if (r->code == R_412_CONDITIONAL_REQUEST_FAILED) { log_file->write_header("t_epa::recv_response"); log_file->write_raw("SIP-ETag mismatch, retry with initial publication.\n"); log_publication(); log_file->write_endl(); log_file->write_footer(); // The state seems to be gone from the presence agent. Clear // the internal pubication state. remove_client_request(&req_out); etag.clear(); epa_state = EPA_UNPUBLISHED; // Retry to publish state publish(publication_expiry, cached_body); return true; } remove_client_request(&req_out); epa_state = EPA_FAILED; failure_msg = int2str(r->code); failure_msg += ' '; failure_msg += r->reason; log_file->write_header("t_epa::recv_response", LOG_NORMAL, LOG_WARNING); log_file->write_raw("PUBLISH failure response.\n"); log_file->write_raw(r->code); log_file->write_raw(" " + r->reason + "\n"); log_publication(); log_file->write_footer(); send_publish_from_queue(); return true; } bool t_epa::match_response(t_response *r, t_tuid tuid) const { return (req_out && req_out->get_tuid() == tuid); } bool t_epa::timeout(t_publish_timer timer) { switch (timer) { case PUBLISH_TMR_PUBLICATION: id_publication_timeout = 0; log_file->write_header("t_epa::timeout"); log_file->write_raw("Publication timed out.\n"); log_publication(); log_file->write_footer(); refresh_publication(); return true; default: assert(false); } return false; } bool t_epa::match_timer(t_publish_timer timer, t_object_id id_timer) const { return id_timer == id_publication_timeout; } void t_epa::publish(unsigned long expires, t_sip_body *body) { t_request *r = create_publish(expires, body); if (req_out) { // A PUBLISH request is pending, queue this one. // Only 1 PUBLISH at a time may be sent. // RFC 3903 4 enqueue_request(r); return; } // If the body equals the cached body, then do not // delete the cached_body as that will delete the body! if (cached_body && body && body != cached_body) { MEMMAN_DELETE(cached_body); delete cached_body; cached_body = NULL; } if (body) { cached_body = body->copy(); } if (expires > 0) { publication_expiry = expires; } else { publication_expiry = default_duration; } is_unpublishing = false; stop_timer(PUBLISH_TMR_PUBLICATION); req_out = new t_client_request(phone_user->get_user_profile(), r, 0); MEMMAN_NEW(req_out); send_request(r, req_out->get_tuid()); MEMMAN_DELETE(r); delete r; } void t_epa::unpublish(void) { if (!req_out && epa_state != EPA_PUBLISHED) { log_file->write_header("t_epa::unpublish", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Nothing published, discard unpublish\n"); log_publication(); log_file->write_footer(); return; } t_request *r = create_publish(0, NULL); if (req_out) { // A PUBLISH request is pending, queue this one. // Only 1 PUBLISH at a time may be sent. // RFC 3903 4 enqueue_request(r); return; } if (cached_body) { MEMMAN_DELETE(cached_body); delete cached_body; cached_body = NULL; } is_unpublishing = true; stop_timer(PUBLISH_TMR_PUBLICATION); req_out = new t_client_request(phone_user->get_user_profile(), r, 0); MEMMAN_NEW(req_out); send_request(r, req_out->get_tuid()); MEMMAN_DELETE(r); delete r; } void t_epa::refresh_publication(void) { publish(publication_expiry, NULL); } void t_epa::clear(void) { if (req_out) remove_client_request(&req_out); if (id_publication_timeout) stop_timer(PUBLISH_TMR_PUBLICATION); if (cached_body) { MEMMAN_DELETE(cached_body); delete cached_body; cached_body = NULL; } // Cleanup list of unsent PUBLISH messages while (!queue_publish.empty()) { t_request *r = queue_publish.front(); queue_publish.pop(); MEMMAN_DELETE(r); delete r; } } twinkle-1.4.2/src/log.cpp0000644000175000001440000002031111134637060012162 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "log.h" #include "sys_settings.h" #include "translator.h" #include "userintf.h" #include "user.h" #include "util.h" // Pointer allocations/de-allocations are not checked by MEMMAN as the // log file will be deleted after the MEMMAN reports are logged and hence // would show false memory leaks. extern t_userintf cli; // Main function for log viewer void *main_logview(void *arg) { while (true) { log_file->wait_for_log(); // TODO: handle situation where log file was zapped. if (ui) ui->cb_log_updated(false); } } bool t_log::move_current_to_old(void) { string old_log = log_filename + ".old"; if (rename(log_filename.c_str(), old_log.c_str()) != 0) { return false; } return true; } t_log::t_log() { log_disabled = false; log_report_disabled = false; inform_user = false; sema_logview = NULL; thr_logview = NULL; log_filename = DIR_HOME; log_filename += "/"; log_filename += DIR_USER; log_filename += "/"; log_filename += LOG_FILENAME; // If there is a previous log file, then move that to the .old file // before zapping the current log file. (void)move_current_to_old(); log_stream = new ofstream(log_filename.c_str()); if (!*log_stream) { log_disabled = true; string err = TRANSLATE("Failed to create log file %1 ."); err = replace_first(err, "%1", log_filename); err += "\nLogging is now disabled."; if (ui) ui->cb_show_msg(err, MSG_WARNING); return; } string s = PRODUCT_NAME; s += ' '; s += PRODUCT_VERSION; s += ", "; s += PRODUCT_DATE; write_report(s, "t_log::t_log"); string options_built = sys_config->get_options_built(); if (!options_built.empty()) { s = "Built with support for: "; s += options_built; write_report(s, "t_log::t_log"); } } t_log::~t_log() { if (thr_logview) delete thr_logview; if (sema_logview) delete sema_logview; delete log_stream; } void t_log::write_report(const string &report, const string &func_name) { write_report(report, func_name, LOG_NORMAL, LOG_INFO); } void t_log::write_report(const string &report, const string &func_name, t_log_class log_class, t_log_severity severity) { if (log_disabled) return; write_header(func_name, log_class, severity); write_raw(report); write_endl(); write_footer(); } void t_log::write_header(const string &func_name) { write_header(func_name, LOG_NORMAL, LOG_INFO); } void t_log::write_header(const string &func_name, t_log_class log_class, t_log_severity severity) { if (log_disabled) return; mtx_log.lock(); if (severity == LOG_DEBUG) { if (!sys_config->get_log_show_debug()) { log_report_disabled = true; return; } } switch (log_class) { case LOG_SIP: if (!sys_config->get_log_show_sip()) { log_report_disabled = true; return; } break; case LOG_STUN: if (!sys_config->get_log_show_stun()) { log_report_disabled = true; return; } break; case LOG_MEMORY: if (!sys_config->get_log_show_memory()) { log_report_disabled = true; return; } break; default: break; } struct timeval t; struct tm tm; time_t date; gettimeofday(&t, NULL); date = t.tv_sec; localtime_r(&date, &tm); *log_stream << "+++ "; *log_stream << tm.tm_mday; *log_stream << "-"; *log_stream << tm.tm_mon + 1; *log_stream << "-"; *log_stream << tm.tm_year + 1900; *log_stream << " "; *log_stream << int2str(tm.tm_hour, "%02d"); *log_stream << ":"; *log_stream << int2str(tm.tm_min, "%02d"); *log_stream << ":"; *log_stream << int2str(tm.tm_sec, "%02d"); *log_stream << "."; *log_stream << ulong2str(t.tv_usec, "%06d"); *log_stream << " "; // Severity switch (severity) { case LOG_INFO: *log_stream << "INFO"; break; case LOG_WARNING: *log_stream << "WARNING"; break; case LOG_CRITICAL: *log_stream << "CRITICAL"; break; case LOG_DEBUG: *log_stream << "DEBUG"; break; default: *log_stream << "UNNKOWN"; break; } *log_stream << " "; // Message class switch (log_class) { case LOG_NORMAL: *log_stream << "NORMAL"; break; case LOG_SIP: *log_stream << "SIP"; break; case LOG_STUN: *log_stream << "STUN"; break; case LOG_MEMORY: *log_stream << "MEMORY"; break; default: *log_stream << "UNNKOWN"; break; } *log_stream << " "; *log_stream << func_name; *log_stream << endl; } void t_log::write_footer(void) { if (log_disabled) return; if (log_report_disabled) { log_report_disabled = false; mtx_log.unlock(); return; } *log_stream << "---\n\n"; log_stream->flush(); // Check if log file is still in a good state if (!log_stream->good()) { // Log file is bad, disable logging log_disabled = true; if (ui) ui->cb_display_msg("Writing to log file failed. Logging disabled.", MSG_WARNING); mtx_log.unlock(); return; } bool log_zapped = false; if (log_stream->tellp() >= sys_config->get_log_max_size() * 1000000) { *log_stream << "*** Log full. Rotate to new log file. ***\n"; log_stream->flush(); log_stream->close(); if (!move_current_to_old()) { // Failed to move log file. Disable logging if (ui) ui->cb_display_msg("Renaming log file failed. Logging disabled.", MSG_WARNING); log_disabled = true; mtx_log.unlock(); return; } delete log_stream; log_stream = new ofstream(log_filename.c_str()); if (!*log_stream) { // Failed to create a new log file. Disable logging if (ui) ui->cb_display_msg("Creating log file failed. Logging disabled.", MSG_WARNING); log_disabled = true; mtx_log.unlock(); return; } log_zapped = true; } mtx_log.unlock(); // Inform user about log update. // This code must be outside the locked region, otherwise it causes // a deadlock between the GUI and log mutexes. if (inform_user && sema_logview) sema_logview->up(); } void t_log::write_raw(const string &raw) { if (log_disabled || log_report_disabled) return; if (raw.size() < MAX_LEN_LOG_STRING) { *log_stream << to_printable(raw); } else { *log_stream << to_printable(raw.substr(0, MAX_LEN_LOG_STRING)); *log_stream << "\n\n"; *log_stream << "\n"; } } void t_log::write_raw(int raw) { if (log_disabled || log_report_disabled) return; *log_stream << raw; } void t_log::write_raw(unsigned int raw) { if (log_disabled || log_report_disabled) return; *log_stream << raw; } void t_log::write_raw(unsigned short raw) { if (log_disabled || log_report_disabled) return; *log_stream << raw; } void t_log::write_raw(unsigned long raw) { if (log_disabled || log_report_disabled) return; *log_stream << raw; } void t_log::write_raw(long raw) { if (log_disabled || log_report_disabled) return; *log_stream << raw; } void t_log::write_bool(bool raw) { if (log_disabled || log_report_disabled) return; *log_stream << (raw ? "yes" : "no"); } void t_log::write_endl(void) { if (log_disabled || log_report_disabled) return; *log_stream << endl; } string t_log::get_filename(void) const { return log_filename; } void t_log::enable_inform_user(bool on) { if (on) { if (!sema_logview) { sema_logview = new t_semaphore(0); } if (!thr_logview) { thr_logview = new t_thread(main_logview, NULL); thr_logview->detach(); } } else { if (thr_logview) { thr_logview->cancel(); delete thr_logview; thr_logview = NULL; } if (sema_logview) { delete sema_logview; sema_logview = NULL; } } inform_user = on; } void t_log::wait_for_log(void) { if (sema_logview) sema_logview->down(); } twinkle-1.4.2/src/listener.h0000644000175000001440000000221511127714046012700 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Network listener threads */ #ifndef _H_LISTENER #define _H_LISTENER /** Thread listening on SIP UDP port */ void *listen_udp(void *arg); /** Thread listening on established TCP connections */ void *listen_for_data_tcp(void *arg); /** Thread listening for incoming TCP connection requests */ void *listen_for_conn_requests_tcp(void *arg); #endif twinkle-1.4.2/src/call_script.cpp0000644000175000001440000003045111127714055013710 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "call_script.h" #include "log.h" #include "userintf.h" #include "util.h" // Maximum length of the reason value #define MAX_LEN_REASON 50 // Script result fields #define SCR_ACTION "action" #define SCR_REASON "reason" #define SCR_CONTACT "contact" #define SCR_CALLER_NAME "caller_name" #define SCR_RINGTONE "ringtone" #define SCR_DISPLAY_MSG "display_msg" #define SCR_INTERNAL_ERROR "internal_error" // Script triggers #define SCR_TRIGGER_IN_CALL "in_call" #define SCR_TRIGGER_IN_CALL_ANSWERED "in_call_answered" #define SCR_TRIGGER_IN_CALL_FAILED "in_call_failed" #define SCR_TRIGGER_OUT_CALL "out_call" #define SCR_TRIGGER_OUT_CALL_ANSWERED "out_call_answered" #define SCR_TRIGGER_OUT_CALL_FAILED "out_call_failed" #define SCR_TRIGGER_LOCAL_RELEASE "local_release" #define SCR_TRIGGER_REMOTE_RELEASE "remote_release" ///////////////////////// // class t_script_result ///////////////////////// t_script_result::t_script_result() { clear(); } t_script_result::t_action t_script_result::str2action(const string action_string) { string s = tolower(action_string); t_action result; if (s == "continue") { result = ACTION_CONTINUE; } else if (s == "reject") { result = ACTION_REJECT; } else if (s == "dnd") { result = ACTION_DND; } else if (s == "redirect") { result = ACTION_REDIRECT; } else if (s == "autoanswer") { result = ACTION_AUTOANSWER; } else { // Unknown action result = ACTION_ERROR; } return result; } void t_script_result::clear(void) { action = ACTION_CONTINUE; reason.clear(); contact.clear(); caller_name.clear(); ringtone.clear(); display_msgs.clear(); } void t_script_result::set_parameter(const string ¶meter, const string &value) { if (parameter == SCR_ACTION) { action = str2action(value); } else if (parameter == SCR_REASON) { if (value.size() <= MAX_LEN_REASON) { reason = value; } else { reason = value.substr(0, MAX_LEN_REASON); } } else if (parameter == SCR_CONTACT) { contact = value; } else if (parameter == SCR_CALLER_NAME) { caller_name = value; } else if (parameter == SCR_RINGTONE) { ringtone = value; } else if (parameter == SCR_DISPLAY_MSG) { display_msgs.push_back(value); } // Unknown parameters are ignored } ///////////////////////// // class t_call_script ///////////////////////// string t_call_script::trigger2str(t_trigger t) const { switch (t) { case TRIGGER_IN_CALL: return SCR_TRIGGER_IN_CALL; case TRIGGER_IN_CALL_ANSWERED: return SCR_TRIGGER_IN_CALL_ANSWERED; case TRIGGER_IN_CALL_FAILED: return SCR_TRIGGER_IN_CALL_FAILED; case TRIGGER_OUT_CALL: return SCR_TRIGGER_OUT_CALL; case TRIGGER_OUT_CALL_ANSWERED: return SCR_TRIGGER_OUT_CALL_ANSWERED; case TRIGGER_OUT_CALL_FAILED: return SCR_TRIGGER_OUT_CALL_FAILED; case TRIGGER_LOCAL_RELEASE: return SCR_TRIGGER_LOCAL_RELEASE; case TRIGGER_REMOTE_RELEASE: return SCR_TRIGGER_REMOTE_RELEASE; default: return "unknown"; } } char **t_call_script::create_env(t_sip_message *m) const { string var_twinkle; // Number of existing environment variables int environ_size = 0; for (int i = 0; environ[i] != NULL; i++) { environ_size++; } // Number of SIP environment variables int start_sip_env = environ_size; // Position of SIP variables list l = m->encode_env(); var_twinkle = "SIP_FROM_USER="; var_twinkle += m->hdr_from.uri.get_user(); l.push_back(var_twinkle); var_twinkle = "SIP_FROM_HOST="; var_twinkle += m->hdr_from.uri.get_host(); l.push_back(var_twinkle); var_twinkle = "SIP_TO_USER="; var_twinkle += m->hdr_to.uri.get_user(); l.push_back(var_twinkle); var_twinkle = "SIP_TO_HOST="; var_twinkle += m->hdr_to.uri.get_host(); l.push_back(var_twinkle); environ_size += l.size(); // Number of Twinkle environment variables int start_twinkle_env = environ_size; // Position of Twinkle variables environ_size += 3; // MEMMAN not called on purpose char **env = new char *[environ_size + 1]; // Copy current environment to child for (int i = 0; environ[i] != NULL; i++) { env[i] = strdup(environ[i]); } // Add environment variables for SIP request int j = start_sip_env; for (list::iterator i = l.begin(); i != l.end(); i++, j++) { env[j] = strdup(i->c_str()); } // Add Twinkle specific environment variables var_twinkle = "TWINKLE_USER_PROFILE="; var_twinkle += user_config->get_profile_name(); env[start_twinkle_env] = strdup(var_twinkle.c_str()); var_twinkle = "TWINKLE_TRIGGER="; var_twinkle += trigger2str(trigger); env[start_twinkle_env + 1] = strdup(var_twinkle.c_str()); var_twinkle = "TWINKLE_LINE="; var_twinkle += ulong2str(line_number); env[start_twinkle_env + 2] = strdup(var_twinkle.c_str()); // Terminate array with NULL env[environ_size] = NULL; return env; } char **t_call_script::create_argv(void) const { // Determine script agument list vector arg_list = split_ws(script_command, true); // MEMMAN not called on purpose char **argv = new char *[arg_list.size() + 1]; int idx = 0; for (vector::iterator i = arg_list.begin(); i != arg_list.end(); i++, idx++) { argv[idx] = strdup(i->c_str()); } argv[arg_list.size()] = NULL; return argv; } t_call_script::t_call_script(t_user *_user_config, t_trigger _trigger, uint16 _line_number) : user_config(_user_config), trigger(_trigger), line_number(_line_number) { switch (trigger) { case TRIGGER_IN_CALL: script_command = user_config->get_script_incoming_call(); break; case TRIGGER_IN_CALL_ANSWERED: script_command = user_config->get_script_in_call_answered(); break; case TRIGGER_IN_CALL_FAILED: script_command = user_config->get_script_in_call_failed(); break; case TRIGGER_OUT_CALL: script_command = user_config->get_script_outgoing_call(); break; case TRIGGER_OUT_CALL_ANSWERED: script_command = user_config->get_script_out_call_answered(); break; case TRIGGER_OUT_CALL_FAILED: script_command = user_config->get_script_out_call_failed(); break; case TRIGGER_LOCAL_RELEASE: script_command = user_config->get_script_local_release(); break; case TRIGGER_REMOTE_RELEASE: script_command = user_config->get_script_remote_release(); break; default: script_command.clear(); break; } } void t_call_script::exec_action(t_script_result &result, t_sip_message *m) const { result.clear(); if (script_command.empty()) return; log_file->write_header("t_call_script::exec_action"); log_file->write_raw("Execute script: "); log_file->write_raw(script_command); log_file->write_raw("\nTrigger: "); log_file->write_raw(trigger2str(trigger)); log_file->write_raw("\nLine: "); log_file->write_raw(line_number); log_file->write_endl(); log_file->write_footer(); // Create pipe for communication with child process int fds[2]; if (pipe(fds) == -1) { // Failed to create pipe log_file->write_header("t_call_script::exec_action", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Failed to create pipe: "); log_file->write_raw(get_error_str(errno)); log_file->write_endl(); log_file->write_footer(); return; } // Fork child process pid_t pid = fork(); if (pid == -1) { // Failed to fork child process log_file->write_header("t_call_script::exec_action", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Failed to fork child process: "); log_file->write_raw(get_error_str(errno)); log_file->write_endl(); log_file->write_footer(); close(fds[0]); close(fds[1]); return; } else if (pid == 0) { // Child process // Close the read end of the pipe close(fds[0]); // Redirect stdout to the write end of the pipe dup2(fds[1], STDOUT_FILENO); // NOTE: MEMMAN audits are not called as all pointers will be deleted // automatically when the child process dies // Also, the child process has a copy of the MEMMAN object char **argv = create_argv(); // Determine environment char **env = create_env(m); // Replace the child process by the script if (execve(argv[0], argv, env) == -1) { // Failed to execute script. Report error to parent. string err_msg; err_msg = get_error_str(errno); err_msg += ": "; err_msg += argv[0]; cout << SCR_INTERNAL_ERROR << '=' << err_msg << endl; exit(0); } } else { // Parent process log_file->write_header("t_call_script::exec_action"); log_file->write_raw("Child process spawned, pid = "); log_file->write_raw((int)pid); log_file->write_endl(); log_file->write_footer(); // Close the write end of the pipe close(fds[1]); // Read the script results FILE *fp_result = fdopen(fds[0], "r"); if (!fp_result) { log_file->write_header("t_call_script::exec_action", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Failed to open pipe to child: "); log_file->write_raw(get_error_str(errno)); log_file->write_endl(); log_file->write_footer(); // Child will be cleaned up by phone_sigwait close(fds[0]); return; } char *line_buf = NULL; size_t line_buf_len = 0; ssize_t num_read; // Read and parse script results. while ((num_read = getline(&line_buf, &line_buf_len, fp_result)) != -1) { // Strip newline if present if (line_buf[num_read - 1] == '\n') { line_buf[num_read - 1] = 0; } // Convert the read line to a C++ string string line(line_buf); line = trim(line); // Stop reading on end command if (line == "end") break; // Skip empty lines if (line.empty()) continue; // Skip comment lines if (line[0] == '#') continue; vector v = split_on_first(line, '='); // SKip invalid lines if (v.size() != 2) continue; string parameter = trim(v[0]); string value = trim(v[1]); if (parameter == SCR_INTERNAL_ERROR) { log_file->write_report(value, "t_call_script::exec_action", LOG_NORMAL, LOG_WARNING); ui->cb_display_msg(value, MSG_WARNING); result.clear(); break; } result.set_parameter(parameter, value); } if (line_buf) free(line_buf); fclose(fp_result); close(fds[0]); // Child will be cleaned up by phone_sigwait } } void t_call_script::exec_notify(t_sip_message *m) const { if (script_command.empty()) return; log_file->write_header("t_call_script::exec_notify"); log_file->write_raw("Execute script: "); log_file->write_raw(script_command); log_file->write_raw("\nTrigger: "); log_file->write_raw(trigger2str(trigger)); log_file->write_endl(); log_file->write_footer(); // Fork child process pid_t pid = fork(); if (pid == -1) { // Failed to fork child process log_file->write_header("t_call_script::exec_notify", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Failed to fork child process: "); log_file->write_raw(get_error_str(errno)); log_file->write_endl(); log_file->write_footer(); return; } else if (pid == 0) { // Child process // NOTE: MEMMAN audits are not called as all pointers will be deleted // automatically when the child process dies // Also, the child process has a copy of the MEMMAN object char **argv = create_argv(); // Determine environment char **env = create_env(m); // Replace the child process by the script if (execve(argv[0], argv, env) == -1) { // Failed to execute script. exit(0); } } else { // Parent process log_file->write_header("t_call_script::exec_notify"); log_file->write_raw("Child process spawned, pid = "); log_file->write_raw((int)pid); log_file->write_endl(); log_file->write_footer(); // No interaction with child needed. // Child will be cleaned up by phone_sigwait } } twinkle-1.4.2/src/phone_user.cpp0000644000175000001440000013520211146337631013562 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "phone_user.h" #include "log.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" #include "im/im_iscomposing_body.h" #include "presence/presence_epa.h" extern t_phone *phone; extern t_event_queue *evq_timekeeper; extern t_event_queue *evq_sender; extern string user_host; extern string local_hostname; void t_phone_user::cleanup_mwi_dialog(void) { if (mwi_dialog && mwi_dialog->get_subscription_state() == SS_TERMINATED) { string reason_termination = mwi_dialog->get_reason_termination(); bool may_resubscribe = mwi_dialog->get_may_resubscribe(); unsigned long dur_resubscribe = mwi_dialog->get_resubscribe_after(); MEMMAN_DELETE(mwi_dialog); delete mwi_dialog; mwi_dialog = NULL; stun_binding_inuse_mwi = false; cleanup_stun_data(); cleanup_nat_keepalive(); if (mwi_auto_resubscribe) { if (may_resubscribe) { if (dur_resubscribe > 0) { start_resubscribe_mwi_timer(dur_resubscribe * 1000); } else { subscribe_mwi(); } } else if (reason_termination.empty()) { start_resubscribe_mwi_timer(DUR_MWI_FAILURE * 1000); } } } } void t_phone_user::cleanup_stun_data(void) { if (!use_stun) return; if (!stun_binding_inuse_registration && !stun_binding_inuse_mwi && stun_binding_inuse_presence == 0) { stun_public_ip_sip = 0; stun_public_port_sip = 0; } } void t_phone_user::cleanup_nat_keepalive(void) { if (register_ip_port.ipaddr == 0 && register_ip_port.port == 0 && !mwi_dialog) { if (id_nat_keepalive) phone->stop_timer(PTMR_NAT_KEEPALIVE, this); } } void t_phone_user::sync_nat_keepalive(void) { if (user_config->get_enable_nat_keepalive() && !id_nat_keepalive) { send_nat_keepalive(); phone->start_timer(PTMR_NAT_KEEPALIVE, this); } } void t_phone_user::cleanup_tcp_ping(void) { if (register_ip_port.ipaddr == 0 && register_ip_port.port == 0) { if (id_tcp_ping) phone->stop_timer(PTMR_TCP_PING, this); } } void t_phone_user::cleanup_registration_data(void) { register_ip_port.ipaddr = 0; register_ip_port.port = 0; stun_binding_inuse_registration = false; cleanup_stun_data(); cleanup_nat_keepalive(); cleanup_tcp_ping(); } t_phone_user::t_phone_user(const t_user &profile) { user_config = profile.copy(); service = new t_service(user_config); MEMMAN_NEW(service); buddy_list = new t_buddy_list(this); MEMMAN_NEW(buddy_list); presence_epa = new t_presence_epa(this); MEMMAN_NEW(presence_epa); string err_msg; if (buddy_list->load(err_msg)) { log_file->write_header("t_phone_user::t_phone_user"); log_file->write_raw(user_config->get_profile_name()); log_file->write_raw(": buddy list loaded.\n"); log_file->write_footer(); } else { log_file->write_header("t_phone_user::t_phone_user", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw(user_config->get_profile_name()); log_file->write_raw(": falied to load buddy list.\n"); log_file->write_raw(err_msg); log_file->write_endl(); log_file->write_footer(); } active = true; r_options = NULL; r_register = NULL; r_deregister = NULL; r_query_register = NULL; r_message = NULL; r_stun = NULL; // Initialize registration data // Call-ID cannot be set here as user_host is not determined yet. register_seqnr = NEW_SEQNR; is_registered = false; register_ip_port.ipaddr = 0L; register_ip_port.port = 0; last_reg_failed = false; // Initialize STUN data stun_public_ip_sip = 0L; stun_public_port_sip = 0; stun_binding_inuse_registration = false; stun_binding_inuse_mwi = false; stun_binding_inuse_presence = 0; register_after_stun = false; mwi_subscribe_after_stun = false; presence_subscribe_after_stun = false; use_stun = false; use_nat_keepalive = false; // Timers id_registration = 0; id_nat_keepalive = 0; id_tcp_ping = 0; id_resubscribe_mwi = 0; // MWI mwi_dialog = NULL; mwi_auto_resubscribe = false; } t_phone_user::~t_phone_user() { // Stop timers if (id_registration) phone->stop_timer(PTMR_REGISTRATION, this); if (id_nat_keepalive) phone->stop_timer(PTMR_NAT_KEEPALIVE, this); if (id_tcp_ping) phone->stop_timer(PTMR_TCP_PING, this); // Delete pointers if (r_options) { MEMMAN_DELETE(r_options); delete r_options; } if (r_register) { MEMMAN_DELETE(r_register); delete r_register; } if (r_deregister) { MEMMAN_DELETE(r_deregister); delete r_deregister; } if (r_query_register) { MEMMAN_DELETE(r_query_register); delete r_query_register; } if (r_message) { MEMMAN_DELETE(r_message); delete r_message; } if (r_stun) { MEMMAN_DELETE(r_stun); delete r_stun; } for (list::iterator it = pending_messages.begin(); it != pending_messages.end(); ++it) { MEMMAN_DELETE(*it); delete *it; } if (mwi_dialog) { MEMMAN_DELETE(mwi_dialog); delete mwi_dialog; } MEMMAN_DELETE(service); delete service; MEMMAN_DELETE(presence_epa); delete presence_epa; MEMMAN_DELETE(buddy_list); delete buddy_list; buddy_list = NULL; MEMMAN_DELETE(user_config); delete user_config; } t_user *t_phone_user::get_user_profile(void) { return user_config; } t_buddy_list *t_phone_user::get_buddy_list(void) { return buddy_list; } t_presence_epa *t_phone_user::get_presence_epa(void) { return presence_epa; } void t_phone_user::registration(t_register_type register_type, bool re_register, unsigned long expires) { // If STUN is enabled, then do a STUN query before registering to // determine the public IP address. if (register_type == REG_REGISTER && use_stun) { if (stun_public_ip_sip == 0) { send_stun_request(); register_after_stun = true; registration_time = expires; return; } stun_binding_inuse_registration = true; } // Stop registration timer for non-query request if (register_type != REG_QUERY) { phone->stop_timer(PTMR_REGISTRATION, this); } // Create call-id if no call-id is created yet if (register_call_id == "") { register_call_id = NEW_CALL_ID(user_config); } // RFC 3261 10.2 // Construct REGISTER request t_request *req = create_request(REGISTER, t_url(string(USER_SCHEME) + ":" + user_config->get_domain())); // To req->hdr_to.set_uri(user_config->create_user_uri(false)); req->hdr_to.set_display(user_config->get_display(false)); //Call-ID req->hdr_call_id.set_call_id(register_call_id); // CSeq req->hdr_cseq.set_method(REGISTER); req->hdr_cseq.set_seqnr(++register_seqnr); // Contact t_contact_param contact; switch (register_type) { case REG_REGISTER: // URI contact.uri.set_url(user_config->create_user_contact(false, h_ip2str(req->get_local_ip()))); // Expires if (expires > 0) { if (user_config->get_registration_time_in_contact()) { contact.set_expires(expires); } else { req->hdr_expires.set_time(expires); } } // q-value if (user_config->get_reg_add_qvalue()) { contact.set_qvalue(user_config->get_reg_qvalue()); } req->hdr_contact.add_contact(contact); break; case REG_DEREGISTER: contact.uri.set_url(user_config->create_user_contact(false, h_ip2str(req->get_local_ip()))); if (user_config->get_registration_time_in_contact()) { contact.set_expires(0); } else { req->hdr_expires.set_time(0); } req->hdr_contact.add_contact(contact); break; case REG_DEREGISTER_ALL: req->hdr_contact.set_any(); req->hdr_expires.set_time(0); break; default: break; } // Allow SET_HDR_ALLOW(req->hdr_allow, user_config); // Store request in the proper place t_tuid tuid; switch(register_type) { case REG_REGISTER: // Delete a possible pending registration request if (r_register) { MEMMAN_DELETE(r_register); delete r_register; } r_register = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_register); tuid = r_register->get_tuid(); // Store expiration time for re-registration. registration_time = expires; break; case REG_QUERY: // Delete a possible pending query registration request if (r_query_register) { MEMMAN_DELETE(r_query_register); delete r_query_register; } r_query_register = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_query_register); tuid = r_query_register->get_tuid(); break; case REG_DEREGISTER: case REG_DEREGISTER_ALL: // Delete a possible pending de-registration request if (r_deregister) { MEMMAN_DELETE(r_deregister); delete r_deregister; } r_deregister = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_deregister); tuid = r_deregister->get_tuid(); break; default: assert(false); } // Send REGISTER authorizor.set_re_register(re_register); ui->cb_register_inprog(user_config, register_type); phone->send_request(user_config, req, tuid); MEMMAN_DELETE(req); delete req; } void t_phone_user::options(const t_url &to_uri, const string &to_display) { // RFC 3261 11.1 // Construct OPTIONS request t_request *req = create_request(OPTIONS, to_uri); // To req->hdr_to.set_uri(to_uri); req->hdr_to.set_display(to_display); // Call-ID req->hdr_call_id.set_call_id(NEW_CALL_ID(user_config)); // CSeq req->hdr_cseq.set_method(OPTIONS); req->hdr_cseq.set_seqnr(NEW_SEQNR); // Accept req->hdr_accept.add_media(t_media("application","sdp")); // Store and send request // Delete a possible pending options request if (r_options) { MEMMAN_DELETE(r_options); delete r_options; } r_options = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_options); phone->send_request(user_config, req, r_options->get_tuid()); MEMMAN_DELETE(req); delete req; } void t_phone_user::handle_response_out_of_dialog(t_response *r, t_tuid tuid, t_tid tid) { t_client_request **current_cr; t_request *req; bool is_register = false; t_buddy *buddy; if (r_register && r_register->get_tuid() == tuid) { current_cr = &r_register; is_register = true; } else if (r_deregister && r_deregister->get_tuid() == tuid) { current_cr = &r_deregister; is_register = true; } else if (r_query_register && r_query_register->get_tuid() == tuid) { current_cr = &r_query_register; is_register = true; } else if (r_options && r_options->get_tuid() == tuid) { current_cr = &r_options; } else if (r_message && r_message->get_tuid() == tuid) { current_cr = &r_message; } else if (mwi_dialog && mwi_dialog->match_response(r, tuid)) { mwi_dialog->recvd_response(r, tuid, tid); cleanup_mwi_dialog(); return; } else if (presence_epa && presence_epa->match_response(r, tuid)) { presence_epa->recv_response(r, tuid, tid); return; } else if (buddy_list->match_response(r, tuid, &buddy)) { buddy->recvd_response(r, tuid, tid); if (buddy->must_delete_now()) buddy_list->del_buddy(*buddy); return; } else { // Response does not match any pending request. log_file->write_report("Response does not match any pending request.", "t_phone_user::handle_response_out_of_dialog", LOG_NORMAL, LOG_WARNING); return; } req = (*current_cr)->get_request(); // Authentication if (r->must_authenticate()) { if (authorize(req, r)) { resend_request(req, is_register, *current_cr); return; } // Authentication failed // Handle the 401/407 as a normal failure response } // RFC 3263 4.3 // Failover if (r->code == R_503_SERVICE_UNAVAILABLE) { if (req->next_destination()) { log_file->write_report("Failover to next destination.", "t_phone_user::handle_response_out_of_dialog"); resend_request(req, is_register, *current_cr); return; } } // Redirect failed request if there is another destination if (r->get_class() > R_2XX && user_config->get_allow_redirection()) { // If the response is a 3XX response then add redirection // contacts if (r->get_class() == R_3XX && r->hdr_contact.is_populated()) { (*current_cr)->redirector.add_contacts( r->hdr_contact.contact_list); } // Get next destination t_contact_param contact; if ((*current_cr)->redirector.get_next_contact(contact)) { // Ask user for permission to redirect if indicated // by user config bool permission = true; if (user_config->get_ask_user_to_redirect()) { permission = ui->cb_ask_user_to_redirect_request( user_config, contact.uri, contact.display, r->hdr_cseq.method); } if (permission) { req->uri = contact.uri; req->calc_destinations(*user_config); ui->cb_redirecting_request(user_config, contact); resend_request(req, is_register, *current_cr); return; } } } // REGISTER (register) if (r_register && r_register->get_tuid() == tuid) { bool re_register; handle_response_register(r, re_register); MEMMAN_DELETE(r_register); delete r_register; r_register = NULL; if (re_register) registration(REG_REGISTER, authorizor.get_re_register(), registration_time); return; } // REGISTER (de-register) if (r_deregister && r_deregister->get_tuid() == tuid) { handle_response_deregister(r); MEMMAN_DELETE(r_deregister); delete r_deregister; r_deregister = NULL; return; } // REGISTER (query) if (r_query_register && r_query_register->get_tuid() == tuid) { handle_response_query_register(r); MEMMAN_DELETE(r_query_register); delete r_query_register; r_query_register = NULL; return; } // OPTIONS if (r_options && r_options->get_tuid() == tuid) { handle_response_options(r); MEMMAN_DELETE(r_options); delete r_options; r_options = NULL; return; } // MESSAGE if (r_message && r_message->get_tuid() == tuid) { handle_response_message(r); MEMMAN_DELETE(r_message); delete r_message; r_message = NULL; // Send next pending MESSAGE if (!pending_messages.empty()) { t_request *req = pending_messages.front(); pending_messages.pop_front(); r_message = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_message); phone->send_request(user_config, req, r_message->get_tuid()); MEMMAN_DELETE(req); delete req; } return; } // Response does not match any pending request. Do nothing. } void t_phone_user::resend_request(t_request *req, bool is_register, t_client_request *cr) { // A new sequence number must be assigned if (is_register) { req->hdr_cseq.set_seqnr(++register_seqnr); } else { req->hdr_cseq.seqnr++; } // Create a new via-header. Otherwise the // request will be seen as a retransmission unsigned long local_ip = req->get_local_ip(); req->hdr_via.via_list.clear(); t_via via(USER_HOST(user_config, h_ip2str(local_ip)), PUBLIC_SIP_PORT(user_config)); req->hdr_via.add_via(via); cr->renew(0); phone->send_request(user_config, req, cr->get_tuid()); } void t_phone_user::handle_response_out_of_dialog(StunMessage *r, t_tuid tuid) { if (!r_stun || r_stun->get_tuid() != tuid) { // Response does not match pending STUN request return; } if (r->msgHdr.msgType == BindResponseMsg && r->hasMappedAddress) { // The STUN response contains the public IP. stun_public_ip_sip = r->mappedAddress.ipv4.addr; stun_public_port_sip = r->mappedAddress.ipv4.port; MEMMAN_DELETE(r_stun); delete r_stun; r_stun = NULL; if (register_after_stun) { register_after_stun = false; registration(REG_REGISTER, false, registration_time); } if (mwi_subscribe_after_stun) { mwi_subscribe_after_stun = false; subscribe_mwi(); } if (presence_subscribe_after_stun) { presence_subscribe_after_stun = false; buddy_list->stun_completed(); } return; } if (r->msgHdr.msgType == BindErrorResponseMsg && r->hasErrorCode) { // STUN request failed. ui->cb_stun_failed(user_config, r->errorCode.errorClass * 100 + r->errorCode.number, r->errorCode.reason); } else { // No satisfying STUN response was received. ui->cb_stun_failed(user_config); } MEMMAN_DELETE(r_stun); delete r_stun; r_stun = NULL; if (register_after_stun) { // Retry registration later. bool first_failure = !last_reg_failed; last_reg_failed = true; is_registered = false; ui->cb_register_stun_failed(user_config, first_failure); phone->start_set_timer(PTMR_REGISTRATION, DUR_REG_FAILURE * 1000, this); register_after_stun = false; } if (mwi_subscribe_after_stun) { // Retry MWI subscription later start_resubscribe_mwi_timer(DUR_MWI_FAILURE * 1000); mwi_subscribe_after_stun = false; } if (presence_subscribe_after_stun) { buddy_list->stun_failed(); presence_subscribe_after_stun = false; } } void t_phone_user::handle_response_register(t_response *r, bool &re_register) { t_contact_param *c; unsigned long expires; unsigned long e; bool first_failure, first_success; re_register = false; // Store the destination IP address/port of the REGISTER message. // To this destination the NAT keep alive packets will be sent. t_request *req = r_register->get_request(); req->get_destination(register_ip_port, *user_config); switch(r->get_class()) { case R_2XX: last_reg_failed = false; // Stop registration timer if one was running phone->stop_timer(PTMR_REGISTRATION, this); c = r->hdr_contact.find_contact(req->hdr_contact.contact_list.front().uri); if (!c) { if (!user_config->get_allow_missing_contact_reg()) { is_registered = false; log_file->write_report( "Contact header is missing.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, "Contact header missing."); cleanup_registration_data(); return; } else { log_file->write_report( "Cannot find matching contact header.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_DEBUG); } } if (c && c->is_expires_present() && c->get_expires() != 0) { expires = c->get_expires(); } else if (r->hdr_expires.is_populated() && r->hdr_expires.time != 0) { expires = r->hdr_expires.time; } else { if (!user_config->get_allow_missing_contact_reg()) { is_registered = false; log_file->write_report( "Expires parameter/header mising.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, "Expires parameter/header mising."); cleanup_registration_data(); return; } expires = user_config->get_registration_time(); // Assume a default expiration of 3600 sec if no expiry // time was returned. if (expires == 0) expires = 3600; } // Start new registration timer // The maximum value of the timer can be 2^32-1 s // The maximum timer that we can handle however is 2^31-1 ms e = (expires > 2147483 ? 2147483 : expires); phone->start_set_timer(PTMR_REGISTRATION, e * 1000, this); // Save the Service-Route if present the response contains any // RFC 3608 6 // Collect the service route to route later initial requests. if (r->hdr_service_route.is_populated()) { service_route = r->hdr_service_route.route_list; log_file->write_header("t_phone_user::handle_response_register"); log_file->write_raw("Store service route:\n"); for (list::const_iterator it = service_route.begin(); it != service_route.end(); ++it) { log_file->write_raw(it->encode()); log_file->write_endl(); } log_file->write_footer(); } else { if (!service_route.empty()) { log_file->write_report("Clear service route.", "t_phone_user::handle_response_register"); service_route.clear(); } } first_success = !is_registered; is_registered = true; ui->cb_register_success(user_config, r, expires, first_success); // Start sending NAT keepalive packets when STUN is used // (or in case of symmetric firewall) if (use_nat_keepalive && id_nat_keepalive == 0) { // Just start the NAT keepalive timer. The REGISTER // message itself created the NAT binding. So there is // no need to send a NAT keep alive packet now. phone->start_timer(PTMR_NAT_KEEPALIVE, this); } // Start sending TCP ping packets on persistent TCP connections. if (user_config->get_persistent_tcp() && id_tcp_ping == 0) { phone->start_timer(PTMR_TCP_PING, this); } // Registration succeeded. If sollicited MWI is provisioned // and no MWI subscription is established yet, then subscribe // to MWI. if (user_config->get_mwi_sollicited() && !mwi_auto_resubscribe) { subscribe_mwi(); } // Publish presence state if not yet published. if (user_config->get_pres_publish_startup() && presence_epa->get_epa_state() == t_epa::EPA_UNPUBLISHED) { publish_presence(t_presence_state::ST_BASIC_OPEN); } // Subscribe to buddy list presence if not done so. if (!buddy_list->get_is_subscribed()) { subscribe_presence(); } break; case R_4XX: is_registered = false; // RFC 3261 10.3 if (r->code == R_423_INTERVAL_TOO_BRIEF) { if (!r->hdr_min_expires.is_populated()) { // Violation of RFC 3261 10.3 item 7 log_file->write_report("Min-Expires header missing from 423 response.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, "Min-Expires header missing."); cleanup_registration_data(); return; } if (r->hdr_min_expires.time <= registration_time) { // Wrong Min-Expires time string s = "Min-Expires ("; s += ulong2str(r->hdr_min_expires.time); s += ") is smaller than the requested "; s += "time ("; s += ulong2str(registration_time); s += ")"; log_file->write_report(s, "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, s); cleanup_registration_data(); return; } // Automatic re-register with Min-Expires time registration_time = r->hdr_min_expires.time; re_register = true; // No need to cleanup STUN data as a new REGISTER will be // sent immediately. return; } // If authorization failed, then do not start the continuous // re-attempts. When authorization fails the user is asked // for credentials (in GUI). So the user cancelled these // questions and should not be bothered with the same question // again every 30 seconds. The user does not have the // credentials. if (r->code == R_401_UNAUTHORIZED || r->code == R_407_PROXY_AUTH_REQUIRED) { last_reg_failed = true; ui->cb_register_failed(user_config, r, true); cleanup_registration_data(); return; } // fall thru default: first_failure = !last_reg_failed; last_reg_failed = true; is_registered = false; authorizor.remove_from_cache(""); // Clear credentials cache ui->cb_register_failed(user_config, r, first_failure); phone->start_set_timer(PTMR_REGISTRATION, DUR_REG_FAILURE * 1000, this); cleanup_registration_data(); } } void t_phone_user::handle_response_deregister(t_response *r) { is_registered = false; last_reg_failed = false; if (r->is_success()) { ui->cb_deregister_success(user_config, r); } else { ui->cb_deregister_failed(user_config, r); } cleanup_registration_data(); } void t_phone_user::handle_response_query_register(t_response *r) { if (r->is_success()) { ui->cb_fetch_reg_result(user_config, r); } else { ui->cb_fetch_reg_failed(user_config, r); } } void t_phone_user::handle_response_options(t_response *r) { ui->cb_options_response(r); } void t_phone_user::handle_response_message(t_response *r) { t_request *req = r_message->get_request(); if (req->body && req->body->get_type() == BODY_IM_ISCOMPOSING_XML) { // Response on message composing indication. if (r->code == R_415_UNSUPPORTED_MEDIA_TYPE) { // RFC 3994 4 // In SIP-based IM, The composer MUST cease transmitting // status messages if the receiver returned a 415 status // code (Unsupported Media Type) in response to MESSAGE // request containing the status indication. ui->cb_im_iscomposing_not_supported(user_config, r); } } else { // Response on instant message ui->cb_message_response(user_config, r, req); } } void t_phone_user::subscribe_mwi(void) { mwi_auto_resubscribe = true; if (mwi_dialog) { // This situation may occur, when an unsubscription is still // in progress. The subscibe will be retried after the unsubscription // is finished. Note that mwi_auto_resubscribe has been set to true // to trigger an automatic subscription. log_file->write_header("t_phone_user::subscribe_mwi", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("MWI dialog already exists.\n"); log_file->write_raw("Subscription state: "); log_file->write_raw(t_subscription_state2str(mwi_dialog->get_subscription_state())); log_file->write_endl(); log_file->write_footer(); return; } // If STUN is enabled, then do a STUN query before registering to // determine the public IP address. if (use_stun) { if (stun_public_ip_sip == 0) { send_stun_request(); mwi_subscribe_after_stun = true; return; } stun_binding_inuse_mwi = true; } mwi_dialog = new t_mwi_dialog(this); MEMMAN_NEW(mwi_dialog); // RFC 3842 4.1 // The example flow shows: // Request-URI = mail_user@mailbox_server // To = user@domain mwi_dialog->subscribe(DUR_MWI(user_config), user_config->get_mwi_uri(), user_config->create_user_uri(false), user_config->get_display(false)); // Start sending NAT keepalive packets when STUN is used // (or in case of symmetric firewall) if (use_nat_keepalive && id_nat_keepalive == 0) { // Just start the NAT keepalive timer. The SUBSCRIBE // message will create the NAT binding. So there is // no need to send a NAT keep alive packet now. phone->start_timer(PTMR_NAT_KEEPALIVE, this); } cleanup_mwi_dialog(); } void t_phone_user::unsubscribe_mwi(void) { mwi_auto_resubscribe = false; stop_resubscribe_mwi_timer(); mwi.set_status(t_mwi::MWI_UNKNOWN); if (mwi_dialog) { mwi_dialog->unsubscribe(); cleanup_mwi_dialog(); } ui->cb_update_mwi(); } bool t_phone_user::is_mwi_subscribed(void) const { if (mwi_dialog) { return mwi_dialog->get_subscription_state() == SS_ESTABLISHED; } return false; } bool t_phone_user::is_mwi_terminated(void) const { return mwi_dialog == NULL; } void t_phone_user::handle_mwi_unsollicited(t_request *r, t_tid tid) { if (user_config->get_mwi_sollicited()) { // Unsollicited MWI is not supported t_response *resp = r->create_response(R_403_FORBIDDEN); phone->send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } if (r->body && r->body->get_type() == BODY_SIMPLE_MSG_SUM) { t_simple_msg_sum_body *body = dynamic_cast(r->body); mwi.set_msg_waiting(body->get_msg_waiting()); t_msg_summary summary; if (body->get_msg_summary(MSG_CONTEXT_VOICE, summary)) { mwi.set_voice_msg_summary(summary); } mwi.set_status(t_mwi::MWI_KNOWN); } t_response *resp = r->create_response(R_200_OK); phone->send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; ui->cb_update_mwi(); } void t_phone_user::subscribe_presence(void) { assert(buddy_list); buddy_list->subscribe_presence(); } void t_phone_user::unsubscribe_presence(void) { assert(buddy_list); buddy_list->unsubscribe_presence(); } void t_phone_user::publish_presence(t_presence_state::t_basic_state basic_state) { assert(presence_epa); presence_epa->publish_presence(basic_state); } void t_phone_user::unpublish_presence(void) { assert(presence_epa); presence_epa->unpublish(); } bool t_phone_user::is_presence_terminated(void) const { assert(buddy_list); return buddy_list->is_presence_terminated(); } bool t_phone_user::send_message(const t_url &to_uri, const string &to_display, const t_msg &msg) { t_request *req = create_request(MESSAGE, to_uri); // To req->hdr_to.set_uri(to_uri); req->hdr_to.set_display(to_display); // Call-ID req->hdr_call_id.set_call_id(NEW_CALL_ID(user_config)); // CSeq req->hdr_cseq.set_method(MESSAGE); req->hdr_cseq.set_seqnr(NEW_SEQNR); // Subject if (!msg.subject.empty()) { req->hdr_subject.set_subject(msg.subject); } // Body and Content-Type if (!msg.has_attachment) { // A message without an attachment is a text message. req->set_body_plain_text(msg.message, MSG_TEXT_CHARSET); } else { // Send message with file attachment if (!req->set_body_from_file(msg.attachment_filename, msg.attachment_media)) { log_file->write_header("t_phone_user::send_message", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Could not read file "); log_file->write_raw(msg.attachment_filename); log_file->write_endl(); log_file->write_footer(); MEMMAN_DELETE(req); delete req; return false; } // Content-Disposition req->hdr_content_disp.set_type(DISPOSITION_ATTACHMENT); req->hdr_content_disp.set_filename(msg.attachment_save_as_name); } // Store and send request // Delete a possible pending options request if (r_message) { // RFC 3428 8 // Send only 1 message at a time. // Store the message. It will be sent if the previous // message transaction is finished. pending_messages.push_back(req); } else { r_message = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_message); phone->send_request(user_config, req, r_message->get_tuid()); MEMMAN_DELETE(req); delete req; } return true; } bool t_phone_user::send_im_iscomposing(const t_url &to_uri, const string &to_display, const string &state, time_t refresh) { t_request *req = create_request(MESSAGE, to_uri); // To req->hdr_to.set_uri(to_uri); req->hdr_to.set_display(to_display); // Call-ID req->hdr_call_id.set_call_id(NEW_CALL_ID(user_config)); // CSeq req->hdr_cseq.set_method(MESSAGE); req->hdr_cseq.set_seqnr(NEW_SEQNR); // Body and Content-Type t_im_iscomposing_xml_body *body = new t_im_iscomposing_xml_body; MEMMAN_NEW(body); body->set_state(state); body->set_refresh(refresh); req->body = body; req->hdr_content_type.set_media(body->get_media()); // Store and send request // Delete a possible pending options request if (r_message) { // RFC 3428 8 // Send only 1 message at a time. // Store the message. It will be sent if the previous // message transaction is finished. pending_messages.push_back(req); } else { r_message = new t_client_request(user_config, req, 0); MEMMAN_NEW(r_message); phone->send_request(user_config, req, r_message->get_tuid()); MEMMAN_DELETE(req); delete req; } return true; } void t_phone_user::recvd_message(t_request *r, t_tid tid) { t_response *resp; if (!r->body || !MESSAGE_CONTENT_TYPE_SUPPORTED(*r)) { resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE); // RFC 3261 21.4.13 SET_MESSAGE_HDR_ACCEPT(resp->hdr_accept); phone->send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } if (r->body && r->body->get_type() == BODY_IM_ISCOMPOSING_XML) { // Message composing indication t_im_iscomposing_xml_body *sb = dynamic_cast(r->body); im::t_composing_state state = im::string2composing_state(sb->get_state()); time_t refresh = sb->get_refresh(); ui->cb_im_iscomposing_request(user_config, r, state, refresh); resp = r->create_response(R_200_OK); } else { bool accepted = ui->cb_message_request(user_config, r); if (accepted) { resp = r->create_response(R_200_OK); } else { if (user_config->get_im_max_sessions() == 0) { resp = r->create_response(R_603_DECLINE); } else { resp = r->create_response(R_486_BUSY_HERE); } } } phone->send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone_user::recvd_notify(t_request *r, t_tid tid) { bool partial_match = false; if (r->hdr_to.tag.empty()) { // Unsollicited NOTIFY handle_mwi_unsollicited(r, tid); return; } if (mwi_dialog && mwi_dialog->match_request(r, partial_match)) { // Sollicited NOTIFY mwi_dialog->recvd_request(r, 0, tid); cleanup_mwi_dialog(); return; } // A NOTIFY may be received before a 2XX on SUBSCRIBE. // In this case the NOTIFY will establish the dialog. if (partial_match && mwi_dialog->get_remote_tag().empty()) { mwi_dialog->recvd_request(r, 0, tid); cleanup_mwi_dialog(); return; } t_buddy *buddy; if (buddy_list->match_request(r, &buddy)) { buddy->recvd_request(r, 0, tid); if (buddy->must_delete_now()) buddy_list->del_buddy(*buddy); return; } // RFC 3265 4.4.9 // A SUBSCRIBE request may have forked. So multiple NOTIFY's // can be received. Twinkle simply rejects additional NOTIFY's with // a 481. This should terminate the forked dialog, such that only // one dialog will remain. t_response *resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); phone->send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone_user::send_stun_request(void) { if (r_stun) { log_file->write_report("STUN request already in progress.", "t_phone_user::send_stun_request", LOG_NORMAL, LOG_DEBUG); return; } StunMessage req; StunAtrString username; username.sizeValue = 0; stunBuildReqSimple(&req, username, false, false); r_stun = new t_client_request(user_config, &req, 0); MEMMAN_NEW(r_stun); phone->send_request(user_config, &req, r_stun->get_tuid()); return; } // NOTE: The term "NAT keep alive" does not cover all uses. The keep alives will // also be sent when there is a symmetric firewall without NAT. void t_phone_user::send_nat_keepalive(void) { // Send keep-alive to registrar/proxy if (register_ip_port.ipaddr != 0 && register_ip_port.port != 0 && register_ip_port.transport == "udp") { evq_sender->push_nat_keepalive(register_ip_port.ipaddr, register_ip_port.port); } // Send keep-alive to MWI mailbox if different from registrar/proxy if (mwi_dialog) { t_ip_port mwi_ip_port = mwi_dialog->get_remote_ip_port(); if (!mwi_ip_port.is_null() && mwi_ip_port != register_ip_port && mwi_ip_port.transport == "udp") { evq_sender->push_nat_keepalive(mwi_ip_port.ipaddr, mwi_ip_port.port); } } } void t_phone_user::send_tcp_ping(void) { if (register_ip_port.ipaddr != 0 && register_ip_port.port != 0 && register_ip_port.transport == "tcp") { evq_sender->push_tcp_ping(user_config->create_user_uri(false), register_ip_port.ipaddr, register_ip_port.port); } } void t_phone_user::timeout(t_phone_timer timer) { switch (timer) { case PTMR_REGISTRATION: id_registration = 0; // Registration expired. Re-register. if (is_registered || last_reg_failed) { // Re-register if no register is pending if (!r_register) { registration(REG_REGISTER, true, registration_time); } } break; case PTMR_NAT_KEEPALIVE: id_nat_keepalive = 0; // Send a new NAT keepalive packet if (use_nat_keepalive) { send_nat_keepalive(); phone->start_timer(PTMR_NAT_KEEPALIVE, this); } break; case PTMR_TCP_PING: id_tcp_ping = 0; // Send a TCP ping; if (user_config->get_persistent_tcp()) { send_tcp_ping(); phone->start_timer(PTMR_TCP_PING, this); } break; default: assert(false); } } void t_phone_user::timeout_sub(t_subscribe_timer timer, t_object_id id_timer) { t_buddy *buddy; switch (timer) { case STMR_SUBSCRIPTION: if (mwi_dialog && mwi_dialog->match_timer(timer, id_timer)) { mwi_dialog->timeout(timer); } else if (buddy_list->match_timer(timer, id_timer, &buddy)) { buddy->timeout(timer, id_timer); if (buddy->must_delete_now()) buddy_list->del_buddy(*buddy); } else if (id_timer == id_resubscribe_mwi) { // Try to subscribe to MWI id_resubscribe_mwi = 0; subscribe_mwi(); } break; default: assert(false); } } void t_phone_user::timeout_publish(t_publish_timer timer, t_object_id id_timer) { switch (timer) { case PUBLISH_TMR_PUBLICATION: if (presence_epa->match_timer(timer, id_timer)) { presence_epa->timeout(timer); } break; default: assert(false); } } void t_phone_user::handle_broken_connection(void) { log_file->write_header("t_phone_user::handle_broken_connection", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Handle broken connection for "); log_file->write_raw(user_config->get_profile_name()); log_file->write_endl(); log_file->write_footer(); // A persistent connection has been broken. The connection must be re-established // by registering again. This is only needed when the user was registered already. // If no registration was present, then the persistent connection should not have // been established. if (is_registered) { // Re-register if no register is pending if (!r_register) { log_file->write_header("t_phone_user::handle_broken_connection", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Re-establish broken connection for "); log_file->write_raw(user_config->get_profile_name()); log_file->write_endl(); log_file->write_footer(); registration(REG_REGISTER, true, registration_time); } } } bool t_phone_user::match_subscribe_timer(t_subscribe_timer timer, t_object_id id_timer) const { t_buddy *buddy; if (mwi_dialog && mwi_dialog->match_timer(timer, id_timer)) { return true; } t_phone_user *self = const_cast(this); if (self->buddy_list->match_timer(timer, id_timer, &buddy)) { return true; } return id_timer == id_resubscribe_mwi; } bool t_phone_user::match_publish_timer(t_publish_timer timer, t_object_id id_timer) const { assert(presence_epa); return presence_epa->match_timer(timer, id_timer); } void t_phone_user::start_resubscribe_mwi_timer(unsigned long duration) { t_tmr_subscribe *t; t = new t_tmr_subscribe(duration, STMR_SUBSCRIPTION, 0, 0, SIP_EVENT_MSG_SUMMARY, ""); MEMMAN_NEW(t); id_resubscribe_mwi = t->get_object_id(); evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_phone_user::stop_resubscribe_mwi_timer(void) { if (id_resubscribe_mwi != 0) { evq_timekeeper->push_stop_timer(id_resubscribe_mwi); id_resubscribe_mwi = 0; } } t_request *t_phone_user::create_request(t_method m, const t_url &request_uri) const { t_request *req = new t_request(m); MEMMAN_NEW(req); // From req->hdr_from.set_uri(user_config->create_user_uri(false)); req->hdr_from.set_display(user_config->get_display(false)); req->hdr_from.set_tag(NEW_TAG); // Max-Forwards header (mandatory) req->hdr_max_forwards.set_max_forwards(MAX_FORWARDS); // User-Agent SET_HDR_USER_AGENT(req->hdr_user_agent); // Set request URI and calculate destinations. By calculating // destinations now, the request can be resend to a next destination // if failover is needed. if (m == REGISTER) { // For a REGISTER do not use the service route for routing. req->uri = request_uri; } else { // RFC 3608 // For all other requests, use the service route set for routing. req->set_route(request_uri, service_route); } req->calc_destinations(*user_config); // The Via header can only be created after the destinations // are calculated, because the destination deterimines which // local IP address should be used. // Via unsigned long local_ip = req->get_local_ip(); t_via via(USER_HOST(user_config, h_ip2str(local_ip)), PUBLIC_SIP_PORT(user_config)); req->hdr_via.add_via(via); return req; } t_response *t_phone_user::create_options_response(t_request *r, bool in_dialog) const { t_response *resp; // RFC 3261 11.2 switch(phone->get_state()) { case PS_IDLE: if (!in_dialog && service->is_dnd_active()) { resp = r->create_response(R_480_TEMP_NOT_AVAILABLE); } else { resp = r->create_response(R_200_OK); } break; case PS_BUSY: if (in_dialog) { resp = r->create_response(R_200_OK); } else { resp = r->create_response(R_486_BUSY_HERE); } break; default: assert(false); } SET_HDR_ALLOW(resp->hdr_allow, user_config); SET_HDR_ACCEPT(resp->hdr_accept); SET_HDR_ACCEPT_ENCODING(resp->hdr_accept_encoding); SET_HDR_ACCEPT_LANGUAGE(resp->hdr_accept_language); SET_HDR_SUPPORTED(resp->hdr_supported, user_config); if (user_config->get_ext_100rel() != EXT_DISABLED) { resp->hdr_supported.add_feature(EXT_100REL); } // TODO: include SDP body if requested (optional) return resp; } bool t_phone_user::get_is_registered(void) const { return is_registered; } bool t_phone_user::get_last_reg_failed(void) const { return last_reg_failed; } string t_phone_user::get_ip_sip(const string &auto_ip) const { if (stun_public_ip_sip) return h_ip2str(stun_public_ip_sip); if (user_config->get_use_nat_public_ip()) return user_config->get_nat_public_ip(); if (LOCAL_IP == AUTO_IP4_ADDRESS) return auto_ip; return LOCAL_IP; } unsigned short t_phone_user::get_public_port_sip(void) const { if (stun_public_port_sip) return stun_public_port_sip; return sys_config->get_sip_port(); } list t_phone_user::get_service_route(void) const { return service_route; } bool t_phone_user::match(t_response *r, t_tuid tuid) const { t_buddy *dummy; if (r_register && r_register->get_tuid() == tuid) { return true; } else if (r_deregister && r_deregister->get_tuid() == tuid) { return true; } else if (r_query_register && r_query_register->get_tuid() == tuid) { return true; } else if (r_options && r_options->get_tuid() == tuid) { return true; } else if (r_message && r_message->get_tuid() == tuid) { return true; } else if (mwi_dialog && mwi_dialog->match_response(r, tuid)) { return true; } else if (presence_epa && presence_epa->match_response(r, tuid)) { return true; } else if (buddy_list && buddy_list->match_response(r, tuid, &dummy)) { return true; } else { // Response does not match any pending request. return false; } } bool t_phone_user::match(t_request *r) const { if (!r->hdr_to.tag.empty()) { // Match in-dialog requests if (mwi_dialog) { bool partial_match = false; if (mwi_dialog->match_request(r, partial_match)) return true; if (partial_match) return true; } else if (buddy_list) { t_buddy *dummy; if (buddy_list->match_request(r, &dummy)) return true; } else { return false; } } // Match on contact URI // NOTE: the host-part is not matched with the IP address to avoid // NAT traversal problems. Some providers, using hosted NAT // traversal, send an INVITE to username@. Twinkle // only knows the in this case though. This is a // fault on the provider side. if (r->uri.get_user() == user_config->get_contact_name()) { return true; } // Match on user URI if (r->uri.get_user() == user_config->get_name() && r->uri.get_host() == user_config->get_domain()) { return true; } return false; } bool t_phone_user::match(StunMessage *r, t_tuid tuid) const { if (r_stun && r_stun->get_tuid() == tuid) return true; return false; } bool t_phone_user::authorize(t_request *r, t_response *resp) { if (authorizor.authorize(user_config, r, resp)) { return true; } return false; } void t_phone_user::resend_request(t_request *req, t_client_request *cr) { return resend_request(req, false, cr); } void t_phone_user::remove_cached_credentials(const string &realm) { authorizor.remove_from_cache(realm); } bool t_phone_user::is_active(void) const { return active; } void t_phone_user::activate(const t_user &user) { // Replace old user config with the new passed user config, because // the user config might have been edited while this phone user was // inactive. delete user_config; MEMMAN_DELETE(user_config); user_config = user.copy(); // Initialize registration data register_seqnr = NEW_SEQNR; is_registered = false; register_ip_port.ipaddr = 0L; register_ip_port.port = 0; last_reg_failed = false; // Initialize STUN data stun_public_ip_sip = 0L; stun_public_port_sip = 0; use_stun = false; use_nat_keepalive = false; active = true; } void t_phone_user::deactivate(void) { // Stop timers if (id_registration) phone->stop_timer(PTMR_REGISTRATION, this); if (id_nat_keepalive) phone->stop_timer(PTMR_NAT_KEEPALIVE, this); if (id_tcp_ping) phone->stop_timer(PTMR_TCP_PING, this); if (id_resubscribe_mwi) stop_resubscribe_mwi_timer(); // Clear MWI if (mwi_dialog) { MEMMAN_DELETE(mwi_dialog); delete mwi_dialog; mwi_dialog = NULL; } mwi.set_status(t_mwi::MWI_UNKNOWN); mwi_auto_resubscribe = false; // Clear presence state // presence_epa->clear(); buddy_list->clear_presence(); // Clear STUN stun_binding_inuse_registration = false; stun_binding_inuse_mwi = false; stun_binding_inuse_presence = 0; cleanup_registration_data(); cleanup_stun_data(); active = false; } twinkle-1.4.2/src/sys_settings.h0000644000175000001440000004166111144643416013622 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _SYS_SETTINGS_H #define _SYS_SETTINGS_H #include #include #include #include "parser/sip_message.h" #include "sockets/url.h" #include "threads/mutex.h" #include "twinkle_config.h" using namespace std; /** @name General system settings */ //@{ /** User directory, relative to the home directory ($HOME) */ #define DIR_USER ".twinkle" /** Home directory */ #define DIR_HOME (getenv("HOME")) /** Directory for storing temporary files, relative to @ref DIR_USER */ #define DIR_TMPFILE "tmp" /** Device file for DSP */ #define DEV_DSP "/dev/dsp" /** Device prefixes in settings file */ #define PFX_OSS "oss:" #define PFX_ALSA "alsa:" /** ALSA default device */ #define DEV_ALSA_DFLT "alsa:default" /** Device string for other device */ #define DEV_OTHER "other device" /** File with SIP providers for the wizard */ #define FILE_PROVIDERS "providers.csv" /** File with CLI command history */ #define FILE_CLI_HISTORY "twinkle.history" //@} /** Audio device */ class t_audio_device { public: enum t_audio_device_type { OSS, ALSA } type; string device; // eg. /dev/dsp, /dev/dsp1 for OSS or hw:0,0 for ALSA string sym_link; // real device if the device is a symbolic link string name; // name of the sound card // Get a one-line description string get_description(void) const; // Get string to be written in settings file string get_settings_value(void) const; }; /** Window geometry */ struct t_win_geometry { int x; /**< x-coordinate of top left corner */ int y; /**< y-coordinate of top left corner */ int width; /**< Window width */ int height; /**< Window height */ /** Constructor */ t_win_geometry(); /** Constructor */ t_win_geometry(int x_, int y_, int width_, int height_); /** * Construct a geometry from an encoded string. * If the string cannot be parsed, all values are set to zero. * @param value [in] Encoded string "x,y,widht,height" */ t_win_geometry(const string &value); /** * Encode geometry into a string. * @return Encoded geometry "x,y,width,height" */ string encode(void) const; }; /** System settings */ class t_sys_settings { private: // Mutex to avoid sync concurrent access mutable t_recursive_mutex mtx_sys; /** File descriptor of lock file */ int fd_lock_file; // Share directory for files applicable to all users string dir_share; // Full file name for config file string filename; /** The SIP port that is currently used */ unsigned short active_sip_port; // Sound devices t_audio_device dev_ringtone; t_audio_device dev_speaker; t_audio_device dev_mic; // Indicates if audio devices should be validated before // usage. bool validate_audio_dev; int alsa_play_period_size; int alsa_capture_period_size; int oss_fragment_size; // Log file settings unsigned short log_max_size; // in MB bool log_show_sip; bool log_show_stun; bool log_show_memory; bool log_show_debug; /** @name GUI settings */ //@{ bool gui_use_systray; bool gui_hide_on_close; /** Show main window on incoming call after a few seconds */ bool gui_auto_show_incoming; int gui_auto_show_timeout; /** Command to start an internet browser */ string gui_browser_cmd; //@} // Address book settings bool ab_show_sip_only; bool ab_lookup_name; bool ab_override_display; bool ab_lookup_photo; // Call history settings int ch_max_size; // #calls // Service settings // Call waiting allows an incoming call if one line is busy. bool call_waiting; // Indicates if both lines should be hung up when ending a // 3-way conference call. // If false, then only the active line will be hung up. bool hangup_both_3way; // Startup settings list start_user_profiles; bool start_hidden; /** The full path name of the shared mime database */ string mime_shared_database; /** @name Network settings */ //@{ /** Port for sending and receiving SIP messages. This is the value * written in the system settings file. This value can differ from * active_sip_port value if the user changed the system * settings while Twinkle is running. */ unsigned short config_sip_port; /** SIP UDP port overridden by the command options. */ unsigned short override_sip_port; /** Port for RTP. * rtp_port is the base port for RTP streams. Each phone line * uses has its own RTP port number. * line x has RTP port = rtp_port + x * 2 and * RTCP port = rtp_port + x * 2 + 1 * Where x starts at 0 * * NOTE: for call transfer scenario, line 2 (3rd line) is used * which is not a line that is visible to the user. The user * only sees 2 lines for its use. By having a dedicated port * for line 2, the RTP stream for a referred call uses another * port than the RTP stream for an original call, preventing * the RTP streams for these calls to become mixed. * * NOTE: during a call transfer, line 2 will be swapped with another * line, so the ports swap accordingly. */ unsigned short rtp_port; /** RTP port overridden by the command options. */ unsigned short override_rtp_port; /** Maximum size of a SIP message received over UDP. */ unsigned short sip_max_udp_size; /** Maximum size of a SIP message received over TCP. */ unsigned long sip_max_tcp_size; //@} // Ring tone settings bool play_ringtone; string ringtone_file; bool play_ringback; string ringback_file; // Persistent storage for user interface state // The profile that was last used before Twinkle was terminated. string last_used_profile; // Call information for redial last call function t_url redial_url; string redial_display; string redial_subject; string redial_profile; // profile used to make the call bool redial_hide_user; // Did the user request hiding? // History of latest dialed addresses list dial_history; /** @name GUI view settings */ //@{ bool show_display; bool compact_line_status; bool show_buddy_list; //@} /** @name Settings to restore a previous user interface session after system shutdown */ //@{ /** ID of previous session */ string ui_session_id; /** Active user profiles */ list ui_session_active_profiles; /** Geometry of main window */ t_win_geometry ui_session_main_geometry; /** Flag to indicate if the main window is hidden. */ bool ui_session_main_hidden; /** Window state of main window. */ unsigned int ui_session_main_state; //@} // One time warnings bool warn_hide_user; // Warn use that provider may not support hiding. public: /** Constructor */ t_sys_settings(); /** @name Getters */ //@{ t_audio_device get_dev_ringtone(void) const; t_audio_device get_dev_speaker(void) const; t_audio_device get_dev_mic(void) const; bool get_validate_audio_dev(void) const; int get_alsa_play_period_size(void) const; int get_alsa_capture_period_size(void) const; int get_oss_fragment_size(void) const; unsigned short get_log_max_size(void) const; bool get_log_show_sip(void) const; bool get_log_show_stun(void) const; bool get_log_show_memory(void) const; bool get_log_show_debug(void) const; bool get_gui_use_systray(void) const; bool get_gui_hide_on_close(void) const; bool get_gui_auto_show_incoming(void) const; int get_gui_auto_show_timeout(void) const; string get_gui_browser_cmd(void) const; bool get_ab_show_sip_only(void) const; bool get_ab_lookup_name(void) const; bool get_ab_override_display(void) const; bool get_ab_lookup_photo(void) const; int get_ch_max_size(void) const; bool get_call_waiting(void) const; bool get_hangup_both_3way(void) const; list get_start_user_profiles(void) const; bool get_start_hidden(void) const; unsigned short get_config_sip_port(void) const; unsigned short get_rtp_port(void) const; unsigned short get_sip_max_udp_size(void) const; unsigned long get_sip_max_tcp_size(void) const; bool get_play_ringtone(void) const; string get_ringtone_file(void) const; bool get_play_ringback(void) const; string get_ringback_file(void) const; string get_last_used_profile(void) const; t_url get_redial_url(void) const; string get_redial_display(void) const; string get_redial_subject(void) const; string get_redial_profile(void) const; bool get_redial_hide_user(void) const; list get_dial_history(void) const; bool get_show_display(void) const; bool get_compact_line_status(void) const; bool get_show_buddy_list(void) const; string get_ui_session_id(void) const; list get_ui_session_active_profiles(void) const; t_win_geometry get_ui_session_main_geometry(void) const; bool get_ui_session_main_hidden(void) const; unsigned int get_ui_session_main_state(void) const; bool get_warn_hide_user(void) const; string get_mime_shared_database(void) const; //@} /** @name Setters */ //@{ void set_dev_ringtone(const t_audio_device &dev); void set_dev_speaker(const t_audio_device &dev); void set_dev_mic(const t_audio_device &dev); void set_validate_audio_dev(bool b); void set_alsa_play_period_size(int size); void set_alsa_capture_period_size(int size); void set_oss_fragment_size(int size); void set_log_max_size(unsigned short size); void set_log_show_sip(bool b); void set_log_show_stun(bool b); void set_log_show_memory(bool b); void set_log_show_debug(bool b); void set_gui_use_systray(bool b); void set_gui_hide_on_close(bool b); void set_gui_auto_show_incoming(bool b); void set_gui_auto_show_timeout(int timeout); void set_gui_browser_cmd(const string &s); void set_ab_show_sip_only(bool b); void set_ab_lookup_name(bool b); void set_ab_override_display(bool b); void set_ab_lookup_photo(bool b); void set_ch_max_size(int size); void set_call_waiting(bool b); void set_hangup_both_3way(bool b); void set_start_user_profiles(const list &profiles); void set_start_hidden(bool b); void set_config_sip_port(unsigned short port); void set_override_sip_port(unsigned short port); void set_rtp_port(unsigned short port); void set_override_rtp_port(unsigned short port); void set_sip_max_udp_size(unsigned short size); void set_sip_max_tcp_size(unsigned long size); void set_play_ringtone(bool b); void set_ringtone_file(const string &file); void set_play_ringback(bool b); void set_ringback_file(const string &file); void set_last_used_profile(const string &profile); void set_redial_url(const t_url &url); void set_redial_display(const string &display); void set_redial_subject(const string &subject); void set_redial_profile(const string &profile); void set_redial_hide_user(bool b); void set_dial_history(const list &history); void set_show_display(bool b); void set_compact_line_status(bool b); void set_show_buddy_list(bool b); void set_ui_session_id(const string &id); void set_ui_session_active_profiles(const list &profiles); void set_ui_session_main_geometry(const t_win_geometry &geometry); void set_ui_session_main_hidden(bool hidden); void set_ui_session_main_state(unsigned int state); void set_warn_hide_user(bool b); void set_mime_shared_database(const string &filename); //@} /** * Get "about" text. * @param html [in] Indicates if "about" text must be in HTML format. * @return The "about" text" */ string about(bool html) const; /** * Get produce release date. * @return product release date in locale format */ string get_product_date(void) const; /** * Get a string of options that are built, e.g. ALSA, KDE * @return The string of options. */ string get_options_built(void) const; /** * Check if the environment of the machine satisfies all requirements. * @param error_msg [out] User readable error message when false is returned. * @return true if all requirements are met. * @return false, otherwise and error_msg contains an appropriate * error message to show the user. */ bool check_environment(string &error_msg) const; /** * Set the share directory * @param dir [in] Absolute path of the share directory. */ void set_dir_share(const string &dir); /** * Get the share directory. * @return Absolute path of the directory with shared files. */ string get_dir_share(void) const; /** * Get the directory containing language translation files. * @return Absolute path of the language directory. */ string get_dir_lang(void) const; /** * Get the user directory. * @return Absolute path of the user directory. */ string get_dir_user(void) const; /** * Get the CLI command history file. * @return Full pathname of the history file. */ string get_history_file(void) const; /** * Get the temporary file directory. * @return The full pathname of the temporary file directory. */ string get_dir_tmpfile(void) const; /** * Check if a file is located in the temporary file directory. * @return true if the file is in the temporary file directory, false otherwise. */ bool is_tmpfile(const string &filename) const; /** * Save data to a temporary file. * @param data [in] Data to save. * @param file_extension [in] Extension (glob) for file name. * @param filename [out] File name of save file, relative to the tmp directory. * @param error_msg [out] If saving failed, then this parameter contains an * error message. * @return true if saving succeeded, false otherwise. */ bool save_tmp_file(const string &data, const string &file_extension, string &filename, string &error_msg); /** * Save the body of a SIP message to a temporary file. * @param sip_msg [in] The SIP message from which the body must be saved. * @param suggested_file_extension [in] File extension (glob) for file name to save * if an extension cannot be determined from a filename supplied as * in the Content-Disposition header. * @param tmpname [out] The name of the saved file. * @param save_as_name [out] Suggested file name for user for saving. * @param error_msg [out] Error message when saving failed. * @return true if saving succeeded, false otherwise. */ bool save_sip_body(const t_sip_message &sip_msg, const string &suggested_file_extension, string &tmpname, string &save_as_name, string &error_msg); /** Remove all files from the temporary file directory */ void remove_all_tmp_files(void) const; /** @name Lock file operations */ /** * Create a lock file if it does not exist yet and take a file lock on it. * @param shared_lock [in] Indicates if the file lock must be shared or exclusive. * A shared lock is needed when the users forces multiple Twinkle processes * to run. * @param error_msg [out] Error message if the operation fails. * @param already_running [out] If the operation fails, this flag indicates Twinkle * is already running. * @return True if the file is locked succesfully. * @return False if the file could not be locked. */ bool create_lock_file(bool shared_lock, string &error_msg, bool &already_running); /** Unlock the lock file. */ void delete_lock_file(void); // Read and parse a config file into the t_sys_settings object. // Returns false if it fails. error_msg is an error message that can // be give to the user. bool read_config(string &error_msg); // Write the settings into a config file bool write_config(string &error_msg); // Get all OSS devices list get_oss_devices(bool playback) const; #ifdef HAVE_LIBASOUND // Get all ALSA devices list get_alsa_devices(bool playback) const; #endif // Get all audio devices list get_audio_devices(bool playback) const; // Check if two OSS devices are equal bool equal_audio_dev(const t_audio_device &dev1, const t_audio_device &dev2) const; static t_audio_device audio_device(string device = ""); // Check validate the audio devices flagged as true. // If audio validation is turned off then always true is returned. bool exec_audio_validation(bool ringtone, bool speaker, bool mic, string &error_msg) const; // Get the active value of the SIP UDP port // Once the SIP UDP port is retrieved from the system settings, it // is stored as the active port. A next call to get_sip_port // returns the active port, even when the SIP UDP port in the settings // has changed. // If force_active == true, then always the SIP UDP port is returned // and made active unsigned short get_sip_port(bool force_active = false); }; extern t_sys_settings *sys_config; #endif twinkle-1.4.2/src/session.h0000644000175000001440000001474011127714046012544 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Session description of an established session. // A session is the media part of a dialog. #ifndef _SESSION_H #define _SESSION_H #include #include #include #include "dialog.h" #include "user.h" #include "sdp/sdp.h" #include "parser/sip_message.h" #include "audio/audio_codecs.h" #include "audio/audio_session.h" // Forward declarations class t_dialog; class t_line; using namespace std; class t_session { private: // The owning dialog t_dialog *dialog; // User profile of user for which the session is created. // This is a pointer to the user_config owned by a phone user. // So this pointer should never be deleted. t_user *user_config; // Copy of host needed for call-retrieve after call-hold string retrieve_host; // Audio RTP session t_audio_session *audio_rtp_session; // Indicates if session is put on-hold, i.e. no RTP should be sent // or received for this session. bool is_on_hold; // Indicates if a session is killed, i.e. RTP will never be // sent or received anymore. bool is_killed; // Mapping from audio codecs to RTP payload numbers for receiving // and sending directions. map recv_ac2payload; map send_ac2payload; // Mapping from RTP payload numbers to audio codecs for receiving // and sending directions. map recv_payload2ac; map send_payload2ac; // Set the list of received codecs from the SDP. // Create the send_ac2paylaod and send_payload2ac mappings. void set_recvd_codecs(t_sdp *sdp); // Returns if this session is part of a 3-way conference bool is_3way(void) const; // Returns the peer session of a 3-way conference t_session *get_peer_3way (void) const; public: // Audio session information // Near end information string src_sdp_version; string src_sdp_id; string receive_host; // RTP receive host address unsigned short receive_port; // RTP receive port // Far end information string dst_sdp_version; string dst_sdp_id; string dst_rtp_host; unsigned short dst_rtp_port; bool dst_zrtp_support; // Direction of the audio stream from this phone's point of view t_sdp_media_direction direction; list offer_codecs; // codecs to offer in outgoing INVITE list recvd_codecs; // codecs received from far-end t_audio_codec use_codec; // codec to be used unsigned short ptime; // payload size (ms) unsigned short ilbc_mode; // 20 or 30 ms bool recvd_offer; // offer received? bool recvd_answer; // answer received? bool sent_offer; // offer sent? unsigned short recv_dtmf_pt; // payload type for DTMF receiving unsigned short send_dtmf_pt; // payload type for DTMF sending t_sdp recvd_sdp_offer; t_session(t_dialog *_dialog, string _receive_host, unsigned short _receive_port); // The destructor will destroy the RTP session and stop the // RTP streams ~t_session(); /** @name Clone a new session from an existing session. */ //@{ /** @note copies of a session do not copy the audio RTP session! */ /** * Create a session based on an existing session, i.e. * same receive user and host. The source SDP version of the * new session will be increased by 1. * @return The new session. */ t_session *create_new_version(void) const; /** * Create a copy of the session. The destination paramters * and recvd/offer and answer are erased in the copy. * The source SDP version of the new session will be increased by 1. * @return The new session. */ t_session *create_clean_copy(void) const; /** * Create a session for call-hold. * @return The call-hold session. */ t_session *create_call_hold(void) const; /** * Create a session for call-retrieve. * @return The call-retrieve session. */ t_session *create_call_retrieve(void) const; //@} // Process incoming SDP offer. Return false if SDP is not // supported. If SDP is supported then use_codec will be // set to the first codec in the received offer that is // supported by this phone, i.e. this is the codec that should // be put in the answer. bool process_sdp_offer(t_sdp *sdp, int &warn_code, string &warn_text); // Process incoming SDP answer. Return false if SDP is not // supported. It is expected that the answer contains 1 codec // only. If more codecs are answered, then only the first supported // codec is considered. bool process_sdp_answer(t_sdp *sdp, int &warn_code, string &warn_text); // Create an SDP offer body for a SIP message void create_sdp_offer(t_sip_message *m, const string &user); // Create an SDP answer body for a SIP message void create_sdp_answer(t_sip_message *m, const string &user); // Start/stop the RTP streams // When a session is on-hold then start_rtp simply returns. void start_rtp(void); void stop_rtp(void); // Kill RTP streams. The difference with stopping an RTP stream // is that it cannot be started after being killed. void kill_rtp(void); t_audio_session *get_audio_session(void) const; void set_audio_session(t_audio_session *as); // Check if two session are equal wrt the audio parameters bool equal_audio(const t_session &s) const; // Send DTMF digit void send_dtmf(char digit, bool inband); // Get the line that belongs to this session t_line *get_line(void) const; // Transfer ownership of this session to a new dialog void set_owner(t_dialog *d); // Hold/un-hold a session // These methods only toggle the hold indicator. If you hold // a session, you must make sure that any running RTP is stopped. // If you unhold a session you have to call start_rtp to start the // RTP. void hold(void); void unhold(void); // Check if RTP session is acitve bool is_rtp_active(void) const; }; #endif twinkle-1.4.2/src/main.cpp0000644000175000001440000003720511144641303012333 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "address_book.h" #include "call_history.h" #include "events.h" #include "line.h" #include "listener.h" #include "log.h" #include "phone.h" #include "protocol.h" #include "sender.h" #include "sys_settings.h" #include "transaction_mgr.h" #include "translator.h" #include "user.h" #include "userintf.h" #include "util.h" #include "sockets/connection_table.h" #include "sockets/interfaces.h" #include "sockets/socket.h" #include "threads/thread.h" #include "utils/mime_database.h" #include "audits/memman.h" using namespace std; using namespace utils; // Class to initialize the random generator before objects of // other classes are created. Initializing just from the main function // is too late. class t_init_rand { public: t_init_rand(); }; t_init_rand::t_init_rand() { srand(time(NULL)); } // Memory manager for memory leak tracing t_memman *memman; // Initialize random generator t_init_rand init_rand; // Indicates if application is ending (because user pressed Quit) bool end_app; // Language translator t_translator *translator = NULL; // IP address on which the phone is running string user_host; // Local host name string local_hostname; // SIP UDP socket for sending and receiving signaling t_socket_udp *sip_socket; // SIP TCP socket for sending and receiving signaling t_socket_tcp *sip_socket_tcp; // SIP connection table for connection oriented transport t_connection_table *connection_table; // Event queue that is handled by the transaction manager thread // The following threads write to this queue // - UDP listener // - transaction layer // - timekeeper t_event_queue *evq_trans_mgr; // Event queue that is handled by the sender thread // The following threads write to this queue: // - phone UAS // - phone UAC // - transaction manager t_event_queue *evq_sender; // Event queue that is handled by the transaction layer thread // The following threads write to this queue // - transaction manager // - timekeeper t_event_queue *evq_trans_layer; // Event queue that is handled by the phone timekeeper thread // The following threads write into this queue // - phone UAS // - phone UAC // - transaction manager t_event_queue *evq_timekeeper; // The timekeeper t_timekeeper *timekeeper; // The transaction manager t_transaction_mgr *transaction_mgr; // The phone t_phone *phone; // User interface t_userintf *ui; // Log file t_log *log_file; // System config t_sys_settings *sys_config; // Call history t_call_history *call_history; // Local address book t_address_book *ab_local; // Mime database t_mime_database *mime_database; // If a port number is passed by the user on the command line, then // that port number overrides the port from the system settings. unsigned short g_override_sip_port = 0; unsigned short g_override_rtp_port = 0; // Indicates if LinuxThreads or NPTL is active. bool threading_is_LinuxThreads; int main(int argc, char *argv[]) { string error_msg; end_app = false; memman = new t_memman(); MEMMAN_NEW(memman); translator = new t_translator(); MEMMAN_NEW(translator); connection_table = new t_connection_table(); MEMMAN_NEW(connection_table); evq_trans_mgr = new t_event_queue(); MEMMAN_NEW(evq_trans_mgr); evq_sender = new t_event_queue(); MEMMAN_NEW(evq_sender); evq_trans_layer = new t_event_queue(); MEMMAN_NEW(evq_trans_layer); evq_timekeeper = new t_event_queue(); MEMMAN_NEW(evq_timekeeper); timekeeper = new t_timekeeper(); MEMMAN_NEW(timekeeper); transaction_mgr = new t_transaction_mgr(); MEMMAN_NEW(transaction_mgr); phone = new t_phone(); MEMMAN_NEW(phone); sys_config = new t_sys_settings(); MEMMAN_NEW(sys_config); ui = new t_userintf(phone); MEMMAN_NEW(ui); // Check requirements on environment if (!sys_config->check_environment(error_msg)) { // Environment is not good ui->cb_show_msg(error_msg, MSG_CRITICAL); exit(1); } // Read system configuration if (!sys_config->read_config(error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); exit(1); } // Get default values from system configuration list config_files; list start_user_profiles = sys_config->get_start_user_profiles(); for (list::iterator i = start_user_profiles.begin(); i != start_user_profiles.end(); i++) { string config_file = *i; config_file += USER_FILE_EXT; config_files.push_back(config_file); } #if 0 // DEPRECATED if (user_host.empty()) { string ip; if (exists_interface(sys_config->get_start_user_host())) { user_host = sys_config->get_start_user_host(); } else if (exists_interface_dev(sys_config->get_start_user_nic(), ip)) { user_host = ip; } } #endif user_host = AUTO_IP4_ADDRESS; local_hostname = get_local_hostname(); // Create a lock file to guarantee that the application // runs only once. bool already_running; if (!sys_config->create_lock_file(false, error_msg, already_running)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); exit(1); } log_file = new t_log(); MEMMAN_NEW(log_file); call_history = new t_call_history(); MEMMAN_NEW(call_history); // Determine threading implementation threading_is_LinuxThreads = t_thread::is_LinuxThreads(); if (threading_is_LinuxThreads) { log_file->write_report("Threading implementation is LinuxThreads.", "::main", LOG_NORMAL, LOG_INFO); } else { log_file->write_report("Threading implementation is NPTL.", "::main", LOG_NORMAL, LOG_INFO); } // Take default user profile if there are is no default is sys settings if (config_files.empty()) config_files.push_back(USER_CONFIG_FILE); // Read user configurations. if (argc >= 2) { config_files.clear(); for (int i = 1; i < argc; i++) { config_files.push_back(argv[i]); } } // Activate users for (list::iterator i = config_files.begin(); i != config_files.end(); i++) { t_user *user_config = new t_user(); MEMMAN_NEW(user_config); if (!user_config->read_config(*i, error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } t_user *dup_user; if(!phone->add_phone_user(*user_config, &dup_user)) { error_msg = "The following profiles are both for user "; error_msg += user_config->get_name(); error_msg += '@'; error_msg += user_config->get_domain(); error_msg += ":\n\n"; error_msg += user_config->get_profile_name(); error_msg += "\n"; error_msg += dup_user->get_profile_name(); error_msg += "\n\n"; error_msg += "You can only run multiple profiles "; error_msg += "for different users."; ui->cb_show_msg(error_msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } MEMMAN_DELETE(user_config); delete user_config; } // Read call history if (!call_history->load(error_msg)) { log_file->write_report(error_msg, "::main", LOG_NORMAL, LOG_WARNING); } // Create local address book ab_local = new t_address_book(); MEMMAN_NEW(ab_local); // Read local address book if (!ab_local->load(error_msg)) { log_file->write_report(error_msg, "::main", LOG_NORMAL, LOG_WARNING); ui->cb_show_msg(error_msg, MSG_WARNING); } // Create mime database mime_database = new t_mime_database(); MEMMAN_NEW(mime_database); if (!mime_database->load(error_msg)) { log_file->write_report(error_msg, "::main", LOG_NORMAL, LOG_WARNING); } // Initialize RTP port settings. phone->init_rtp_ports(); // Open UDP socket for SIP signaling try { sip_socket = new t_socket_udp(sys_config->get_sip_port()); MEMMAN_NEW(sip_socket); if (sip_socket->enable_icmp()) { log_file->write_report("ICMP processing enabled.", "::main"); } else { log_file->write_report("ICMP processing disabled.", "::main"); } } catch (int err) { string msg("Failed to create a UDP socket (SIP) on port "); msg += int2str(sys_config->get_sip_port()); msg += "\n"; msg += get_error_str(err); log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } // Open TCP socket for SIP signaling try { sip_socket_tcp = new t_socket_tcp(sys_config->get_sip_port()); MEMMAN_NEW(sip_socket_tcp); } catch (int err) { string msg("Failed to create a TCP socket (SIP) on port "); msg += int2str(sys_config->get_sip_port()); msg += "\n"; msg += get_error_str(err); log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } #if 0 // DEPRECATED // Pick network interface if (user_host.empty()) { user_host = ui->select_network_intf(); if (user_host.empty()) { sys_config->delete_lock_file(); exit(1); } } #endif // Discover NAT type if STUN is enabled list msg_list; if (!phone->stun_discover_nat(msg_list)) { for (list::iterator i = msg_list.begin(); i != msg_list.end(); i++) { ui->cb_show_msg(*i, MSG_WARNING); } } // Dedicated thread will catch SIGALRM, SIGINT, SIGTERM, SIGCHLD signals, // therefore all threads must block these signals. Block now, then all // created threads will inherit the signal mask. // In LinuxThreads the sigwait does not work very well, so // in LinuxThreads a signal handler is used instead. if (!threading_is_LinuxThreads) { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, NULL); } else { if (!phone->set_sighandler()) { string msg = "Failed to register signal handler."; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } } // Ignore SIGPIPE so read from broken sockets will not cause // the process to terminate. (void)signal(SIGPIPE, SIG_IGN); // Create threads t_thread *thr_sender; t_thread *thr_tcp_sender; t_thread *thr_listen_udp; t_thread *thr_listen_data_tcp; t_thread *thr_listen_conn_tcp; t_thread *thr_conn_timeout_handler; t_thread *thr_timekeeper; t_thread *thr_alarm_catcher = NULL; t_thread *thr_sig_catcher = NULL; t_thread *thr_trans_mgr; t_thread *thr_phone_uas; try { // SIP sender thread thr_sender = new t_thread(sender_loop, NULL); MEMMAN_NEW(thr_sender); // SIP TCP sender thread thr_tcp_sender = new t_thread(tcp_sender_loop, NULL); MEMMAN_NEW(thr_tcp_sender); // UDP listener thread thr_listen_udp = new t_thread(listen_udp, NULL); MEMMAN_NEW(thr_listen_udp); // TCP data listener thread thr_listen_data_tcp = new t_thread(listen_for_data_tcp, NULL); MEMMAN_NEW(thr_listen_data_tcp); // TCP connection listener thread thr_listen_conn_tcp = new t_thread(listen_for_conn_requests_tcp, NULL); MEMMAN_NEW(thr_listen_conn_tcp); // Connection timeout handler thread thr_conn_timeout_handler = new t_thread(connection_timeout_main, NULL); MEMMAN_NEW(thr_conn_timeout_handler); // Timekeeper thread thr_timekeeper = new t_thread(timekeeper_main, NULL); MEMMAN_NEW(thr_timekeeper); if (!threading_is_LinuxThreads) { // Alarm catcher thread thr_alarm_catcher = new t_thread(timekeeper_sigwait, NULL); MEMMAN_NEW(thr_alarm_catcher); // Signal catcher thread thr_sig_catcher = new t_thread(phone_sigwait, NULL); MEMMAN_NEW(thr_sig_catcher); } // Transaction manager thread thr_trans_mgr = new t_thread(transaction_mgr_main, NULL); MEMMAN_NEW(thr_trans_mgr); // Phone thread (UAS) thr_phone_uas = new t_thread(phone_uas_main, NULL); MEMMAN_NEW(thr_phone_uas); } catch (int) { string msg = "Failed to create threads."; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } // Validate sound devices if (!sys_config->exec_audio_validation(true, true, true, error_msg)) { ui->cb_show_msg(error_msg, MSG_WARNING); } try { ui->run(); } catch (string e) { string msg = "Exception: "; msg += e; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } catch (...) { string msg = "Unknown exception"; log_file->write_report(msg, "::main", LOG_NORMAL, LOG_CRITICAL); ui->cb_show_msg(msg, MSG_CRITICAL); sys_config->delete_lock_file(); exit(1); } // Application is ending end_app = true; // Kill the threads getting receiving input from the outside world first, // so no new inputs come in during termination. thr_listen_udp->cancel(); thr_listen_udp->join(); thr_listen_conn_tcp->cancel(); thr_listen_conn_tcp->join(); connection_table->cancel_select(); thr_listen_data_tcp->join(); thr_conn_timeout_handler->join(); thr_tcp_sender->join(); evq_trans_layer->push_quit(); thr_phone_uas->join(); evq_trans_mgr->push_quit(); thr_trans_mgr->join(); if (!threading_is_LinuxThreads) { try { thr_sig_catcher->cancel(); } catch (int) { // Thread terminated already by itself } thr_sig_catcher->join(); thr_alarm_catcher->cancel(); thr_alarm_catcher->join(); } evq_timekeeper->push_quit(); thr_timekeeper->join(); evq_sender->push_quit(); thr_sender->join(); sys_config->remove_all_tmp_files(); MEMMAN_DELETE(thr_phone_uas); delete thr_phone_uas; MEMMAN_DELETE(thr_trans_mgr); delete thr_trans_mgr; MEMMAN_DELETE(thr_timekeeper); delete thr_timekeeper; MEMMAN_DELETE(thr_conn_timeout_handler); delete thr_conn_timeout_handler; if (!threading_is_LinuxThreads) { MEMMAN_DELETE(thr_sig_catcher); delete thr_sig_catcher; MEMMAN_DELETE(thr_alarm_catcher); delete thr_alarm_catcher; } MEMMAN_DELETE(thr_listen_udp); delete thr_listen_udp; MEMMAN_DELETE(thr_sender); delete thr_sender; MEMMAN_DELETE(thr_tcp_sender); delete thr_tcp_sender; MEMMAN_DELETE(thr_listen_data_tcp); delete thr_listen_data_tcp; MEMMAN_DELETE(thr_listen_conn_tcp); delete thr_listen_conn_tcp; MEMMAN_DELETE(mime_database); delete mime_database; MEMMAN_DELETE(ab_local); delete ab_local; MEMMAN_DELETE(call_history); delete call_history; MEMMAN_DELETE(ui); delete ui; ui = NULL; MEMMAN_DELETE(connection_table); delete connection_table; MEMMAN_DELETE(sip_socket_tcp); delete sip_socket_tcp; MEMMAN_DELETE(sip_socket); delete sip_socket; MEMMAN_DELETE(phone); delete phone; MEMMAN_DELETE(transaction_mgr); delete transaction_mgr; MEMMAN_DELETE(timekeeper); delete timekeeper; MEMMAN_DELETE(evq_trans_mgr); delete evq_trans_mgr; MEMMAN_DELETE(evq_sender); delete evq_sender; MEMMAN_DELETE(evq_trans_layer); delete evq_trans_layer; MEMMAN_DELETE(evq_timekeeper); delete evq_timekeeper; MEMMAN_DELETE(translator); delete translator; translator = NULL; // Report memory leaks // Report deletion of log_file and sys_config already to get // a correct report. MEMMAN_DELETE(sys_config); MEMMAN_DELETE(log_file); MEMMAN_DELETE(memman); MEMMAN_REPORT; delete log_file; delete memman; sys_config->delete_lock_file(); delete sys_config; } twinkle-1.4.2/src/sockets/0000777000175000001440000000000011151327751012441 500000000000000twinkle-1.4.2/src/sockets/dnssrv.h0000644000175000001440000000214311127714046014045 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _DNSSRV_H #define _DNSSRV_H #include #include using namespace std; typedef struct { string hostname; unsigned short port; } t_dns_result; void insrv_init (unsigned long flags); int insrv_lookup (const char *service, const char *proto, const char *domain, list &result); #endif twinkle-1.4.2/src/sockets/connection_table.h0000644000175000001440000001241211127714046016034 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Connection table */ #ifndef _H_CONNECTION_TABLE #define _H_CONNECTION_TABLE #include #include #include #include #include "connection.h" #include "threads/mutex.h" using namespace std; /** Table of established connections. */ class t_connection_table { private: /** Established connections */ list connections_; /** Mutex to protect concurrent access to the connections. */ static t_recursive_mutex mtx_connections_; /** Indicates if the connection table is terminated. */ bool terminated_; /** Pipe to signal modification of the list of readable connections. */ int fd_pipe_modified_read_[2]; /** Pipe to signal modification of the list of connections with data to send. */ int fd_pipe_modified_write_[2]; /** Pipe to signal the read select operation to quit. */ int fd_pipe_quit_read_[2]; /** Pipe to signal the write select operation to quit. */ int fd_pipe_quit_write_[2]; /** Create a pipe. */ void create_pipe(int p[2]); /** Send a modification signal on the read modification pipe. */ void signal_modification_read(void); /** Send a modification signal on the write modification pipe. */ void signal_modification_write(void); /** Send a quit signal on the modification pipes. */ void signal_quit(void); public: typedef list::size_type size_type; /** Constructor */ t_connection_table(); /** * Destructor. * @note All connections in the table will be closed * and destroyed. */ ~t_connection_table(); /** * Unlock connection table. * @note After some operations, the table stays lock to avoid race * conditions. The caller should unlock the table explicitly * when it has finished working on the connections. */ void unlock(void) const; /** * Check if connection table is empty. * @return true if empty, false if not empty. */ bool empty(void) const; /** * Get number of connections in table. * @return number of connections. */ size_type size(void) const; /** * Add a connection to the table. * @param connection [in] Connection to add. */ void add_connection(t_connection *connection); /** * Remove a TCP connection from the table. * @param connection [in] TCP connection to remove. */ void remove_connection(t_connection *connection); /** * Get a connection to a particular destination. * @param remote_addr [in] IP address of destination. * @param remote_port [in] Port of destination. * @return The connection to the destination. If there is no * connection to the destination, then NULL is returned. * @post If a connection is returned, the table is locked. The caller must * unlock the tbale when it is finished with the connection. * @note Only re-usable connections are considered. */ t_connection *get_connection(unsigned long remote_addr, unsigned short remote_port); /** * Wait for connections to become readable. * @param timeout [in] Maxmimum time to wait. If NULL, then wait indefinitely. * @return List of sockets that are readable. * @throw int Errno * @post The transaction table is locked if a non-empty list of sockets is returned. * @note The caller should unlock the table when processing of the sockets is finished. */ list select_read(struct timeval *timeout) const; /** * Wait for connections to become writeable. * Only connections with data to send are waited for. * @param timeout [in] Maxmimum time to wait. If NULL, then wait indefinitely. * @return List of sockets that are writable. * @throw int Errno * @post The transaction table is locked if a non-empty list of sockets is returned. * @note The caller should unlock the table when processing of the sockets is finished. */ list select_write(struct timeval *timeout) const; /** Cancel all selects. */ void cancel_select(void); /** Restart write select, so new connections with data are picked up. */ void restart_write_select(void); /** * Close all idle connections. * Increment the idle time of all connections with interval. * A persistent connection with associated registered URI's will not be closed. * @param interval [in] Interval to add to idle time (ms). * @param terminated [out] Indicates if the connection table has been terminated. */ void close_idle_connections(unsigned long interval, bool &terminated); }; /** Main for thread handling connection timeouts */ void *connection_timeout_main(void *arg); #endif twinkle-1.4.2/src/sockets/url.h0000644000175000001440000001742011134627726013342 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_URL #define _H_URL #include #include #include "parser/header.h" /** @name Forward declarations */ //@{ class t_user; //@} using namespace std; class t_ip_port { public: string transport; unsigned long ipaddr; unsigned short port; t_ip_port() : transport("udp") {}; t_ip_port(unsigned long _ipaddr, unsigned short _port); t_ip_port(const string &proto, unsigned long _ipaddr, unsigned short _port); void clear(void); bool is_null(void) const; bool operator==(const t_ip_port &other) const; bool operator!=(const t_ip_port &other) const; string tostring(void) const; }; // Return the default port for a protocol (host order) unsigned short get_default_port(const string &protocol); // Return the first IP address of host name. // Return 0 if no IP address can be found. unsigned long gethostbyname(const string &name); // Return all IP address of host name list gethostbyname_all(const string &name); /** * Get local host name. * @return Local host name. */ string get_local_hostname(void); /** * Get the source IP address that will be used for sending * a packet to a certain destination. * @param dst_ip4 [in] The destination IPv4 address. * @return The source IPv4 address. * @return 0 if the source address cannot be determined. */ unsigned long get_src_ip4_address_for_dst(unsigned long dst_ip4); class t_url { private: /** * A t_url object is created with a string represnetation of * the URL. The encode method just returns this string. * If one of the components of the t_url object is modified * however, then encode will build a new string representation. * The modified flag indicates if the object was modified after * construction. */ bool modified; /** URL scheme. */ string scheme; /** The user part of a URL. For a tel URL this is empty. */ string user; /** The user password. */ string password; /** * The host part of a URL. For a tel URL, it contains the part before * the first semi-colon. */ string host; unsigned short port; // host order // parameters string transport; string maddr; bool lr; string user_param; string method; int ttl; string other_params; // unparsed other parameters // starting with a semi-colon // headers string headers; // unparsed headers bool user_url; // true -> user url // false -> machine bool valid; // indicates if the url is valid string text_format; // url in string format void construct_user_url(const string &s); // eg sip:, mailto: void construct_machine_url(const string &s); // eg http:, ftp: // Parse uri parameters and headers. Returns false if parsing // fails. bool parse_params_headers(const string &s); public: // Escape reserved symbols in a user value static string escape_user_value(const string &user_value); // Escape reserved symbols in a password value static string escape_passwd_value(const string &passwd_value); // Escape reserved symbols in a header name or value static string escape_hnv(const string &hnv); public: t_url(); t_url(const string &s); // Return a copy of the URI without headers. // If the URI does not contain any headers, then the copy is // identical to the URI. t_url copy_without_headers(void) const; void set_url(const string &s); // Returns "" or 0 if item cannot be found string get_scheme(void) const; string get_user(void) const; string get_password(void) const; string get_host(void) const; // The following methods will return the default port if // no port is present in the url. int get_nport(void) const; // Get port in network order. int get_hport(void) const; // get port in host order. // The following method returns 0 if no port is present // in the url. int get_port(void) const; // ip address network order. Return 0 if address not found // DNS A RR lookup unsigned long get_n_ip(void) const; // ip address host order. Return 0 if address not found // DNS A RR lookup unsigned long get_h_ip(void) const; list get_h_ip_all(void) const; // DNS A RR lookup string get_ip(void) const; // ip address as string // Get list op IP address/ports in host order. // First do DNS SRV lookup. If no SRV RR's are found, then // do a DNS A RR lookup. // transport = the transport protocol for the service list get_h_ip_srv(const string &transport) const; /** @name Getters */ //@{ string get_transport(void) const; string get_maddr(void) const; bool get_lr(void) const; string get_user_param(void) const; string get_method(void) const; int get_ttl(void) const; string get_other_params(void) const; string get_headers(void) const; //@} /** @name Setters */ //@{ void set_user(const string &u); void set_host(const string &h); //@} /** * Add a header to the URI. * The encoded header will be concatenated to the headers field. * @param hdr [in] Header to be added. */ void add_header(const t_header &hdr); /** Remove headers from the URI. */ void clear_headers(void); /** * Check if the URI is valid. * @return True if valid, otherwise false. */ bool is_valid(void) const; // Check if 2 sip or sips url's are equivalent bool sip_match(const t_url &u) const; bool operator==(const t_url &u) const; bool operator!=(const t_url &u) const; /** * Check if the user-host part of 2 url's are equal. * If the user-part is a phone number, then only compare * the user parts. If the url is a tel-url then the host * contains a telephone number for comparison. * @param u [in] Other URL to compare with. * @param looks_like_phone [in] Flag to indicate is a SIP URL * that looks like a phone number must be treated as such. * @param special_symbols [in] Interpuction symbols in a phone number. * @return true if the URLs match, false otherwise. */ bool user_host_match(const t_url &u, bool looks_like_phone, const string &special_symbols) const; // Return true if the user part looks like a phone number, i.e. // consists of digits, *, # and special symbols bool user_looks_like_phone(const string &special_symbols) const; // Return true if the URI indicates a phone number, i.e. // - the user=phone parameter is present // or // - if looks_like_phone == true and the user part looks like // a phone number bool is_phone(bool looks_like_phone, const string &special_symbols) const; // Return string encoding of url string encode(void) const; // Return string encoding of url without scheme information string encode_noscheme(void) const; // Return string encoding of url without parameters/headers string encode_no_params_hdrs(bool escape = true) const; /** * Apply number conversion rules to modify the URL. * @param user_config [in] The user profile having the conversion * rules to apply. */ void apply_conversion_rules(t_user *user_config); }; // Display name and url combined class t_display_url { public: t_url url; string display; t_display_url(); t_display_url(const t_url &_url, const string &_display); bool is_valid(); string encode(void) const; }; #endif twinkle-1.4.2/src/sockets/dnssrv.cpp0000644000175000001440000001000511134636222014371 00000000000000/* This software is copyrighted (c) 2002 Rick van Rein, the Netherlands. This software has been modified by Michel de Boer. 2005 */ #include "dnssrv.h" #include #include #include #include #include #include #include #include #include #include #include #include /* Common offsets into an SRV RR */ #define SRV_COST (RRFIXEDSZ+0) #define SRV_WEIGHT (RRFIXEDSZ+2) #define SRV_PORT (RRFIXEDSZ+4) #define SRV_SERVER (RRFIXEDSZ+6) #define SRV_FIXEDSZ (RRFIXEDSZ+6) /* Data structures */ typedef struct { unsigned char buf [PACKETSZ]; int len; } iobuf; typedef char name [MAXDNAME]; #define MAXNUM_SRV PACKETSZ /* Local variable for SRV options */ static unsigned long int srv_flags = 0L; /* Setup the SRV options when initialising -- invocation optional */ void insrv_init (unsigned long flags) { #ifdef HAVE_RES_INIT srv_flags = flags; res_init (); #endif } /* Test the given SRV options to see if all are set */ int srv_testflag (unsigned long flags) { return ((srv_flags & flags) == flags) ? 1 : 0; } /* Compare two SRV records by priority and by (scattered) weight */ int srvcmp (const void *left, const void *right) { int lcost = ntohs (((unsigned short **) left ) [0][5]); int rcost = ntohs (((unsigned short **) right) [0][5]); if (lcost == rcost) { lcost = -ntohs (((unsigned short **) left ) [0][6]); rcost = -ntohs (((unsigned short **) right) [0][6]); } if (lcost < rcost) { return -1; } else if (lcost > rcost) { return +1; } else { return 0; } } /* Setup a client socket for the named service over the given protocol under * the given domain name. */ int insrv_lookup (const char *service, const char *proto, const char *domain, list &result) { // 1. convert service/proto to svcnm // 2. construct SRV query for _service._proto.domain iobuf names; name svcnm; int ctr; int rnd; HEADER *nameshdr; unsigned char *here, *srv[MAXNUM_SRV]; int num_srv=0; // Storage for fallback SRV list, constructed when DNS gives no SRV //unsigned char fallbacksrv [2*(MAXCDNAME+SRV_FIXEDSZ+MAXCDNAME)]; // srv_flags &= ~SRV_GOT_MASK; // srv_flags |= SRV_GOT_SRV; strcpy (svcnm, "_"); strcat (svcnm, service); strcat (svcnm, "._"); strcat (svcnm, proto); // Note that SRV records are only defined for class IN if (domain) { names.len=res_querydomain (svcnm, domain, C_IN, T_SRV, names.buf, PACKETSZ); } else { names.len=res_query (svcnm, C_IN, T_SRV, names.buf, PACKETSZ); } if (names.len < 0) { return -ENOENT; } nameshdr=(HEADER *) names.buf; here=names.buf + HFIXEDSZ; rnd=nameshdr->id; // Heck, gimme one reason why not! if ((names.len < HFIXEDSZ) || nameshdr->tc) { return -EMSGSIZE; } switch (nameshdr->rcode) { case 1: return -EFAULT; case 2: return -EAGAIN; case 3: return -ENOENT; case 4: return -ENOSYS; case 5: return -EPERM; default: break; } if (ntohs (nameshdr->ancount) == 0) { return -ENOENT; } if (ntohs (nameshdr->ancount) > MAXNUM_SRV) { return -ERANGE; } for (ctr=ntohs (nameshdr->qdcount); ctr>0; ctr--) { int strlen=dn_skipname (here, names.buf+names.len); here += strlen + QFIXEDSZ; } for (ctr=ntohs (nameshdr->ancount); ctr>0; ctr--) { int strlen=dn_skipname (here, names.buf+names.len); here += strlen; srv [num_srv++] = here; here += SRV_FIXEDSZ; here += dn_skipname (here, names.buf+names.len); } // Overwrite weight with rnd-spread version to divide load over weights for (ctr=0; ctr This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "interfaces.h" #include "url.h" using namespace std; t_interface::t_interface(string _name) : name(_name) {} string t_interface::get_ip_addr(void) const { return inet_ntoa(address); } string t_interface::get_ip_netmask(void) const { return inet_ntoa(netmask); } list *get_interfaces(bool include_loopback) { struct ifaddrs *ifa, *ifaddrs; struct sockaddr_in *sin; t_interface *intf; list *result = new list; if (getifaddrs(&ifaddrs)) { // No interfaces found return result; } for (ifa = ifaddrs; ifa ; ifa = ifa -> ifa_next) { // Skip interface without address // Skip interfaces marked DOWN and LOOPBACK. if (ifa->ifa_addr == NULL || !(ifa->ifa_flags & IFF_UP) || ((ifa->ifa_flags & IFF_LOOPBACK) && !include_loopback)) { continue; } // Add the interface to the list if it has an IP4 address switch(ifa->ifa_addr->sa_family) { case AF_INET: intf = new t_interface(ifa->ifa_name); sin = (struct sockaddr_in *)ifa->ifa_addr; memcpy(&intf->address, &sin->sin_addr, sizeof(struct in_addr)); sin = (struct sockaddr_in *)ifa->ifa_netmask; memcpy(&intf->netmask, &sin->sin_addr, sizeof(struct in_addr)); result->push_back(*intf); delete intf; break; } } freeifaddrs(ifaddrs); return result; } bool exists_interface(const string &hostname) { struct hostent *h; h = gethostbyname(hostname.c_str()); if (h == NULL) return false; string ipaddr = inet_ntoa(*((struct in_addr *)h->h_addr)); list *l = get_interfaces(true); for (list::iterator i = l->begin(); i != l->end(); i++) { if (i->get_ip_addr() == ipaddr) { delete l; return true; } } delete l; return false; } bool exists_interface_dev(const string &devname, string &ip_address) { list *l = get_interfaces(true); for (list::iterator i = l->begin(); i != l->end(); i++) { if (i->name == devname) { ip_address = i->get_ip_addr(); delete l; return true; } } delete l; return false; } twinkle-1.4.2/src/sockets/interfaces.h0000644000175000001440000000336511127714046014660 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_INTERFACES #define _H_INTERFACES #include #include #include #include #include #include #include #include using namespace std; class t_interface { public: string name; // interface name, eg. eth0 struct in_addr address; // interface IP address struct in_addr netmask; // interface netmask t_interface(string _name); // Get string representation of IP address string get_ip_addr(void) const; string get_ip_netmask(void) const; }; // Return a list of all interfaces that are UP // If include_loopback == true, then the loopback interface is returned as well. list *get_interfaces(bool include_loopback = false); // Check if an interface with a certain IP address exists bool exists_interface(const string &hostname); // Check if an interface exists and return its IP address bool exists_interface_dev(const string &devname, string &ip_address); #endif twinkle-1.4.2/src/sockets/connection_table.cpp0000644000175000001440000002550711133434363016376 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "connection_table.h" #include #include #include #include #include #include #include #include #include "log.h" #include "protocol.h" #include "util.h" #include "audits/memman.h" using namespace std; extern t_connection_table *connection_table; void t_connection_table::create_pipe(int p[2]) { if (pipe(p) == -1) { string err = get_error_str(errno); cerr << "FATAL: t_connection_table - Cannot create pipe.\n"; cerr << err << endl; exit(-1); } if (fcntl(p[0], F_SETFL, O_NONBLOCK) == -1) { string err = get_error_str(errno); cerr << "FATAL: t_connection_table - fcntl fails on read side of pipe.\n"; cerr << err << endl; exit(-1); } if (fcntl(p[1], F_SETFL, O_NONBLOCK) == -1) { string err = get_error_str(errno); cerr << "FATAL: t_connection_table - fcntl fails on write side of pipe.\n"; cerr << err << endl; exit(-1); } } void t_connection_table::signal_modification_read(void) { t_mutex_guard guard(mtx_connections_); // Write a byte to the modified pipe, so a select can be retried. char x = 'x'; (void)write(fd_pipe_modified_read_[1], &x, 1); } void t_connection_table::signal_modification_write(void) { t_mutex_guard guard(mtx_connections_); // Write a byte to the modified pipe, so a select can be retried. char x = 'x'; (void)write(fd_pipe_modified_write_[1], &x, 1); } void t_connection_table::signal_quit(void) { t_mutex_guard guard(mtx_connections_); // Write a byte to the quit pipe, so a select can be halted. char x = 'x'; (void)write(fd_pipe_quit_read_[1], &x, 1); (void)write(fd_pipe_quit_write_[1], &x, 1); terminated_ = true; } t_recursive_mutex t_connection_table::mtx_connections_; t_connection_table::t_connection_table() : terminated_(false) { create_pipe(fd_pipe_modified_read_); create_pipe(fd_pipe_modified_write_); create_pipe(fd_pipe_quit_read_); create_pipe(fd_pipe_quit_write_); } t_connection_table::~t_connection_table() { t_mutex_guard guard(mtx_connections_); for (list::iterator it = connections_.begin(); it != connections_.end(); ++it) { MEMMAN_DELETE(*it); delete *it; } } void t_connection_table::unlock(void) const { mtx_connections_.unlock(); } bool t_connection_table::empty(void) const { t_mutex_guard guard(mtx_connections_); return connections_.empty(); } t_connection_table::size_type t_connection_table::size(void) const { t_mutex_guard guard(mtx_connections_); return connections_.size(); } void t_connection_table::add_connection(t_connection *connection) { t_mutex_guard guard(mtx_connections_); connections_.push_back(connection); signal_modification_read(); signal_modification_write(); } void t_connection_table::remove_connection(t_connection *connection) { t_mutex_guard guard(mtx_connections_); connections_.remove(connection); signal_modification_read(); signal_modification_write(); } t_connection *t_connection_table::get_connection(unsigned long remote_addr, unsigned short remote_port) { mtx_connections_.lock(); t_connection *found_connection = NULL; list broken_connections; for (list::iterator it = connections_.begin(); it != connections_.end(); ++it) { unsigned long addr; unsigned short port; if ((*it)->may_reuse()) { try { t_socket *socket = (*it)->get_socket(); t_socket_tcp *tcp_socket = dynamic_cast(socket); if (tcp_socket) { tcp_socket->get_remote_address(addr, port); if (addr == remote_addr && port == remote_port) { found_connection = *it; break; } } } catch (int err) { // This should never happen. cerr << "Cannot get remote address of socket." << endl; // Destroy and remove connection as it is probably broken. broken_connections.push_back(*it); } } } // Clear broken connections for (list::iterator it = broken_connections.begin(); it != broken_connections.end(); ++it) { remove_connection(*it); MEMMAN_DELETE(*it); delete *it; } if (!found_connection) mtx_connections_.unlock(); return found_connection; } list t_connection_table::select_read(struct timeval *timeout) const { fd_set read_fds; int nfds = 0; bool retry = true; list result; // Empty modification pipe char pipe_buf; while (read(fd_pipe_modified_read_[0], &pipe_buf, 1) > 0); while (retry) { FD_ZERO(&read_fds); // Add modification pipe so select can be restarted when the // connection table modifies. FD_SET(fd_pipe_modified_read_[0], &read_fds); nfds = fd_pipe_modified_read_[0]; // Add quit pipe so select can quit on demand. FD_SET(fd_pipe_quit_read_[0], &read_fds); nfds = max(nfds, fd_pipe_quit_read_[0]); mtx_connections_.lock(); for (list::const_iterator it = connections_.begin(); it != connections_.end(); ++it) { t_socket *socket = (*it)->get_socket(); int fd = socket->get_descriptor(); FD_SET(fd, &read_fds); nfds = max(nfds, fd); } mtx_connections_.unlock(); int ret = select(nfds + 1, &read_fds, NULL, NULL, timeout); if (ret < 0) throw errno; if (FD_ISSET(fd_pipe_quit_read_[0], &read_fds)) { // Quit was signalled, so stop immediately. break; } mtx_connections_.lock(); // Determine which sockets have become readable for (list::const_iterator it = connections_.begin(); it != connections_.end(); ++it) { t_socket *socket = (*it)->get_socket(); int fd = socket->get_descriptor(); if (FD_ISSET(fd, &read_fds)) { result.push_back(*it); } } if (!result.empty()) { // Connections have become readable, so return to the caller. retry = false; } else { mtx_connections_.unlock(); // No connections have become readable. Check signal descriptors if (FD_ISSET(fd_pipe_modified_read_[0], &read_fds)) { // The connection table is modified. Retry select. read(fd_pipe_modified_read_[0], &pipe_buf, 1); } else { // This should never happen. cerr << "ERROR: select_read returned without any file descriptor." << endl; } } } return result; } list t_connection_table::select_write(struct timeval *timeout) const { fd_set read_fds; fd_set write_fds; int nfds = 0; bool retry = true; list result; // Empty modification pipe char pipe_buf; while (read(fd_pipe_modified_write_[0], &pipe_buf, 1) > 0); while (retry) { FD_ZERO(&read_fds); FD_ZERO(&write_fds); // Add modification pipe so select can be restarted when the // connection table modifies. FD_SET(fd_pipe_modified_write_[0], &read_fds); nfds = fd_pipe_modified_write_[0]; // Add quit pipe so select can quit on demand. FD_SET(fd_pipe_quit_write_[0], &read_fds); nfds = max(nfds, fd_pipe_quit_write_[0]); mtx_connections_.lock(); for (list::const_iterator it = connections_.begin(); it != connections_.end(); ++it) { if ((*it)->has_data_to_send()) { t_socket *socket = (*it)->get_socket(); int fd = socket->get_descriptor(); FD_SET(fd, &write_fds); nfds = max(nfds, fd); } } mtx_connections_.unlock(); int ret = select(nfds + 1, &read_fds, &write_fds, NULL, timeout); if (ret < 0) throw errno; if (FD_ISSET(fd_pipe_quit_write_[0], &read_fds)) { // Quit was signalled, so stop immediately. break; } mtx_connections_.lock(); // Determine which sockets have become writable for (list::const_iterator it = connections_.begin(); it != connections_.end(); ++it) { t_socket *socket = (*it)->get_socket(); int fd = socket->get_descriptor(); if (FD_ISSET(fd, &write_fds)) { result.push_back(*it); } } if (!result.empty()) { // Connections have become writable, so return to the caller. retry = false; } else { mtx_connections_.unlock(); // No connections have become writable. Check signal descriptors if (FD_ISSET(fd_pipe_modified_write_[0], &read_fds)) { // The connection table is modified. Retry select. read(fd_pipe_modified_write_[0], &pipe_buf, 1); } else { // This should never happen. cerr << "ERROR: select_write returned without any file descriptor." << endl; } } } return result; } void t_connection_table::cancel_select(void) { signal_quit(); } void t_connection_table::restart_write_select(void) { signal_modification_write(); } void t_connection_table::close_idle_connections(unsigned long interval, bool &terminated) { t_mutex_guard guard(mtx_connections_); terminated = terminated_; list expired_connections; // Update idle times and find expired connections. for (list::iterator it = connections_.begin(); it != connections_.end(); ++it) { unsigned long idle_time = (*it)->increment_idle_time(interval); if (idle_time >= DUR_IDLE_CONNECTION || terminated) { // If a registered URI is associated with the connection, then // it is persistent and it should not be closed. if (!(*it)->has_registered_uri()) { expired_connections.push_back(*it); } } } // Close expired connections. for (list::iterator it = expired_connections.begin(); it != expired_connections.end(); ++it) { unsigned long ipaddr; unsigned short port; (*it)->get_remote_address(ipaddr, port); log_file->write_header("t_connection_table::close_idle_connections", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Close connection to "); log_file->write_raw(h_ip2str(ipaddr)); log_file->write_raw(":"); log_file->write_raw(int2str(port)); log_file->write_endl(); log_file->write_footer(); remove_connection(*it); MEMMAN_DELETE(*it); delete *it; } } void *connection_timeout_main(void *arg) { bool terminated = false; while (!terminated) { struct timespec sleep_timer; sleep_timer.tv_sec = 1; sleep_timer.tv_nsec = 0; nanosleep(&sleep_timer, NULL); connection_table->close_idle_connections(1000, terminated); } log_file->write_report("Connection timeout handler terminated.", "::connection_timeout_main"); return NULL; }; twinkle-1.4.2/src/sockets/Makefile.am0000644000175000001440000000121311134651172014404 00000000000000AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src\ $(XML2_CFLAGS) noinst_LIBRARIES = libsocket.a #noinst_PROGRAMS = srvinfo urlinfo #srvinfo_SOURCES = srvinfo.cpp #srvinfo_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/sockets/libsocket.a\ # -lresolv #urlinfo_SOURCES = urlinfo.cpp #urlinfo_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/sockets/libsocket.a\ # -lresolv libsocket_a_SOURCES =\ connection.cpp\ connection_table.cpp\ dnssrv.cpp\ interfaces.cpp\ socket.cpp\ url.cpp\ connection.h\ connection_table.h\ dnssrv.h\ interfaces.h\ socket.h\ url.h twinkle-1.4.2/src/sockets/Makefile.in0000644000175000001440000004106511151323410014414 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/sockets DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libsocket_a_AR = $(AR) $(ARFLAGS) libsocket_a_LIBADD = am_libsocket_a_OBJECTS = connection.$(OBJEXT) \ connection_table.$(OBJEXT) dnssrv.$(OBJEXT) \ interfaces.$(OBJEXT) socket.$(OBJEXT) url.$(OBJEXT) libsocket_a_OBJECTS = $(am_libsocket_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libsocket_a_SOURCES) DIST_SOURCES = $(libsocket_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src\ $(XML2_CFLAGS) noinst_LIBRARIES = libsocket.a #noinst_PROGRAMS = srvinfo urlinfo #srvinfo_SOURCES = srvinfo.cpp #srvinfo_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/sockets/libsocket.a\ # -lresolv #urlinfo_SOURCES = urlinfo.cpp #urlinfo_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/sockets/libsocket.a\ # -lresolv libsocket_a_SOURCES = \ connection.cpp\ connection_table.cpp\ dnssrv.cpp\ interfaces.cpp\ socket.cpp\ url.cpp\ connection.h\ connection_table.h\ dnssrv.h\ interfaces.h\ socket.h\ url.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sockets/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/sockets/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libsocket.a: $(libsocket_a_OBJECTS) $(libsocket_a_DEPENDENCIES) -rm -f libsocket.a $(libsocket_a_AR) libsocket.a $(libsocket_a_OBJECTS) $(libsocket_a_LIBADD) $(RANLIB) libsocket.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection_table.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dnssrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interfaces.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/sockets/socket.cpp0000644000175000001440000002460511134636276014366 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "twinkle_config.h" #include "socket.h" #include "audits/memman.h" #if HAVE_UNISTD_H #include #endif #if HAVE_LINUX_TYPES_H #include #endif #if HAVE_LINUX_ERRQUEUE_H #include #endif ///////////////// // t_icmp_msg ///////////////// t_icmp_msg::t_icmp_msg(short _type, short _code, unsigned long _icmp_src_ipaddr, unsigned long _ipaddr, unsigned short _port) : type(_type), code(_code), icmp_src_ipaddr(_icmp_src_ipaddr), ipaddr(_ipaddr), port(_port) {} ///////////////// // t_socket ///////////////// t_socket::~t_socket() { close(sd); } t_socket::t_socket() : sd(0) {} t_socket::t_socket(int _sd) : sd(_sd) {} int t_socket::get_descriptor(void) const { return sd; } int t_socket::getsockopt(int level, int optname, void *optval, socklen_t *optlen) { return ::getsockopt(sd, level, optname, optval, optlen); } int t_socket::setsockopt(int level, int optname, const void *optval, socklen_t optlen) { return ::setsockopt(sd, level, optname, optval, optlen); } ///////////////// // t_socket_udp ///////////////// t_socket_udp::t_socket_udp() { struct sockaddr_in addr; int ret; sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd < 0) throw errno; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(0); ret = bind(sd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) throw errno; } t_socket_udp::t_socket_udp(unsigned short port) { struct sockaddr_in addr; int ret; sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd < 0) throw errno; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); ret = bind(sd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) throw errno; } int t_socket_udp::connect(unsigned long dest_addr, unsigned short dest_port) { struct sockaddr_in addr; int ret; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(dest_addr); addr.sin_port = htons(dest_port); ret = ::connect(sd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) throw errno; return ret; } int t_socket_udp::sendto(unsigned long dest_addr, unsigned short dest_port, const char *data, int data_size) { struct sockaddr_in addr; int ret; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(dest_addr); addr.sin_port = htons(dest_port); ret = ::sendto(sd, data, data_size, 0, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) throw errno; return ret; } ssize_t t_socket_udp::send(const void *data, int data_size) { int ret = ::send(sd, data, data_size, 0); if (ret < 0) throw errno; return ret; } int t_socket_udp::recvfrom(unsigned long &src_addr, unsigned short &src_port, char *buf, int buf_size) { struct sockaddr_in addr; int ret, len_addr; len_addr = sizeof(addr); memset(buf, 0, buf_size); ret = ::recvfrom(sd, buf, buf_size - 1, 0, (struct sockaddr *)&addr, (socklen_t *)&len_addr); if (ret < 0) throw errno; src_addr = ntohl(addr.sin_addr.s_addr); src_port = ntohs(addr.sin_port); return ret; } ssize_t t_socket_udp::recv(void *buf, int buf_size) { int ret; memset(buf, 0, buf_size); ret = ::recv(sd, buf, buf_size - 1, 0); if (ret < 0) throw errno; return ret; } bool t_socket_udp::select_read(unsigned long timeout) { fd_set fds; struct timeval t; FD_ZERO(&fds); FD_SET(sd, &fds); t.tv_sec = timeout / 1000; t.tv_usec = (timeout % 1000) * 1000; int ret = select(sd + 1, &fds, NULL, NULL, &t); if (ret < 0) throw errno; if (ret == 0) return false; return true; } bool t_socket_udp::enable_icmp(void) { #if HAVE_LINUX_ERRQUEUE_H int enable = 1; int ret = setsockopt(SOL_IP, IP_RECVERR, &enable, sizeof(int)); if (ret < 0) return false; return true; #else return false; #endif } bool t_socket_udp::get_icmp(t_icmp_msg &icmp) { #if HAVE_LINUX_ERRQUEUE_H int ret; char buf[256]; // The destination address of the packet causing the ICMP struct sockaddr dest_addr; struct msghdr msgh; struct cmsghdr *cmsg; // Initialize message header to receive the ancillary data for // an ICMP message. memset(&msgh, 0, sizeof(struct msghdr)); msgh.msg_control = buf; msgh.msg_controllen = 256; msgh.msg_name = &dest_addr; msgh.msg_namelen = sizeof(struct sockaddr); // Get error from the socket error queue ret = recvmsg(sd, &msgh, MSG_ERRQUEUE); if (ret < 0) return false; // Find ICMP message in returned controll messages for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) { if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) { // ICMP message found sock_extended_err *err = (sock_extended_err *)CMSG_DATA(cmsg); icmp.type = err->ee_type; icmp.code = err->ee_code; // Get IP address of host that has sent the ICMP error sockaddr *sa_src_icmp = SO_EE_OFFENDER(err); if (sa_src_icmp->sa_family == AF_INET) { sockaddr_in *addr = (sockaddr_in *)sa_src_icmp; icmp.icmp_src_ipaddr = ntohl(addr->sin_addr.s_addr); } else { // Non supported address type icmp.icmp_src_ipaddr = 0; } // Get destinnation address/port of packet causing the error. if (dest_addr.sa_family == AF_INET) { sockaddr_in *addr = (sockaddr_in *)&dest_addr; icmp.ipaddr = ntohl(addr->sin_addr.s_addr); icmp.port = ntohs(addr->sin_port); return true; } else { // Non supported address type continue; } } } #endif return false; } string h_ip2str(unsigned long ipaddr) { char buf[16]; unsigned long x = htonl(ipaddr); unsigned char *ipbuf = (unsigned char *)&x; snprintf(buf, 16, "%u.%u.%u.%u", ipbuf[0], ipbuf[1], ipbuf[2], ipbuf[3]); return string(buf); } ///////////////// // t_socket_tcp ///////////////// t_socket_tcp::t_socket_tcp() { sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) throw errno; } t_socket_tcp::t_socket_tcp(unsigned short port) { struct sockaddr_in addr; int ret; sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) throw errno; int enable = 1; // Allow server to connect to the socket immediately (disable TIME_WAIT) (void)setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); enable = 1; // Disable Nagle algorithm (void)setsockopt(IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); ret = bind(sd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) throw errno; } t_socket_tcp::t_socket_tcp(int _sd) : t_socket(_sd) {} void t_socket_tcp::listen(int backlog) { int ret = ::listen(sd, backlog); if (ret < 0) throw errno; } t_socket_tcp *t_socket_tcp::accept(unsigned long &src_addr, unsigned short &src_port) { struct sockaddr_in addr; socklen_t socklen = sizeof(addr); int ret = ::accept(sd, (struct sockaddr *)&addr, &socklen); if (ret < 0) throw errno; src_addr = ntohl(addr.sin_addr.s_addr); src_port = ntohs(addr.sin_port); t_socket_tcp *sock = new t_socket_tcp(ret); MEMMAN_NEW(sock); return sock; } void t_socket_tcp::connect(unsigned long dest_addr, unsigned short dest_port) { struct sockaddr_in addr; int ret; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(dest_addr); addr.sin_port = htons(dest_port); ret = ::connect(sd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) throw errno; } ssize_t t_socket_tcp::send(const void *data, int data_size) { ssize_t ret = ::send(sd, data, data_size, 0); if (ret < 0) throw errno; return ret; } ssize_t t_socket_tcp::recv(void *buf, int buf_size) { ssize_t ret; ret = ::recv(sd, buf, buf_size, 0); if (ret < 0) throw errno; return ret; } void t_socket_tcp::get_remote_address(unsigned long &remote_addr, unsigned short &remote_port) { struct sockaddr_in addr; socklen_t namelen = sizeof(addr); int ret = getpeername(sd, (struct sockaddr *)&addr, &namelen); if (ret < 0) throw errno; if (addr.sin_family != AF_INET) throw EBADF; remote_addr = ntohl(addr.sin_addr.s_addr); remote_port = ntohs(addr.sin_port); }; ///////////////// // t_socket_local ///////////////// t_socket_local::t_socket_local() { sd = socket(PF_LOCAL, SOCK_STREAM, 0); if (sd < 0) throw errno; } t_socket_local::t_socket_local(int _sd) { sd = _sd; } void t_socket_local::bind(const string &name) { int ret; struct sockaddr_un sockname; // A name for a local socket can be at most 108 characters // including NULL at end of string. if (name.size() > 107) { throw ENAMETOOLONG; } sockname.sun_family = AF_LOCAL; strcpy(sockname.sun_path, name.c_str()); ret = ::bind(sd, (struct sockaddr *)&sockname, SUN_LEN(&sockname)); if (ret < 0) throw errno; } void t_socket_local::listen(int backlog) { int ret; ret = ::listen(sd, backlog); if (ret < 0) throw errno; } int t_socket_local::accept(void) { int ret; ret = ::accept(sd, NULL, 0); if (ret < 0) throw errno; return ret; } void t_socket_local::connect(const string &name) { int ret; struct sockaddr_un sockname; // A name for a local socket can be at most 108 characters // including NULL at end of string. if (name.size() > 107) { throw ENAMETOOLONG; } sockname.sun_family = AF_LOCAL; strcpy(sockname.sun_path, name.c_str()); ret = ::connect(sd, (struct sockaddr *)&sockname, SUN_LEN(&sockname)); if (ret < 0) throw errno; } int t_socket_local::read(void *buf, int count) { int ret; ret = ::read(sd, buf, count); if (ret < 0) throw errno; return ret; } ssize_t t_socket_local::recv(void *buf, int buf_size) { return read(buf, buf_size); } int t_socket_local::write(const void *buf, int count) { int ret; ret = ::write(sd, buf, count); if (ret < 0) throw errno; return ret; } ssize_t t_socket_local::send(const void *buf, int count) { return write(buf, count); } twinkle-1.4.2/src/sockets/url.cpp0000644000175000001440000004670111134636421013671 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include "dnssrv.h" #include "log.h" #include "socket.h" #include "url.h" #include "user.h" #include "util.h" using namespace std; unsigned short get_default_port(const string &protocol) { if (protocol == "mailto") return 25; if (protocol == "http") return 80; if (protocol == "sip") return 5060; if (protocol == "sips") return 5061; if (protocol == "stun") return 3478; return 0; } unsigned long gethostbyname(const string &name) { struct hostent *h; h = gethostbyname(name.c_str()); if (h == NULL) return 0; return ntohl(*((unsigned long *)h->h_addr)); } list gethostbyname_all(const string &name) { struct hostent *h; list l; h = gethostbyname(name.c_str()); if (h == NULL) return l; char **ipaddr = h->h_addr_list; while (*ipaddr) { l.push_back(ntohl(*((unsigned long *)(*ipaddr)))); ipaddr++; } return l; } string get_local_hostname(void) { char name[256]; int rc = gethostname(name, 256); if (rc < 0) { return "localhost"; } struct hostent *h = gethostbyname(name); if (h == NULL) { return "localhost"; } return h->h_name; } unsigned long get_src_ip4_address_for_dst(unsigned long dst_ip4) { string log_msg; struct sockaddr_in addr; int ret; // Create UDP socket int sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd < 0) { string err = get_error_str(errno); log_msg = "Cannot create socket: "; log_msg += err; log_file->write_report(log_msg, "::get_src_ip4_address_for_dst", LOG_NORMAL, LOG_CRITICAL); return 0; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(dst_ip4); addr.sin_port = htons(5060); // Connect to the destination. Note that no network traffic // is sent out as this is a UDP socket. The routing engine // will set the correct source address however. ret = connect(sd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { string err = get_error_str(errno); log_msg = "Cannot connect socket: "; log_msg += err; log_file->write_report(log_msg, "::get_src_ip4_address_for_dst", LOG_NORMAL, LOG_CRITICAL); close(sd); return 0; } // Get source address of socket memset(&addr, 0, sizeof(addr)); socklen_t len_addr = sizeof(addr); ret = getsockname(sd, (struct sockaddr *)&addr, &len_addr); if (ret < 0) { string err = get_error_str(errno); log_msg = "Cannot get sockname: "; log_msg += err; log_file->write_report(log_msg, "::get_src_ip4_address_for_dst", LOG_NORMAL, LOG_CRITICAL); close(sd); return 0; } close(sd); return ntohl(addr.sin_addr.s_addr); } string display_and_url2str(const string &display, const string &url) { string s; if (!display.empty()) { if (must_quote(display)) s += '"'; s += display; if (must_quote(display)) s += '"'; s += " <"; } s += url; if (!display.empty()) s += '>'; return s; } // t_ip_port t_ip_port::t_ip_port(unsigned long _ipaddr, unsigned short _port) : transport("udp"), ipaddr(_ipaddr), port(_port) {} t_ip_port::t_ip_port(const string &proto, unsigned long _ipaddr, unsigned short _port) : transport(proto), ipaddr(_ipaddr), port(_port) {} void t_ip_port::clear(void) { transport.clear(); ipaddr = 0; port = 0; } bool t_ip_port::is_null(void) const { return (ipaddr == 0 && port == 0); } bool t_ip_port::operator==(const t_ip_port &other) const { return (transport == other.transport && ipaddr == other.ipaddr && port == other.port); } bool t_ip_port::operator!=(const t_ip_port &other) const { return !operator==(other); } string t_ip_port::tostring(void) const { string s; s = transport; s += ":"; s += h_ip2str(ipaddr); s += ":"; s += int2str(port); return s; } // Private void t_url::construct_user_url(const string &s) { string::size_type i; string r; // Determine user/password (both are optional) i = s.find('@'); if (i != string::npos) { if (i == 0 || i == s.size()-1) return; string userpass = s.substr(0, i); r = s.substr(i+1); i = userpass.find(':'); if (i != string::npos) { if (i == 0 || i == userpass.size()-1) return; user = unescape_hex(userpass.substr(0, i)); password = unescape_hex(userpass.substr(i+1)); if (escape_passwd_value(password) != password) { modified = true; } } else { user = unescape_hex(userpass); } // Set modified flag if user contains reserved symbols. // This enforces escaping these symbols when the url gets // encoded. if (escape_user_value(user) != user) { modified = true; } } else { r = s; } // Determine host/port string hostport; i = r.find_first_of(";?"); if (i != string::npos) { hostport = r.substr(0, i); if (!parse_params_headers(r.substr(i))) return; } else { hostport = r; } if (hostport.empty()) return; if (hostport.at(0) == '[') { // Host contains an IPv6 reference i = hostport.find(']'); if (i == string::npos) return; // TODO: check format of an IPv6 address host = hostport.substr(0, i+1); if (i < hostport.size()-1) { if (hostport.at(i+1) != ':') return; // wrong port separator if (i+1 == hostport.size()-1) return; // port missing unsigned long p = atol(hostport.substr(i+2).c_str()); if (p > 65535) return; // illegal port value port = (unsigned short)p; } } else { // Host contains a host name or IPv4 address i = hostport.find(':'); if (i != string::npos) { if (i == 0 || i == hostport.size()-1) return; host = hostport.substr(0, i); unsigned long p = atol(hostport.substr(i+1).c_str()); if (p > 65535) return; // illegal port value port = (unsigned short)p; } else { host = hostport; } } user_url = true; valid = true; } void t_url::construct_machine_url(const string &s) { string::size_type i; // Determine host string hostport; i = s.find_first_of("/?;"); if ( i != string::npos) { hostport = s.substr(0, i); if (!parse_params_headers(s.substr(i))) return; } else { hostport = s; } if (hostport.empty()) return; if (hostport.at(0) == '[') { // Host contains an IPv6 reference i = hostport.find(']'); if (i == string::npos) return; // TODO: check format of an IPv6 address host = hostport.substr(0, i+1); if (i < hostport.size()-1) { if (hostport.at(i+1) != ':') return; // wrong port separator if (i+1 == hostport.size()-1) return; // port missing unsigned long p = atol(hostport.substr(i+2).c_str()); if (p > 65535) return; // illegal port value port = (unsigned short)p; } } else { // Host contains a host name or IPv4 address i = hostport.find(':'); if (i != string::npos) { if (i == 0 || i == hostport.size()-1) return; host = hostport.substr(0, i); unsigned long p = atol(hostport.substr(i+1).c_str()); if (p > 65535) return; // illegal port value port = (unsigned short)p; } else { host = hostport; } } user_url = false; valid = true; } bool t_url::parse_params_headers(const string &s) { string param_str = ""; // Find start of headers // Note: parameters will not contain / or ?-symbol string::size_type header_start = s.find_first_of("/?"); if (header_start != string::npos) { headers = s.substr(header_start + 1); if (s[0] == ';') { // The first symbol of the parameter list is ; // Remove this. param_str = s.substr(1, header_start - 1); } } else { // There are no headers // The first symbol of the parameter list is ; // Remove this. param_str = s.substr(1); } if (param_str == "") return true; // Create a list of single parameters. Parameters are // seperated by semi-colons. // Note: parameters will not contain a semi-colon in the // name or value. vector param_lst = split(param_str, ';'); // Parse the parameters for (vector::iterator i = param_lst.begin(); i != param_lst.end(); i++) { string pname; string pvalue; vector param = split(*i, '='); if (param.size() > 2) return false; pname = tolower(unescape_hex(trim(param.front()))); if (param.size() == 2) { pvalue = tolower(unescape_hex(trim(param.back()))); } if (pname == "transport") { transport = pvalue; } else if (pname == "maddr") { maddr = pvalue; } else if (pname == "lr") { lr = true; } else if (pname == "user") { user_param = pvalue; } else if (pname == "method") { method = pvalue; } else if (pname == "ttl") { ttl = atoi(pvalue.c_str()); } else { other_params += ';'; other_params += *i; } } return true; } // Public static string t_url::escape_user_value(const string &user_value) { // RFC 3261 // user = 1*( unreserved / escaped / user-unreserved ) // user-unreserved = "&" / "=" / "+" / "$" / "," / ";" / "?" / "/" // unreserved = alphanum / mark // mark = "-" / "_" / "." / "!" / "~" / "*" / "'" / "(" / ")" return escape_hex(user_value, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYX0123456789"\ "-_.!~*'()&=+$,;?/"); } string t_url::escape_passwd_value(const string &passwd_value) { // RFC 3261 // password = *( unreserved / escaped / "&" / "=" / "+" / "$" / "," ) // unreserved = alphanum / mark // mark = "-" / "_" / "." / "!" / "~" / "*" / "'" / "(" / ")" return escape_hex(passwd_value, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYX0123456789"\ "-_.!~*'()&=+$,"); } string t_url::escape_hnv(const string &hnv) { // RFC 3261 // hname = 1*( hnv-unreserved / unreserved / escaped ) // hvalue = *( hnv-unreserved / unreserved / escaped ) // hnv-unreserved = "[" / "]" / "/" / "?" / ":" / "+" / "$" // unreserved = alphanum / mark // mark = "-" / "_" / "." / "!" / "~" / "*" / "'" / "(" / ")" return escape_hex(hnv, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYX0123456789"\ "-_.!~*'()[]/?:+$"); } // Public t_url::t_url(void) { modified = false; valid = false; port = 0; lr = false; ttl = 0; } t_url::t_url(const string &s) { set_url(s); } t_url t_url::copy_without_headers(void) const { t_url u(*this); u.clear_headers(); return u; } void t_url::set_url(const string &s) { string::size_type i; string r; modified = false; valid = false; scheme.clear(); user.clear(); password.clear(); host.clear(); port = 0; transport.clear(); maddr.clear(); lr = false; user_param.clear(); method.clear(); ttl = 0; other_params.clear(); headers.clear(); user_url = false; text_format = s; // Determine scheme. A scheme is mandatory. There should // be text following the scheme. i = s.find(':'); if (i == string::npos || i == 0 || i == s.size()-1) return; scheme = tolower(s.substr(0, i)); r = s.substr(i+1); if (r[0] == '/') { if (r.size() == 1) return; if (r[1] != '/') return; construct_machine_url(r.substr(2)); } else { construct_user_url(r); } } string t_url::get_scheme(void) const { return scheme; } string t_url::get_user(void) const { return user; } string t_url::get_password(void) const { return password; } string t_url::get_host(void) const { return host; } int t_url::get_nport(void) const { return htons(get_hport()); } int t_url::get_hport(void) const { if (port != 0) return port; return get_default_port(scheme); } int t_url::get_port(void) const { return port; } unsigned long t_url::get_n_ip(void) const { struct hostent *h; // TODO: handle multiple A RR's if (scheme == "tel") return 0; h = gethostbyname(host.c_str()); if (h == NULL) return 0; return *((unsigned long *)h->h_addr); } unsigned long t_url::get_h_ip(void) const { if (scheme == "tel") return 0; return gethostbyname(host); } list t_url::get_h_ip_all(void) const { if (scheme == "tel") return list(); return gethostbyname_all(host); } string t_url::get_ip(void) const { struct hostent *h; // TODO: handle multiple A RR's if (scheme == "tel") return 0; h = gethostbyname(host.c_str()); if (h == NULL) return ""; return inet_ntoa(*((struct in_addr *)h->h_addr)); } list t_url::get_h_ip_srv(const string &transport) const { list ip_list; list srv_list; list ipaddr_list; if (scheme == "tel") return list(); // RFC 3263 4.2 // Only do an SRV lookup if host is a hostname and no port is specified. if (!is_ipaddr(host) && port == 0) { int ret = insrv_lookup(scheme.c_str(), transport.c_str(), host.c_str(), srv_list); if (ret >= 0 && !srv_list.empty()) { // SRV RR's found for (list::iterator i = srv_list.begin(); i != srv_list.end(); i++) { // Get A RR's t_ip_port ip_port; ipaddr_list = gethostbyname_all(i->hostname); for (list::iterator j = ipaddr_list.begin(); j != ipaddr_list.end(); j++) { ip_list.push_back(t_ip_port(transport, *j, i->port)); } } return ip_list; } } // No SRV RR's found, do an A RR lookup t_ip_port ip_port; ipaddr_list = get_h_ip_all(); for (list::iterator j = ipaddr_list.begin(); j != ipaddr_list.end(); j++) { ip_list.push_back(t_ip_port(transport, *j, get_hport())); } return ip_list; } string t_url::get_transport(void) const { return transport; } string t_url::get_maddr(void) const { return maddr; } bool t_url::get_lr(void) const { return lr; } string t_url::get_user_param(void) const { return user_param; } string t_url::get_method(void) const { return method; } int t_url::get_ttl(void) const { return ttl; } string t_url::get_other_params(void) const { return other_params; } string t_url::get_headers(void) const { return headers; } void t_url::set_user(const string &u) { modified = true; user = u; } void t_url::set_host(const string &h) { modified = true; host = h; } void t_url::add_header(const t_header &hdr) { if (!hdr.is_populated()) return; modified = true; if (!headers.empty()) headers += ';'; headers += escape_hnv(hdr.get_name()); headers += '='; headers += escape_hnv(hdr.get_value()); } void t_url::clear_headers(void) { if (headers.empty()) { // No headers to clear return; } modified = true; headers.clear(); } bool t_url::is_valid(void) const { return valid; } // RCF 3261 19.1.4 bool t_url::sip_match(const t_url &u) const { if (!u.is_valid() || !is_valid()) return false; // Compare schemes if (scheme != "sip" && scheme != "sips") return false; if (u.get_scheme() != "sip" && u.get_scheme() != "sips") { return false; } if (scheme != u.get_scheme()) return false; // Compare user info if (user != u.get_user()) return false; if (password != u.get_password()) return false; // Compare host/port if (cmp_nocase(host, u.get_host()) != 0) return false; if (port != u.get_port()) return false; // Compare parameters if (transport != "" && u.get_transport() != "" && cmp_nocase(transport, u.get_transport()) != 0) { return false; } if (maddr != u.get_maddr()) return false; if (cmp_nocase(user_param, u.get_user_param()) != 0) return false; if (cmp_nocase(method, u.get_method()) != 0) return false; if (ttl != u.get_ttl()) return false; // TODO: compare other params and headers return true; } bool t_url::operator==(const t_url &u) const { return sip_match(u); } bool t_url::operator!=(const t_url &u) const { return !sip_match(u); } bool t_url::user_host_match(const t_url &u, bool looks_like_phone, const string &special_symbols) const { string u1 = get_user(); string u2 = u.get_user(); // For tel-URIs the phone number is in the host part. if (scheme == "tel") u1 = get_host(); if (u.scheme == "tel") u2 = u.get_host(); bool u1_is_phone = false; bool u2_is_phone = false; if (is_phone(looks_like_phone, special_symbols)) { u1 = remove_symbols(u1, special_symbols); u1_is_phone = true; } if (u.is_phone(looks_like_phone, special_symbols)) { u2 = remove_symbols(u2, special_symbols); u2_is_phone = true; } if (u1 != u2) return false; if (u1_is_phone && u2_is_phone) { // Both URLs are phone numbers. Do not compare // the host-part. return true; } return (get_host() == u.get_host()); } bool t_url::user_looks_like_phone(const string &special_symbols) const { return looks_like_phone(user, special_symbols); } bool t_url::is_phone(bool looks_like_phone, const string &special_symbols) const { if (scheme == "tel") return true; // RFC 3261 19.1.1 if (user_param == "phone") return true; return (looks_like_phone && user_looks_like_phone(special_symbols)); } string t_url::encode(void) const { if (modified) { if (!user_url) { // TODO: machine URL's are currently not used return text_format; } string s; s = scheme; s += ':'; if (!user.empty()) { s += escape_user_value(user); if (!password.empty()) { s += ':'; s += escape_passwd_value(password); } s += '@'; } s += host; if (port > 0) { s += ':'; s += int2str(port); } if (!transport.empty()) { s += ";transport="; s += transport; } if (!maddr.empty()) { s += ";maddr="; s += maddr; } if (lr) { s += ";lr"; } if (!user_param.empty()) { s += ";user="; s += user_param; } if (!method.empty()) { s += ";method="; s += method; } if (ttl > 0) { s += ";ttl="; s += int2str(ttl); } if (!other_params.empty()) { s += other_params; } if (!headers.empty()) { s += "?"; s += headers; } return s; } else { return text_format; } } string t_url::encode_noscheme(void) const { string s = encode(); string::size_type i = s.find(':'); if (i != string::npos && i < s.size()) { s = s.substr(i + 1); } return s; } string t_url::encode_no_params_hdrs(bool escape) const { if (!user_url) { // TODO: machine URL's are currently not used return text_format; } string s; s = scheme; s += ':'; if (!user.empty()) { if (escape) { s += escape_user_value(user); } else { s += user; } if (!password.empty()) { s += ':'; if (escape) { s += escape_passwd_value(password); } else { s += password; } } s += '@'; } s += host; if (port > 0) { s += ':'; s += int2str(port); } return s; } void t_url::apply_conversion_rules(t_user *user_config) { if (scheme == "tel") { host = user_config->convert_number(host); } else { // Convert user part for all other schemes user = user_config->convert_number(user); } modified = true; } t_display_url::t_display_url() {} t_display_url::t_display_url(const t_url &_url, const string &_display) : url(_url), display(_display) {} bool t_display_url::is_valid() { return url.is_valid(); } string t_display_url::encode(void) const { string s; if (!display.empty()) { if (must_quote(display)) s += '"'; s += display; if (must_quote(display)) s += '"'; s += " <"; } s += url.encode(); if (!display.empty()) s += '>'; return s; } twinkle-1.4.2/src/sockets/connection.h0000644000175000001440000001471311127714046014673 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Network connection */ #ifndef _H_CONNECTION #define _H_CONNECTION #include #include #include "socket.h" #include "parser/request.h" #include "parser/sip_message.h" using namespace std; /** Abstract class for a network connection. */ class t_connection { private: static const unsigned int READ_BLOCK_SIZE = 1448; static const unsigned int WRITE_BLOCK_SIZE = 1448; /** Buffer with data already read from the network. */ string read_buf_; /** Socket for connection. */ t_socket *socket_; /** SIP message parsed from available data (headers only) */ t_sip_message *sip_msg_; /** Raw SIP headers that have been parsed already */ string raw_sip_headers_; /** Data to be sent on the connection. */ string send_buf_; /** Position in send buffer for next send action. */ string::size_type pos_send_buf_; /** * Time (ms) that the connection is idle . * This time is reset to zero by read and send actions. */ unsigned long idle_time_; /** * Flag to indicate that a connection can be reused. * By default a connection is reusable. */ bool can_reuse_; /** * A set of user URI's (AoR) that are registered via this connection. * If persistent connections are used for NAT traversal, then these are * the URI's that are impacted when the connection breaks. * A URI is only added to this set, if a persistent connection is required * for this user. * @note The set is implemented as a list as t_url has not less-than operator. */ list registered_uri_set_; public: typedef string::size_type size_type; t_connection(t_socket *socket); /** * Destuctor. * @note The socket will be closed and destroyed. */ virtual ~t_connection(); /** * Get a pointer to the socket. * @return The socket. */ t_socket *get_socket(void); /** * Get the amount of data in the read buffer. * @return Number of bytes in read buffer. */ size_type data_size(void) const; /** * Read a block data from connection in to read buffer. * @param connection_closed [out] Indicates if the connection was closed. * @throw int errno as set by recv. */ void read(bool &connection_closed); /** * Send a block of data from the send buffer on a connection. * @throw int errno. */ void write(void); /** * Send data on a connection. * @param data [in] Data to send * @param data_size [in] Size of data in bytes * @return Number of bytes sent. * @throw int errno. */ ssize_t send(const char *data, int data_size); /** * Append data to the send buffer for asynchronous sending. * @param data [in] Data to send * @param data_size [in] Size of data in bytes */ void async_send(const char *data, int data_size); /** * Get a SIP message from the connection. * @param raw_headers [out] Raw headers of SIP message * @param raw_body [out] Raw body of SIP message * @param error [out] Indicates if an error occurred (invalid SIP message) * @param msg_too_large [out] Indicates that the message is cutoff because it was too large * @return The SIP message if a message was received. * @return NULL, if no full SIP message has been received yet or an error occurred. * @post If error == true, then NULL is returned * @post If msg_too_large == true, then a message is returned (partial though) */ t_sip_message *get_sip_msg(string &raw_headers, string &raw_body, bool &error, bool &msg_too_large); /** * Get read data from read buffer. * @param nbytes [in] Maximum number of bytes to get. * @return Data from the read buffer up to nbytes. * @note The data is still in the buffer after this operation. */ string get_data(size_t nbytes = 0) const; /** * Remove data from read buffer. * @param nbytes [in] Number of bytes to remove. */ void remove_data(size_t nbytes); /** * Get the remote address of a connection. * @param remote_addr [out] Source IPv4 address of the connection. * @param remote_port [out] Source port of the connection. */ void get_remote_address(unsigned long &remote_addr, unsigned short &remote_port); /** * Add an interval to the idle time. * @param interval [in] Interval in ms. * @return The new idle time. */ unsigned long increment_idle_time(unsigned long interval); /** * Get idle time. * @return Idle time in ms. */ unsigned long get_idle_time(void) const; /** * Check if there is data in the send buffer. * @return true if there is data, otherwise false. */ bool has_data_to_send(void) const; /** Set re-use characteristic. */ void set_reuse(bool reuse); /** * Check if this connection may be reused to send data. * @return true if the connection may be reused, otherwise false. */ bool may_reuse(void) const; /** * Add a URI to the set of registered URI's. * @param uri [in] The URI to add. */ void add_registered_uri(const t_url &uri); /** * Remove a URI from the set of registered URI's. * @param uri [in] The URI to remove. */ void remove_registered_uri(const t_url &uri); /** * Update the set of registered URI based on a REGISTER request. * If the REGISTER is a registration, then add the To-header URI. * If the REGISTER is a de-registration, then remove the To-header URI. * If the REGISTER is a query, then do nothing. * @param req [in] A REGISTER request. * @pre req must be a REGISTER request. */ void update_registered_uri_set(const t_request *req); /** * Get the set of registered URI's. * @return The set of registered URI's. */ const list &get_registered_uri_set(void) const; /** * Check if at least one registered URI is associated with this connection. * @return True if a URI is associated, false otherwise. */ bool has_registered_uri(void) const; }; #endif twinkle-1.4.2/src/sockets/connection.cpp0000644000175000001440000001720511134635441015224 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "connection.h" #include #include #include "connection_table.h" #include "log.h" #include "sys_settings.h" #include "util.h" #include "audits/memman.h" #include "parser/parse_ctrl.h" extern t_connection_table *connection_table; using namespace std; t_connection::t_connection(t_socket *socket) : socket_(socket), sip_msg_(NULL), pos_send_buf_(0), idle_time_(0), can_reuse_(true) {} t_connection::~t_connection() { MEMMAN_DELETE(socket_); delete socket_; } t_socket *t_connection::get_socket(void) { return socket_; } t_connection::size_type t_connection::data_size(void) const { return read_buf_.size(); } void t_connection::read(bool &connection_closed) { connection_closed = false; char buf[READ_BLOCK_SIZE]; ssize_t nread = socket_->recv(buf, READ_BLOCK_SIZE); if (nread > 0) { read_buf_.append(buf, buf + nread); } else { connection_closed = true; } idle_time_ = 0; } void t_connection::write(void) { if (send_buf_.empty()) return; ssize_t nwrite = send_buf_.size() - pos_send_buf_; if ((ssize_t)WRITE_BLOCK_SIZE < nwrite) nwrite = WRITE_BLOCK_SIZE; ssize_t nwritten = socket_->send(send_buf_.c_str() + pos_send_buf_, nwrite); pos_send_buf_ += nwritten; if (pos_send_buf_ >= send_buf_.size()) { // All data written send_buf_.clear(); pos_send_buf_ = 0; } } ssize_t t_connection::send(const char *data, int data_size) { ssize_t bytes_sent = socket_->send(data, data_size); idle_time_ = 0; return bytes_sent; } void t_connection::async_send(const char *data, int data_size) { send_buf_ += string(data, data_size); connection_table->restart_write_select(); } t_sip_message *t_connection::get_sip_msg(string &raw_headers, string &raw_body, bool &error, bool &msg_too_large) { string log_msg; raw_headers.clear(); raw_body.clear(); error = false; msg_too_large = false; if (!sip_msg_) { // RFC 3261 7.5 // Ignore CRLF preceding the start-line of a SIP message while (read_buf_.size() >= 2 && read_buf_.substr(0, 2) == string(CRLF)) { remove_data(2); } // A complete list of headers has not been read yet, try // to find the boundary between headers and body. string seperator = string(CRLF) + string(CRLF); string::size_type pos_body = read_buf_.find(seperator); if (pos_body == string::npos) { // Still no complete list of headers. if (read_buf_.size() > sys_config->get_sip_max_tcp_size()) { log_file->write_report("Message too large", "t_connection::get_sip_msg", LOG_SIP, LOG_WARNING); error = true; } return NULL; } pos_body += seperator.size(); // Parse SIP headers raw_sip_headers_ = read_buf_.substr(0, pos_body); list parse_errors; try { sip_msg_ = t_parser::parse(raw_sip_headers_, parse_errors); } catch (int) { // Discard malformed SIP messages. log_msg = "Invalid SIP message.\n"; log_msg += "Fatal parse error in headers.\n\n"; log_msg += to_printable(raw_sip_headers_); log_file->write_report(log_msg, "t_connection::get_sip_msg", LOG_SIP, LOG_DEBUG); error = true; return NULL; } // Log non-fatal parse errors. if (!parse_errors.empty()) { log_msg = "Parse errors:\n"; log_msg += "\n"; for (list::iterator i = parse_errors.begin(); i != parse_errors.end(); i++) { log_msg += *i; log_msg += "\n"; } log_msg += "\n"; log_file->write_report(log_msg, "t_connection::get_sip_msg", LOG_SIP, LOG_DEBUG); } get_remote_address(sip_msg_->src_ip_port.ipaddr, sip_msg_->src_ip_port.port); sip_msg_->src_ip_port.transport = "tcp"; // Remove the processed headers from the read buffer. remove_data(pos_body); } // RFC 3261 18.4 // The Content-Length header field MUST be used with stream oriented transports. if (!sip_msg_->hdr_content_length.is_populated()) { // The transaction layer will send an error response. log_file->write_report("Content-Length header is missing.", "t_connection::get_sip_msg", LOG_SIP, LOG_WARNING); } else { if (read_buf_.size() < sip_msg_->hdr_content_length.length) { // No full body read yet. if (read_buf_.size() + raw_sip_headers_.size() <= sys_config->get_sip_max_tcp_size()) { return NULL; } else { log_file->write_report("Message too large", "t_connection::get_sip_msg", LOG_SIP, LOG_WARNING); msg_too_large = true; } } else { if (sip_msg_->hdr_content_length.length > 0) { raw_body = read_buf_.substr(0, sip_msg_->hdr_content_length.length); remove_data(sip_msg_->hdr_content_length.length); } } } // Return data to caller. Clear internally cached data. t_sip_message *msg = sip_msg_; sip_msg_ = NULL; raw_headers = raw_sip_headers_; raw_sip_headers_.clear(); return msg; } string t_connection::get_data(size_t nbytes) const { size_t nread = min(nbytes, read_buf_.size()); return read_buf_.substr(0, nread); } void t_connection::remove_data(size_t nbytes) { if (nbytes == 0) return; if (nbytes >= read_buf_.size()) { read_buf_.clear(); } else { read_buf_.erase(0, nbytes); } } void t_connection::get_remote_address(unsigned long &remote_addr, unsigned short &remote_port) { remote_addr = 0; remote_port = 0; try { t_socket_tcp *tcp_socket = dynamic_cast(socket_); if (tcp_socket) { tcp_socket->get_remote_address(remote_addr, remote_port); } else { log_file->write_report("Socket is not connection oriented.", "t_connection::get_sip_msg", LOG_NORMAL, LOG_WARNING); } } catch (int err) { string errmsg = get_error_str(err); string log_msg = "Cannot get remote address: "; log_msg += errmsg; log_file->write_report(log_msg, "t_connection::get_sip_msg", LOG_NORMAL, LOG_WARNING); } } unsigned long t_connection::increment_idle_time(unsigned long interval) { idle_time_ += interval; return idle_time_; } unsigned long t_connection::get_idle_time(void) const { return idle_time_; } bool t_connection::has_data_to_send(void) const { return !send_buf_.empty(); } void t_connection::set_reuse(bool reuse) { can_reuse_ = reuse; } bool t_connection::may_reuse(void) const { return can_reuse_; } void t_connection::add_registered_uri(const t_url &uri) { // Add the URI if it is not in the set. if (find(registered_uri_set_.begin(), registered_uri_set_.end(), uri) == registered_uri_set_.end()) { registered_uri_set_.push_back(uri); } } void t_connection::remove_registered_uri(const t_url &uri) { registered_uri_set_.remove(uri); } void t_connection::update_registered_uri_set(const t_request *req) { assert(req->method == REGISTER); if (req->is_registration_request()) { add_registered_uri(req->hdr_to.uri); } else if (req->is_de_registration_request()) { remove_registered_uri(req->hdr_to.uri); } } const list &t_connection::get_registered_uri_set(void) const { return registered_uri_set_; } bool t_connection::has_registered_uri(void) const { return !registered_uri_set_.empty(); } twinkle-1.4.2/src/sockets/socket.h0000644000175000001440000001362111127714046014021 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Socket operations */ #ifndef _H_SOCKET #define _H_SOCKET #include #include #include #include #include using namespace std; // ports and addresses should be in host order /** ICMP message */ class t_icmp_msg { public: short type; short code; // ICMP source IP address unsigned long icmp_src_ipaddr; // Destination IP address/port of packet causing the ICMP message. unsigned long ipaddr; unsigned short port; t_icmp_msg() {}; t_icmp_msg(short _type, short _code, unsigned long _icmp_src_ipaddr, unsigned long _ipaddr, unsigned short _port); }; /** Abstract socket */ class t_socket { protected: int sd; /**< Socket descriptor. */ /** * Constructor. This constructor does not create a valid socket. * The subclasses will create the real socket. */ t_socket(); /** * Constructor. * @param _sd Socket desciptor. */ t_socket(int _sd); public: /** Destructor */ virtual ~t_socket(); /** * Get the socket descriptor. * @return The socket descriptor. */ int get_descriptor(void) const; /** Get socket options */ int getsockopt(int level, int optname, void *optval, socklen_t *optlen); /** Set socket options */ int setsockopt(int level, int optname, const void *optval, socklen_t optlen); /** Receive data */ virtual ssize_t recv(void *buf, int buf_size) = 0; /** Send data */ virtual ssize_t send(const void *data, int data_size) = 0; }; /** UDP socket */ class t_socket_udp : public t_socket { public: // Create a socket and bind it to any port. // Throws an int exception if it fails. The int thrown is the value // of errno as set by 'socket' or 'bind'. t_socket_udp(); // Create a socket and bind it to port. // Throws an int exception if it fails. The int thrown is the value // of errno as set by 'socket' or 'bind'. t_socket_udp(unsigned short port); // Connect a socket // Throws an int exception if it fails (errno as set by 'sendto') int connect(unsigned long dest_addr, unsigned short dest_port); // Throws an int exception if it fails (errno as set by 'sendto') int sendto(unsigned long dest_addr, unsigned short dest_port, const char *data, int data_size); virtual ssize_t send(const void *data, int data_size); // Throws an int exception if it fails (errno as set by 'recvfrom') // On success the length of the data in buf is returned. After the // data in buf there will be a 0. int recvfrom(unsigned long &src_addr, unsigned short &src_port, char *buf, int buf_size); virtual ssize_t recv(void *buf, int buf_size); // Do a select on the socket in read mode. timeout is in ms. // Returns true if the socket becomes unblocked. Returns false // on time out. Throws an int exception if select fails // (errno as set by 'select') bool select_read(unsigned long timeout); // Enable reception of ICMP errors on this socket. // Returns false if ICMP reception cannot be enabled. bool enable_icmp(void); // Get an ICMP message that was received on this socket. // Returns false if no ICMP message can be retrieved. bool get_icmp(t_icmp_msg &icmp); }; /** TCP socket */ class t_socket_tcp : public t_socket { public: /** * Constructor. Create a socket. * @throw int The errno value */ t_socket_tcp(); /** * Constructor. Create a socket and bind it to a port. * @throw int The errno value */ t_socket_tcp(unsigned short port); /** * Constructor. Create a socket from an existing descriptor. */ t_socket_tcp(int _sd); /** * Listen for a connection. * @throw int Errno */ void listen(int backlog); /** * Accept a connection * @param src_addr [out] Source IPv4 address of the connection. * @param src_port [out] Source port of the connection. * @return A socket for the new connection * @throw int Errno */ t_socket_tcp *accept(unsigned long &src_addr, unsigned short &src_port); /** * Connect to a destination * @param dest_addr [in] Destination IPv4 address. * @param dest_port [in] Destination port. * @throw int Errno */ void connect(unsigned long dest_addr, unsigned short dest_port); /** Send data */ virtual ssize_t send(const void *data, int data_size); /** Receive data */ virtual ssize_t recv(void *buf, int buf_size); /** * Get the remote address of a connection. * @param remote_addr [out] Source IPv4 address of the connection. * @param remote_port [out] Source port of the connection. * @throw int Errno */ void get_remote_address(unsigned long &remote_addr, unsigned short &remote_port); }; /** Local socket */ class t_socket_local : public t_socket { public: // Throws an int exception if it fails. The int thrown is the value // of errno as set by 'socket' t_socket_local(); t_socket_local(int _sd); void bind(const string &name); void listen(int backlog); int accept(void); void connect(const string &name); int read(void *buf, int count); virtual ssize_t recv(void *buf, int buf_size); int write(const void *buf, int count); virtual ssize_t send(const void *buf, int count); }; // Convert an IP address in host order to a string. string h_ip2str(unsigned long ipaddr); #endif twinkle-1.4.2/src/transaction_mgr.h0000644000175000001440000000724411127714046014254 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TRANSACTION_MGR_H #define _TRANSACTION_MGR_H #include #include "events.h" #include "transaction.h" #include "user.h" #include "parser/request.h" #include "parser/response.h" #include "sockets/socket.h" #include "stun/stun_transaction.h" using namespace std; class t_transaction_mgr { private: // Mapping from transaction id to transaction map map_trans_client; map map_trans_server; map map_stun_trans; // Find existing transactions. Return NULL if not found t_trans_client *find_trans_client(t_response *r) const; t_trans_client *find_trans_client(t_tid tid) const; t_trans_client *find_trans_client(const string &branch, const t_method &cseq_method) const; t_trans_client *find_trans_client(const t_icmp_msg &icmp) const; t_trans_server *find_trans_server(t_request *r) const; t_trans_server *find_trans_server(t_tid tid) const; t_stun_transaction *find_stun_trans(StunMessage *r) const; t_stun_transaction *find_stun_trans(t_tid tid) const; t_stun_transaction *find_stun_trans(const t_icmp_msg &icmp) const; // Create new transactions. // Return NULL if creation failed. t_tc_invite *create_tc_invite(t_user *user_config, t_request *r, unsigned short tuid); t_tc_non_invite *create_tc_non_invite(t_user *user_config, t_request *r, unsigned short tuid); t_ts_invite *create_ts_invite(t_request *r); t_ts_non_invite *create_ts_non_invite(t_request *r); t_sip_stun_trans *create_sip_stun_trans(t_user *user_config, StunMessage *r, unsigned short tuid); t_media_stun_trans *create_media_stun_trans(t_user *user_config, StunMessage *r, unsigned short tuid, unsigned short src_port); // Delete transactions void delete_trans_client(t_trans_client *tc); void delete_trans_server(t_trans_server *ts); void delete_stun_trans(t_stun_transaction *st); // Handle events void handle_event_network(t_event_network *e); void handle_event_user(t_event_user *e); void handle_event_timeout(t_event_timeout *e); void handle_event_abort(t_event_abort_trans *e); void handle_event_stun_request(t_event_stun_request *e); void handle_event_stun_response(t_event_stun_response *e); void handle_event_icmp(t_event_icmp *e); void handle_event_failure(t_event_failure *e); public: ~t_transaction_mgr(); // Find the target transaction for a CANCEL. // Return NULL if not found. t_trans_server *find_cancel_target(t_request *r) const; // Start transaction timer. Return timer id (needed for stopping) t_object_id start_timer(long dur, t_sip_timer tmr, unsigned short tid); t_object_id start_stun_timer(long dur, t_stun_timer tmr, unsigned short tid); // Stop timer. Pass id that is returned by start_timer void stop_timer(t_object_id id); // Main loop of the transaction manager (infinite) void run (void); }; // Thread that runs the transaction manager void *transaction_mgr_main(void *arg); #endif twinkle-1.4.2/src/transaction.h0000644000175000001440000002356311127714047013412 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TRANSACTION_H #define _TRANSACTION_H #include #include "protocol.h" #include "parser/request.h" #include "parser/response.h" #include "sockets/socket.h" #include "threads/mutex.h" using namespace std; typedef unsigned short t_tid; ///////////////////////////////////////////////////////////// // Transaction state (see RFC 3261 17) ///////////////////////////////////////////////////////////// enum t_trans_state { TS_NULL, // non-state used for initialization TS_CALLING, TS_TRYING, TS_PROCEEDING, TS_COMPLETED, TS_CONFIRMED, TS_TERMINATED, }; string trans_state2str(t_trans_state s); ///////////////////////////////////////////////////////////// // General transaction ///////////////////////////////////////////////////////////// // // Concurrent creation of transactions is not allowed. If this // is needed then updates to static members need to be // synchronized with a mutex. // All transactions are created by the transaction manager. This // should not be changed as transactions start timers and all timers // must be started from a single thread. class t_transaction { private: static t_mutex mtx_class; // protect static members static t_tid next_id; // next id to be issued protected: t_tid id; // transaction id unsigned short tuid; // TU id t_trans_state state; string to_tag; // tag for to-header public: // Request that created the transaction t_request *request; t_tid get_id(void) const; // Provisional responses in order of arrival/sending list provisional; // Final response for the transaction t_response *final; // The transaction will keep a copy of the request t_transaction(t_request *r, unsigned short _tuid); // All request and response pointers contained by the // request will be deleted. virtual ~t_transaction(); // Process a provisional repsonse // Transaction will keep a copy of the response virtual void process_provisional(t_response *r); // Process a final response // Transaction will keep a copy of the response virtual void process_final(t_response *r); // Process a response virtual void process_response(t_response *r); // Process timer expiry virtual void timeout(t_sip_timer t) = 0; // Get state of the transaction t_trans_state get_state(void) const; // Set TU ID void set_tuid(unsigned short _tuid); // Get type of request t_method get_method(void) const; // Get tag for to-header string get_to_tag(void); // Create response according to general rules t_response *create_response(int code, string reason = ""); }; ///////////////////////////////////////////////////////////// // Client transaction ///////////////////////////////////////////////////////////// class t_trans_client : public t_transaction { protected: /** Destination for request. */ t_ip_port dst_ip_port; public: /** * Create transaction and send request to destination. * @param r [in] Request creating the transaction. * @param ip_port [in] Destination of the request. * @param _tuid [in] Transaction user id assigned to this transaction. */ t_trans_client(t_request *r, const t_ip_port &ip_port, unsigned short _tuid); /** * Match a response with a transaction. * @param r [in] The response to match. * @return true if the response matches the transaction. */ bool match(t_response *r) const; /** * @param icmp [in] ICMP message to match. * @return true if the ICMP error matches the transaction */ bool match(const t_icmp_msg &icmp) const; /** * Match transaction with a branch and CSeq method value. * @param branch [in] Branch to match. * @param cseq_method [in] CSeq method to match. * @return true if transaction matches, otherwise false. */ bool match(const string &branch, const t_method &cseq_method) const; virtual void process_provisional(t_response *r); /** * Process ICMP errors. * @param icmp [in] ICMP message. */ virtual void process_icmp(const t_icmp_msg &icmp) = 0; /** * Process failures. * @param failure [in] Type of failure. */ virtual void process_failure(t_failure failure) = 0; /** * Abort a transaction. * This will send a 408 response internally to finish the transaction. */ virtual void abort(void) = 0; }; ///////////////////////////////////////////////////////////// // Client INVITE transaction ///////////////////////////////////////////////////////////// class t_tc_invite : public t_trans_client { private: // Timers unsigned short timer_A; unsigned short timer_B; unsigned short timer_D; // Duration of next timer A in msec long duration_A; void start_timer_A(void); void start_timer_B(void); void start_timer_D(void); void stop_timer_A(void); void stop_timer_B(void); void stop_timer_D(void); public: t_request *ack; // ACK request // Create transaction and send request to destination // Start timer A and timer B t_tc_invite(t_request *r, const t_ip_port &ip_port, unsigned short _tuid); virtual ~t_tc_invite(); // Process a provisional repsonse // Stop timer A void process_provisional(t_response *r); // Process a final response // Stop timer B. // Start timer D (for non-2xx final). void process_final(t_response *r); void process_icmp(const t_icmp_msg &icmp); void process_failure(t_failure failure); void timeout(t_sip_timer t); void abort(void); }; ///////////////////////////////////////////////////////////// // Client non-INVITE transaction ///////////////////////////////////////////////////////////// class t_tc_non_invite : public t_trans_client { private: // Timers unsigned short timer_E; unsigned short timer_F; unsigned short timer_K; // Duration of next timer E in msec long duration_E; void start_timer_E(void); void start_timer_F(void); void start_timer_K(void); void stop_timer_E(void); void stop_timer_F(void); void stop_timer_K(void); public: // Create transaction and send request to destination // Stop timer E and timer F t_tc_non_invite(t_request *r, const t_ip_port &ip_port, unsigned short _tuid); virtual ~t_tc_non_invite(); // Process a provisional repsonse void process_provisional(t_response *r); // Process final response // Stop timer E and F. Start timer K. void process_final(t_response *r); void process_icmp(const t_icmp_msg &icmp); void process_failure(t_failure failure); void timeout(t_sip_timer t); void abort(void); }; ///////////////////////////////////////////////////////////// // Server transaction ///////////////////////////////////////////////////////////// class t_trans_server : public t_transaction { private: // Match a the transaction to a request. Argument // If cancel==true then the target for a CANCEL // is matched. // If cancel==false then the request itself is matched, // eg. retransmission or ACK to INVITE matching bool match(t_request *r, bool cancel) const; // Indicates if a 100 Trying has already been sent. // A 100 Trying should only be sent once. // The reason for sending a 100 Trying is to indicate that // the request has been received but that processing will // take some time. // Based on the tasks to perform several parts of the transaction // user can decide independently to send a 100 Trying. This // flag assures that only one 100 Trying will be sent out // though. bool resp_100_trying_sent; public: t_trans_server(t_request *r, unsigned short _tuid); // Process a provisional repsonse // Send provisional response void process_provisional(t_response *r); // Process a final response // Send the final response void process_final(t_response *r); // Process a received retransmission of the request virtual void process_retransmission(void); // Returns true if request matches transaction bool match(t_request *r) const; // Returns true if the transaction is the target of CANCEL bool match_cancel(t_request *r) const; }; ///////////////////////////////////////////////////////////// // Server INIVITE transaction ///////////////////////////////////////////////////////////// class t_ts_invite : public t_trans_server { private: // Timers unsigned short timer_G; unsigned short timer_H; unsigned short timer_I; // Duration of next timer G in msec long duration_G; void start_timer_G(void); void start_timer_H(void); void start_timer_I(void); void stop_timer_G(void); void stop_timer_H(void); void stop_timer_I(void); public: t_request *ack; // ACK request t_ts_invite(t_request *r, unsigned short _tuid); virtual ~t_ts_invite(); void process_provisional(t_response *r); void process_final(t_response *r); void process_retransmission(void); void timeout(t_sip_timer t); // Transaction will keep a copy of the ACK. void acknowledge(t_request *ack_request); }; ///////////////////////////////////////////////////////////// // Server non-INVITE transaction ///////////////////////////////////////////////////////////// class t_ts_non_invite : public t_trans_server { private: // Timers unsigned short timer_J; void start_timer_J(void); void stop_timer_J(void); public: t_ts_non_invite(t_request *r, unsigned short _tuid); virtual ~t_ts_non_invite(); void process_provisional(t_response *r); void process_final(t_response *r); void process_retransmission(void); void timeout(t_sip_timer t); }; #endif twinkle-1.4.2/src/address_book.h0000644000175000001440000000673611127714047013527 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Local address book. */ #ifndef _ADDRESS_BOOK_H #define _ADDRESS_BOOK_H #include #include #include "user.h" #include "sockets/url.h" #include "threads/mutex.h" #include "utils/record_file.h" using namespace std; /** A single address card. */ class t_address_card : public utils::t_record { public: string name_last; /**< Last name. */ string name_first; /**< First name. */ string name_infix; /**< Infix name. */ string sip_address; /**< SIP address. */ string remark; /**< Remark. */ /** * Get the display name derived from first, last and infix name. * @return The display name. */ string get_display_name(void) const; virtual bool create_file_record(vector &v) const; virtual bool populate_from_file_record(const vector &v); /** Equality check. */ bool operator==(const t_address_card other) const; }; /** * A book containing address cards. The user can * create different address books. */ class t_address_book : public utils::t_record_file { private: /** @name Cache for last searched name/url mapping */ //@{ mutable t_url last_url; /**< Last URL. */ mutable string last_name; /**< Lat name. */ //@} /** * Find a matching address for a url and cache the display name. * @param user_config [in] The user profile. * @param u [in] The url to find. * @post If a matching address is found, then the URL and name are * put in the cache. Otherwise the cache is cleared. */ void find_address(t_user *user_config, const t_url &u) const; public: /** Constructor. */ t_address_book(); /** * Add an address. * @param address [in] The address to be added. */ void add_address(const t_address_card &address); /** * Delete an address. * @return true, if the address was succesfully deleted. * @return false, if the address does not exist. */ bool del_address(const t_address_card &address); /** * Update an address. * @param old_address [in] The address to be updated. * @param new_address [in] The updated address information. * @return true, if the update was successful. * @return false, if the old address does not exist. */ bool update_address(const t_address_card &old_address, const t_address_card &new_address); /** * Find the display name for a SIP URL. * @param user_config [in] The user profile. * @param u [in] The SIP URL. * @return The display name if a match was found. * @return Empty string if no match can be found. */ string find_name(t_user *user_config, const t_url &u) const; /** * Get the list of addresses. * @return The list of addresses. */ const list &get_address_list(void) const; }; extern t_address_book *ab_local; #endif twinkle-1.4.2/src/patterns/0000777000175000001440000000000011151327745012631 500000000000000twinkle-1.4.2/src/patterns/observer.h0000644000175000001440000000344411127714047014550 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Abstract observer pattern. */ #ifndef _OBSERVER_H #define _OBSERVER_H #include #include "threads/mutex.h" using namespace std; namespace patterns { /** Observer. */ class t_observer { public: virtual ~t_observer() {}; /** * This method is called by an observed subject to indicate its state * has changed. */ virtual void update(void) = 0; /** * This method is called when the subject is destroyed. */ virtual void subject_destroyed(void) = 0; }; /** An observed subject. */ class t_subject { private: /** Mutex to protect access to the observers. */ mutable t_recursive_mutex mtx_observers; list observers; /** Observers of this subject. */ public: virtual ~t_subject(); /** * Attach an observer. * @param o [in] The observer. */ void attach(t_observer *o); /** * Detach an observer. * @param o [in] The observer. */ void detach(t_observer *o); /** * Notify all observers. */ void notify(void) const; }; }; // namespace #endif twinkle-1.4.2/src/patterns/observer.cpp0000644000175000001440000000273611127714056015106 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "observer.h" using namespace patterns; t_subject::~t_subject() { mtx_observers.lock(); for (list::const_iterator it = observers.begin(); it != observers.end(); ++it) { (*it)->subject_destroyed(); } mtx_observers.unlock(); } void t_subject::attach(t_observer *o) { mtx_observers.lock(); observers.push_back(o); mtx_observers.unlock(); } void t_subject::detach(t_observer *o) { mtx_observers.lock(); observers.remove(o); mtx_observers.unlock(); } void t_subject::notify(void) const { mtx_observers.lock(); for (list::const_iterator it = observers.begin(); it != observers.end(); ++it) { (*it)->update(); } mtx_observers.unlock(); } twinkle-1.4.2/src/patterns/Makefile.am0000644000175000001440000000017711134651144014600 00000000000000AM_CPPFLAGS = -Wall -I$(top_srcdir)/src noinst_LIBRARIES = libpatterns.a libpatterns_a_SOURCES =\ observer.cpp\ observer.h twinkle-1.4.2/src/patterns/Makefile.in0000644000175000001440000003717011151323407014611 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/patterns DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libpatterns_a_AR = $(AR) $(ARFLAGS) libpatterns_a_LIBADD = am_libpatterns_a_OBJECTS = observer.$(OBJEXT) libpatterns_a_OBJECTS = $(am_libpatterns_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libpatterns_a_SOURCES) DIST_SOURCES = $(libpatterns_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = -Wall -I$(top_srcdir)/src noinst_LIBRARIES = libpatterns.a libpatterns_a_SOURCES = \ observer.cpp\ observer.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/patterns/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/patterns/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libpatterns.a: $(libpatterns_a_OBJECTS) $(libpatterns_a_DEPENDENCIES) -rm -f libpatterns.a $(libpatterns_a_AR) libpatterns.a $(libpatterns_a_OBJECTS) $(libpatterns_a_LIBADD) $(RANLIB) libpatterns.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/observer.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/call_history.cpp0000644000175000001440000002476411134636704014121 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include "call_history.h" #include "log.h" #include "sys_settings.h" #include "translator.h" #include "userintf.h" #include "util.h" // Call history file #define CALL_HISTORY_FILE "twinkle.ch"; // Field seperator in call history file #define REC_SEPARATOR '|' //////////////////////// // class t_call_record //////////////////////// t_mutex t_call_record::mtx_class; unsigned short t_call_record::next_id = 1; t_call_record::t_call_record() { mtx_class.lock(); id = next_id++; if (next_id == 65535) next_id = 1; mtx_class.unlock(); time_start = 0; time_answer = 0; time_end = 0; invite_resp_code = 0; } void t_call_record::renew() { mtx_class.lock(); id = next_id++; if (next_id == 65535) next_id = 1; mtx_class.unlock(); time_start = 0; time_answer = 0; time_end = 0; direction = DIR_IN; from_display.clear(); from_uri.set_url(""); from_organization.clear(); to_display.clear(); to_uri.set_url(""); to_organization.clear(); reply_to_display.clear(); reply_to_uri.set_url(""); referred_by_display.clear(); referred_by_uri.set_url(""); subject.clear(); rel_cause = CS_LOCAL_USER; invite_resp_code = 0; invite_resp_reason.clear(); far_end_device.clear(); user_profile.clear(); } void t_call_record::start_call(const t_request *invite, t_direction dir, const string &_user_profile) { assert(invite->method == INVITE); struct timeval t; gettimeofday(&t, NULL); time_start = t.tv_sec; from_display = invite->hdr_from.get_display_presentation(); from_uri = invite->hdr_from.uri; if (invite->hdr_organization.is_populated()) { from_organization = invite->hdr_organization.name; } to_display = invite->hdr_to.display; to_uri = invite->hdr_to.uri; if (invite->hdr_reply_to.is_populated()) { reply_to_display = invite->hdr_reply_to.display; reply_to_uri = invite->hdr_reply_to.uri; } if (invite->hdr_referred_by.is_populated()) { referred_by_display = invite->hdr_referred_by.display; referred_by_uri = invite->hdr_referred_by.uri; } if (invite->hdr_subject.is_populated()) { subject = invite->hdr_subject.subject; } direction = dir; user_profile = _user_profile; if (direction == DIR_IN && invite->hdr_user_agent.is_populated()) { far_end_device = invite->hdr_user_agent.get_ua_info(); } } void t_call_record::fail_call(const t_response *resp) { assert(resp->get_class() >= 3); assert(resp->hdr_cseq.method == INVITE); struct timeval t; gettimeofday(&t, NULL); time_end = t.tv_sec; rel_cause = CS_FAILURE; invite_resp_code = resp->code; invite_resp_reason = resp->reason; if (resp->hdr_organization.is_populated()) { to_organization = resp->hdr_organization.name; } if (direction == DIR_OUT && resp->hdr_server.is_populated()) { far_end_device = resp->hdr_server.get_server_info(); } } void t_call_record::answer_call(const t_response *resp) { assert(resp->is_success()); struct timeval t; gettimeofday(&t, NULL); time_answer = t.tv_sec; invite_resp_code = resp->code; invite_resp_reason = resp->reason; if (resp->hdr_organization.is_populated()) { to_organization = resp->hdr_organization.name; } if (direction == DIR_OUT && resp->hdr_server.is_populated()) { far_end_device = resp->hdr_server.get_server_info(); } } void t_call_record::end_call(t_rel_cause cause) { struct timeval t; gettimeofday(&t, NULL); time_end = t.tv_sec; rel_cause = cause; } void t_call_record::end_call(bool far_end) { if (far_end) { end_call(CS_REMOTE_USER); } else { end_call(CS_LOCAL_USER); } } string t_call_record::get_rel_cause(void) const { switch (rel_cause) { case CS_LOCAL_USER: return TRANSLATE2("CoreCallHistory", "local user"); case CS_REMOTE_USER: return TRANSLATE2("CoreCallHistory", "remote user"); case CS_FAILURE: return TRANSLATE2("CoreCallHistory", "failure"); } return TRANSLATE2("CoreCallHistory", "unknown"); } string t_call_record::get_rel_cause_internal(void) const { switch (rel_cause) { case CS_LOCAL_USER: return "local user"; case CS_REMOTE_USER: return "remote user"; case CS_FAILURE: return "failure"; } return "unknown"; } string t_call_record::get_direction(void) const { switch (direction) { case DIR_IN: return TRANSLATE2("CoreCallHistory", "in"); case DIR_OUT: return TRANSLATE2("CoreCallHistory", "out"); } return TRANSLATE2("CoreCallHistory", "unknown"); } string t_call_record::get_direction_internal(void) const { switch (direction) { case DIR_IN: return "in"; case DIR_OUT: return "out"; } return "unknown"; } bool t_call_record::set_rel_cause(const string &cause) { // NOTE: caller and callee were used before version 0.7 // They are still checked here for backward compatibility if (cause == "caller" || cause == "local user") { rel_cause = CS_LOCAL_USER; } else if (cause == "callee" || cause == "remote user") { rel_cause = CS_REMOTE_USER; } else if (cause == "failure") { rel_cause = CS_FAILURE; } else { return false; } return true; } bool t_call_record::set_direction(const string &dir) { if (dir == "in") { direction = DIR_IN; } else if (dir == "out") { direction = DIR_OUT; } else { return false; } return true; } bool t_call_record::create_file_record(vector &v) const { v.clear(); v.push_back(ulong2str(time_start)); v.push_back(ulong2str(time_answer)); v.push_back(ulong2str(time_end)); v.push_back(get_direction_internal()); v.push_back(from_display); v.push_back(from_uri.encode()); v.push_back(from_organization); v.push_back(to_display); v.push_back(to_uri.encode()); v.push_back(to_organization); v.push_back(reply_to_display); v.push_back(reply_to_uri.encode()); v.push_back(referred_by_display); v.push_back(referred_by_uri.encode()); v.push_back(subject); v.push_back(get_rel_cause_internal()); v.push_back(int2str(invite_resp_code)); v.push_back(invite_resp_reason); v.push_back(far_end_device); v.push_back(user_profile); return true; } bool t_call_record::populate_from_file_record(const vector &v) { // Check number of fields if (v.size() != 20) return false; time_start = strtoul(v[0].c_str(), NULL, 10); time_answer = strtoul(v[1].c_str(), NULL, 10); time_end = strtoul(v[2].c_str(), NULL, 10); if (!set_direction(v[3])) return false; from_display = v[4]; from_uri.set_url(v[5]); if (!from_uri.is_valid()) return false; from_organization = v[6]; to_display = v[7]; to_uri.set_url(v[8]); if (!to_uri.is_valid()) return false; to_organization = v[9]; reply_to_display = v[10]; reply_to_uri.set_url(v[11]); referred_by_display = v[12]; referred_by_uri.set_url(v[13]); subject = v[14]; if (!set_rel_cause(v[15])) return false; invite_resp_code = atoi(v[16].c_str()); invite_resp_reason = v[17]; far_end_device = v[18]; user_profile = v[19]; return true; } bool t_call_record::is_valid(void) const { if (time_start == 0 || time_end == 0) return false; if (time_answer > 0 && rel_cause == CS_FAILURE) return false; return true; } unsigned short t_call_record::get_id(void) const { return id; } //////////////////////// // class t_call_history //////////////////////// t_call_history::t_call_history() : utils::t_record_file() { set_header("time_start|time_answer|time_end|direction|from_display|from_uri|" "from_organization|to_display|to_uri|to_organization|" "reply_to_display|reply_to_uri|referred_by_display|referred_by_uri|" "subject|rel_cause|invite_resp_code|invite_resp_reason|" "far_end_device|user_profile"); set_separator(REC_SEPARATOR); string s(DIR_HOME); s += "/"; s += USER_DIR; s += "/"; s += CALL_HISTORY_FILE; set_filename(s); num_missed_calls = 0; } void t_call_history::add_call_record(const t_call_record &call_record, bool write) { if (!call_record.is_valid()) { log_file->write_report("Call history record is not valid.", "t_call_history::add_call_record", LOG_NORMAL, LOG_WARNING); return; } mtx_records.lock(); records.push_back(call_record); while (records.size() > (size_t)sys_config->get_ch_max_size()) { records.pop_front(); } // Increment missed calls counter if (call_record.rel_cause == t_call_record::CS_FAILURE && call_record.direction == t_call_record::DIR_IN) { ++num_missed_calls; ui->cb_missed_call(num_missed_calls); } mtx_records.unlock(); if (write) { string msg; if (!save(msg)) { log_file->write_report(msg, "t_call_history::add_call_record", LOG_NORMAL, LOG_WARNING); } } // Update call history in user interface. ui->cb_call_history_updated(); } void t_call_history::delete_call_record(unsigned short id, bool write) { mtx_records.lock(); for (list::iterator i = records.begin(); i != records.end(); i++) { if (i->get_id() == id) { records.erase(i); break; } } mtx_records.unlock(); if (write) { string msg; if (!save(msg)) { log_file->write_report(msg, "t_call_history::delete_call_record", LOG_NORMAL, LOG_WARNING); } } // Update call history in user interface. ui->cb_call_history_updated(); } void t_call_history::get_history(list &history) { mtx_records.lock(); history = records; mtx_records.unlock(); } void t_call_history::clear(bool write) { mtx_records.lock(); records.clear(); mtx_records.unlock(); if (write) { string msg; if (!save(msg)) { log_file->write_report(msg, "t_call_history::clear", LOG_NORMAL, LOG_WARNING); } } // Update call history in user interface. ui->cb_call_history_updated(); clear_num_missed_calls(); } int t_call_history::get_num_missed_calls(void) const { return num_missed_calls; } void t_call_history::clear_num_missed_calls(void) { mtx_records.lock(); num_missed_calls = 0; mtx_records.unlock(); ui->cb_missed_call(0); } twinkle-1.4.2/src/threads/0000777000175000001440000000000011151327752012421 500000000000000twinkle-1.4.2/src/threads/mutex.cpp0000644000175000001440000000427211127714056014210 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "mutex.h" #include "thread.h" using namespace std; /////////////////////////// // t_mutex /////////////////////////// t_mutex::t_mutex() { pthread_mutex_init(&mutex, NULL); } t_mutex::t_mutex(bool recursive) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); if (ret != 0) throw string( "t_mutex::t_mutex failed to create a recursive mutex."); pthread_mutex_init(&mutex, &attr); pthread_mutexattr_destroy(&attr); } t_mutex::~t_mutex() { pthread_mutex_destroy(&mutex); } void t_mutex::lock(void) { int ret = pthread_mutex_lock(&mutex); if (ret != 0) throw string("t_mutex::lock failed."); } int t_mutex::trylock(void) { int ret = pthread_mutex_trylock(&mutex); switch (ret) { case 0: case EBUSY: return ret; default: throw string("t_mutex::trylock failed."); } } void t_mutex::unlock(void) { int ret = pthread_mutex_unlock(&mutex); if (ret != 0) throw ("t_mutex::unlock failed."); } /////////////////////////// // t_recursive_mutex /////////////////////////// t_recursive_mutex::t_recursive_mutex() : t_mutex(true) {} t_recursive_mutex::~t_recursive_mutex() {} /////////////////////////// // t_guard_mutex /////////////////////////// t_mutex_guard::t_mutex_guard(t_mutex &mutex) : mutex_(mutex) { mutex_.lock(); } t_mutex_guard::~t_mutex_guard() { mutex_.unlock(); } twinkle-1.4.2/src/threads/Makefile.am0000644000175000001440000000031311134651222014357 00000000000000AM_CPPFLAGS = -Wall -I$(top_srcdir)/src noinst_LIBRARIES = libthread.a libthread_a_SOURCES =\ thread.cpp\ mutex.cpp\ sema.cpp\ thread.h\ mutex.h\ sema.h twinkle-1.4.2/src/threads/Makefile.in0000644000175000001440000003751011151323411014374 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/threads DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libthread_a_AR = $(AR) $(ARFLAGS) libthread_a_LIBADD = am_libthread_a_OBJECTS = thread.$(OBJEXT) mutex.$(OBJEXT) \ sema.$(OBJEXT) libthread_a_OBJECTS = $(am_libthread_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libthread_a_SOURCES) DIST_SOURCES = $(libthread_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = -Wall -I$(top_srcdir)/src noinst_LIBRARIES = libthread.a libthread_a_SOURCES = \ thread.cpp\ mutex.cpp\ sema.cpp\ thread.h\ mutex.h\ sema.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/threads/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/threads/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libthread.a: $(libthread_a_OBJECTS) $(libthread_a_DEPENDENCIES) -rm -f libthread.a $(libthread_a_AR) libthread.a $(libthread_a_OBJECTS) $(libthread_a_LIBADD) $(RANLIB) libthread.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sema.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/threads/mutex.h0000644000175000001440000000375711127714047013664 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_MUTEX #define _H_MUTEX #include #include /** * @file * Mutex operations */ class t_mutex { protected: pthread_mutex_t mutex; public: t_mutex(); // Throws a string exception (error message) when failing. t_mutex(bool recursive); virtual ~t_mutex(); // These methods throw a string exception when the operation // fails. virtual void lock(void); // Returns: // 0 - success // EBUSY - already locked // For other errors a string exception is thrown virtual int trylock(void); virtual void unlock(void); }; class t_recursive_mutex : public t_mutex { public: t_recursive_mutex(); ~t_recursive_mutex(); }; /** * Guard pattern for a mutex . * The constructor of a guard locks a mutex and the destructor * unlocks it. This way a guard object can be created at entrance * of a function. Then at exit, the mutex is automically unlocked * as the guard object goes out of scope. */ class t_mutex_guard { private: /** The guarding mutex. */ t_mutex &mutex_; public: /** * The constructor will lock the mutex. * @param mutex [in] Mutex to lock. */ t_mutex_guard(t_mutex &mutex); /** * The destructor will unlock the mutex. */ ~t_mutex_guard(); }; #endif twinkle-1.4.2/src/threads/sema.cpp0000644000175000001440000000350611127714056013772 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "sema.h" #include "util.h" using namespace std; t_semaphore::t_semaphore(unsigned int value) { int ret; ret = sem_init(&sem, 0, value); if (ret != 0) { string err = get_error_str(errno); string exception = "t_semaphore::t_semaphore failed to create a semaphore.\n"; exception += err; throw exception; } } t_semaphore::~t_semaphore() { sem_destroy(&sem); } void t_semaphore::up(void) { int ret; ret = sem_post(&sem); if (ret != 0) { string err = get_error_str(errno); string exception = "t_semaphore::up failed.\n"; exception += err; throw exception; } } void t_semaphore::down(void) { while (true) { int ret = sem_wait(&sem); if (ret != 0 && errno == EINTR) { // In NPTL threading sem_wait can be interrupted. // In LinuxThreads threading sem_wait is non-interruptable. // Continue with sem_wait if an interrupt is caught. continue; } break; } } bool t_semaphore::try_down(void) { int ret; ret = sem_trywait(&sem); return (ret == 0); } twinkle-1.4.2/src/threads/sema.h0000644000175000001440000000235711127714047013442 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_SEMAPHORE #define _H_SEMAPHORE #include class t_semaphore { private: sem_t sem; public: // Throws a string exception (error message) when failing. t_semaphore(unsigned int value); ~t_semaphore(); // Throws a string exception (error message) when failing. void up(void); void down(void); // Returns true if downing the semaphore succeeded. // Returns false if the semaphore was zero already. bool try_down(void); }; #endif twinkle-1.4.2/src/threads/thread.h0000644000175000001440000000347711127714047013770 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_THREAD #define _H_THREAD #include class t_thread { private: pthread_t tid; // Thread id public: t_thread(void *(*start_routine)(void *), void *arg); // These methods throw an int (return value of libpthread function) // when they fail void join(void); void detach(void); void kill(void); void cancel(void); void set_sched_fifo(int priority); // Get thread id pthread_t get_tid(void) const; // Get thread id of current thread static pthread_t self(void); // Check if 2 threads are equal bool is_equal(const t_thread &thr) const; bool is_equal(const pthread_t &_tid) const; bool is_self(void) const; static bool is_self(const pthread_t &_tid); // Check if LinuxThreads or NPTL is active. This check is needed // for correctly handling signals. Signal handling in LinuxThreads // is quite different from signal handling in NPTL. // This checks creates a new thread and waits on its termination, // so you better cache its result for efficient future checks. static bool is_LinuxThreads(void); }; #endif twinkle-1.4.2/src/threads/thread.cpp0000644000175000001440000000507211127714056014314 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "thread.h" // Scratch variables for checking LinuxThreads vs NPTL static pid_t pid_thread; t_thread::t_thread(void *(*start_routine)(void *), void *arg) { int ret; ret = pthread_create(&tid, NULL, start_routine, arg); if (ret != 0) throw ret; } void t_thread::join(void) { int ret = pthread_join(tid, NULL); if (ret != 0) throw ret; } void t_thread::detach(void) { int ret = pthread_detach(tid); if (ret != 0) throw ret; } void t_thread::kill(void) { int ret = pthread_kill(tid, SIGKILL); if (ret != 0) throw ret; } void t_thread::cancel(void) { int ret = pthread_cancel(tid); if (ret != 0) throw ret; } void t_thread::set_sched_fifo(int priority) { struct sched_param sp; sp.sched_priority = priority; int ret = pthread_setschedparam(tid, SCHED_FIFO, &sp); if (ret != 0) throw ret; } pthread_t t_thread::get_tid(void) const { return tid; } pthread_t t_thread::self(void) { return pthread_self(); } bool t_thread::is_equal(const t_thread &thr) const { return pthread_equal(tid, thr.get_tid()); } bool t_thread::is_equal(const pthread_t &_tid) const { return pthread_equal(tid, _tid); } bool t_thread::is_self(void) const { return pthread_equal(tid, pthread_self()); } bool t_thread::is_self(const pthread_t &_tid) { return pthread_equal(_tid, pthread_self()); } void *check_threading_impl(void *arg) { pid_thread = getpid(); pthread_exit(NULL); } bool t_thread::is_LinuxThreads(void) { t_thread *thr = new t_thread(check_threading_impl, NULL); try { thr->join(); } catch (int) { // Thread is already terminated. } delete thr; // In LinuxThreads each thread has a different pid. // In NPTL all threads have the same pid. return (getpid() != pid_thread); } twinkle-1.4.2/src/audits/0000777000175000001440000000000011151327736012262 500000000000000twinkle-1.4.2/src/audits/Makefile.am0000644000175000001440000000017511134651070014225 00000000000000AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src noinst_LIBRARIES = libaudits.a libaudits_a_SOURCES =\ memman.cpp\ memman.h twinkle-1.4.2/src/audits/Makefile.in0000644000175000001440000003711511151323406014240 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/audits DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libaudits_a_AR = $(AR) $(ARFLAGS) libaudits_a_LIBADD = am_libaudits_a_OBJECTS = memman.$(OBJEXT) libaudits_a_OBJECTS = $(am_libaudits_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libaudits_a_SOURCES) DIST_SOURCES = $(libaudits_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src noinst_LIBRARIES = libaudits.a libaudits_a_SOURCES = \ memman.cpp\ memman.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/audits/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/audits/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libaudits.a: $(libaudits_a_OBJECTS) $(libaudits_a_DEPENDENCIES) -rm -f libaudits.a $(libaudits_a_AR) libaudits.a $(libaudits_a_OBJECTS) $(libaudits_a_LIBADD) $(RANLIB) libaudits.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memman.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/audits/memman.cpp0000644000175000001440000001475211127714056014163 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "memman.h" #include "log.h" #include "util.h" ////////////////////// // class t_ptr_info ////////////////////// t_ptr_info::t_ptr_info(const string &_filename, int _lineno, bool _is_array) : filename(_filename) { lineno = _lineno; is_array = _is_array; } ////////////////////// // class t_memman ////////////////////// t_memman::t_memman() { num_new = 0; num_new_duplicate = 0; num_delete = 0; num_delete_mismatch = 0; num_array_mixing = 0; } void t_memman::trc_new(void *p, const string &filename, int lineno, bool is_array) { mtx_memman.lock(); num_new++; // Check if pointer already exists map::iterator i; i = pointer_map.find(p); if (i != pointer_map.end()) { // Most likely this is an error in the usage of the // MEMMAN_NEW. A wrong pointer has been passed. num_new_duplicate++; // Unlock now. If memman gets called again via the log, // there will be no dead lock. mtx_memman.unlock(); log_file->write_header("t_memman::trc_new", LOG_MEMORY, LOG_WARNING); log_file->write_raw(filename); log_file->write_raw(", line "); log_file->write_raw(lineno); log_file->write_raw(": pointer to "); log_file->write_raw(ptr2str(p)); log_file->write_raw(" has already been allocated.\n"); log_file->write_raw("It was allocated here: "); log_file->write_raw(i->second.filename); log_file->write_raw(", line "); log_file->write_raw(i->second.lineno); log_file->write_endl(); log_file->write_footer(); return; } t_ptr_info pinfo(filename, lineno, is_array); pointer_map[p] = pinfo; mtx_memman.unlock(); } void t_memman::trc_delete(void *p, const string &filename, int lineno, bool is_array) { mtx_memman.lock(); num_delete++; map::iterator i; i = pointer_map.find(p); // Check if the pointer allocation has been reported if (i == pointer_map.end()) { num_delete_mismatch++; mtx_memman.unlock(); log_file->write_header("t_memman::trc_delete", LOG_MEMORY, LOG_WARNING); log_file->write_raw(filename); log_file->write_raw(", line "); log_file->write_raw(lineno); log_file->write_raw(": pointer to "); log_file->write_raw(ptr2str(p)); log_file->write_raw(" is deleted.\n"); log_file->write_raw("This pointer is not allocated however.\n"); log_file->write_footer(); return; } bool array_mismatch = (is_array != i->second.is_array); // Check mixing of array new/delete // NOTE: after the pointer has been erased from pointer_map, the // iterator i is invalid. // The mutex mtx_memman should be unlocked before logging to // avoid dead locks. if (array_mismatch) { num_array_mixing++; string allocation_filename = i->second.filename; int allocation_lineno = i->second.lineno; bool allocation_is_array = i->second.is_array; pointer_map.erase(p); mtx_memman.unlock(); log_file->write_header("t_memman::trc_delete", LOG_MEMORY, LOG_WARNING); log_file->write_raw(filename); log_file->write_raw(", line "); log_file->write_raw(lineno); log_file->write_raw(": pointer to "); log_file->write_raw(ptr2str(p)); log_file->write_raw(" is deleted "); if (is_array) { log_file->write_raw("as array (delete []).\n"); } else { log_file->write_raw("normally (delete).\n"); } log_file->write_raw("But it was allocated "); if (allocation_is_array) { log_file->write_raw("as array (new []) \n"); } else { log_file->write_raw("normally (new) \n"); } log_file->write_raw(allocation_filename); log_file->write_raw(", line "); log_file->write_raw(allocation_lineno); log_file->write_endl(); log_file->write_footer(); } else { pointer_map.erase(p); mtx_memman.unlock(); } } void t_memman::report_leaks(void) { mtx_memman.lock(); if (pointer_map.empty()) { if (num_array_mixing == 0) { log_file->write_report( "All pointers have correctly been deallocated.", "t_memman::report_leaks", LOG_MEMORY, LOG_INFO); } else { log_file->write_header("t_memman::report_leaks", LOG_MEMORY, LOG_WARNING); log_file->write_raw("All pointers have been deallocated."), log_file->write_raw( "Mixing of array/non-array caused memory loss though."); log_file->write_footer(); } mtx_memman.unlock(); return; } log_file->write_header("t_memman::report_leaks", LOG_MEMORY, LOG_WARNING); log_file->write_raw("The following pointers were never deallocated:\n"); for (map::const_iterator i = pointer_map.begin(); i != pointer_map.end(); i++) { log_file->write_raw(ptr2str(i->first)); log_file->write_raw(" allocated from "); log_file->write_raw(i->second.filename); log_file->write_raw(", line "); log_file->write_raw(i->second.lineno); log_file->write_endl(); } log_file->write_footer(); mtx_memman.unlock(); } void t_memman::report_stats(void) { mtx_memman.lock(); log_file->write_header("t_memman::report_stats", LOG_MEMORY, LOG_INFO); log_file->write_raw("Number of allocations: "); log_file->write_raw(num_new); log_file->write_endl(); log_file->write_raw("Number of duplicate allocations: "); log_file->write_raw(num_new_duplicate); log_file->write_endl(); log_file->write_raw("Number of de-allocations: "); log_file->write_raw(num_delete); log_file->write_endl(); log_file->write_raw("Number of mismatched de-allocations: "); log_file->write_raw(num_delete_mismatch); log_file->write_endl(); log_file->write_raw("Number of array/non-array mixed operations: "); log_file->write_raw(num_array_mixing); log_file->write_endl(); unsigned long num_unalloc = num_new - num_new_duplicate - num_delete + num_delete_mismatch; log_file->write_raw("Number of unallocated pointers: "); log_file->write_raw(num_unalloc); log_file->write_endl(); log_file->write_footer(); mtx_memman.unlock(); } twinkle-1.4.2/src/audits/memman.h0000644000175000001440000000505211127714047013621 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MEMMAN_H #define _MEMMAN_H #include #include #include "threads/mutex.h" #define MEMMAN_NEW(ptr) memman->trc_new((ptr), __FILE__, __LINE__) #define MEMMAN_NEW_ARRAY(ptr) memman->trc_new((ptr), __FILE__, __LINE__, true) #define MEMMAN_DELETE(ptr) memman->trc_delete((ptr), __FILE__, __LINE__) #define MEMMAN_DELETE_ARRAY(ptr) memman->trc_delete((ptr), __FILE__, __LINE__, true) #define MEMMAN_REPORT { memman->report_stats(); memman->report_leaks(); } using namespace std; // Memory manager // Trace memory allocations and deallocations class t_ptr_info { public: // Src file from which pointer has been allocated string filename; // Line number of memman trace command tracing this pointer int lineno; // Indicates if the pointer points to an array bool is_array; t_ptr_info() {}; t_ptr_info(const string &_filename, int _lineno, bool _is_array); }; class t_memman { private: // Map of allocated pointers map pointer_map; // Statistics unsigned long num_new; // number of new's unsigned long num_new_duplicate; // number of duplicate new's unsigned long num_delete; // number of delete's unsigned long num_delete_mismatch; // number of delete's for without a new unsigned long num_array_mixing; // number of array/non-array mixes // Mutex to protect operations on the memory manager t_mutex mtx_memman; public: t_memman(); // Report pointer allocation void trc_new(void *p, const string &filename, int lineno, bool is_array = false); // Report pointer deallocation void trc_delete(void *p, const string &filename, int lineno, bool is_array = false); // Write a memory leak report to log void report_leaks(void); // Write statistics to log void report_stats(void); }; extern t_memman *memman; #endif twinkle-1.4.2/src/auth.h0000644000175000001440000001126211127714047012017 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * SIP authentication */ #ifndef _AUTH_H #define _AUTH_H #include "parser/credentials.h" #include "parser/request.h" #include "sockets/url.h" #include using namespace std; /** Size of the credentials cache. */ #define AUTH_CACHE_SIZE 50 /** Credentials cache entry. */ class t_cr_cache_entry { public: /** * Destination for which credentials are cached. * This is not used for the SIP authentication itself. */ t_url to; /** The credentials. */ t_credentials credentials; /** Password. */ string passwd; /** Indicates if proxy authentication was requested. */ bool proxy; /** Constructor. */ t_cr_cache_entry(const t_url &_to, const t_credentials &_cr, const string &_passwd, bool _proxy); }; /** An object of this class authorizes a request given some credentials. */ class t_auth { private: /** Indicates if the current registration request is a re-REGISTER. */ bool re_register; /** * LRU cache credentials for a destination. * The first entry in the list is the least recently used. */ list cache; /** * Find a cache entry that matches the realm. * @param _to [in] Destination for which authentication is needed. * @param realm [in] The authentication realm. * @param proxy [in] Indicates if proxy authentication was requested. * @return An iterator to the cached credentials if found. * @return The end iterator if not found. */ list::iterator find_cache_entry(const t_url &_to, const string &realm, bool proxy=false); /** * Update cached credentials. * If the cache does not contain the credentials already * then it will be added to the end of the list. If the cache * already contains the maximum number of entries, then the least * recently used entry will be removed. * If the cache already contains an entry for credentials, then * this entry will be moved to the end of the list. * @param to [in] Destination for which authentication is needed. * @param cr [in] Credentials to update. * @param passwd [in] The password to store. * @param proxy Indicates if proxy authentication was requested. */ void update_cache(const t_url &to, const t_credentials &cr, const string &passwd, bool proxy); /** * Check if authorization failed. * Authorization failed if the challenge is for a realm for which * the request already contains an authorization header and the * challenge is not stale. * @return true, if authorization failed. * @return false, otherwise. */ bool auth_failed(t_request *r, const t_challenge &c, bool proxy=false) const; /** * Remove existing credentials for this challenge from the * authorization or proxy-authorization header. * @param r [in] The request from which the credentials must be removed. * @param c [in] The challenge for which the credentials must be removed. * @param proxy [in] Indicates if proxy authentication was requested. */ void remove_credentials(t_request *r, const t_challenge &c, bool proxy=false) const; public: /** Constructor. */ t_auth(); /** * Authorize the request based on the challenge in the response * @param user_config [in] The user profile. * @param r [in] The request to be authorized. * @param resp [in] The response containing the challenge. * @return true, if authorization succeeds. * @return false, if authorization fails. * @post On succesful authorization, the credentials has been added to * the request in the proper header (Authorization or Proxy-Authorization). */ bool authorize(t_user *user_config, t_request *r, t_response *resp); /** * Remove credentials for a particular realm from cache. * @param realm [in] The authentication realm. */ void remove_from_cache(const string &realm); /** * Set the re-REGISTER indication. * @param on [in] Value to set. */ void set_re_register(bool on); /** Get the re-REGISTER indication. */ bool get_re_register(void) const; }; #endif twinkle-1.4.2/src/dialog.cpp0000644000175000001440000031413711143636641012660 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "call_history.h" #include "call_script.h" #include "dialog.h" #include "exceptions.h" #include "line.h" #include "log.h" #include "phone_user.h" #include "sub_refer.h" #include "util.h" #include "userintf.h" #include "audio/rtp_telephone_event.h" #include "audits/memman.h" #include "im/im_iscomposing_body.h" #include "sdp/sdp.h" #include "sockets/socket.h" #include "stun/stun_transaction.h" extern t_event_queue *evq_sender; extern t_event_queue *evq_trans_mgr; extern string user_host; extern string local_hostname; extern t_phone *phone; // Protected // Create a request within a dialog // RFC 3261 12.2.1.1 t_request *t_dialog::create_request(t_method m) { assert(state != DS_NULL); t_user *user_config = phone_user->get_user_profile(); // RFC 3261 9.1 if (m == CANCEL) { t_request *r = new t_request(m); MEMMAN_NEW(r); assert(req_out_invite); t_request *orig_req = req_out_invite->get_request(); r->hdr_to = orig_req->hdr_to; r->hdr_from = orig_req->hdr_from; r->hdr_call_id = orig_req->hdr_call_id; r->hdr_cseq.set_seqnr(orig_req->hdr_cseq.seqnr); r->hdr_cseq.set_method(CANCEL); r->hdr_via = orig_req->hdr_via; // RFC 3261 8.1.1.7 r->hdr_max_forwards.set_max_forwards(MAX_FORWARDS); r->hdr_route = orig_req->hdr_route; SET_HDR_USER_AGENT(r->hdr_user_agent); r->uri = orig_req->uri; // RFC 3263 4 // CANCEL for a particular SIP request MUST be sent to the same SIP // server that the SIP request was delivered to. t_ip_port ip_port; orig_req->get_destination(ip_port, *user_config); r->set_destination(ip_port); return r; } t_request *r = t_abstract_dialog::create_request(m); // CSeq header if (m == ACK) { assert(req_out_invite); // Local sequence number was incremented by t_abstract_dialog. // Decrement as it ACK does not take a new sequence number. local_seqnr--; // ACK has the same sequence number // as the INVITE. r->hdr_cseq.set_seqnr(req_out_invite->get_request()->hdr_cseq.seqnr); // RFC 3261 22.1 // Authorization and Proxy-Authorization headers in INVITE // must be repeated in ACK r->hdr_authorization = req_out_invite->get_request()-> hdr_authorization; r->hdr_proxy_authorization = req_out_invite->get_request()-> hdr_proxy_authorization; } // Contact header t_contact_param contact; switch (m) { case REFER: case SUBSCRIBE: case NOTIFY: // RFC 3265 7.1, RFC 3515 2.2 // Contact header is mandatory contact.uri.set_url(line->create_user_contact(h_ip2str(r->get_local_ip()))); r->hdr_contact.add_contact(contact); break; default: break; } // Privacy header if (line->get_hide_user()) { r->hdr_privacy.add_privacy(PRIVACY_ID); } return r; } // NULL state. Waiting for incoming INVITE void t_dialog::state_null(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); if (r->method != INVITE) { state = DS_TERMINATED; return; } // Set local tag if (r->hdr_to.tag.size() == 0) { local_tag = NEW_TAG; } else { local_tag = r->hdr_to.tag; } // If STUN is enabled, then first send a STUN binding request to // discover the IP adderss and port for media. if (phone->use_stun(user_config)) { // The STUN transaction may take a while. // Send 100 Trying resp = r->create_response(R_100_TRYING); resp->hdr_to.set_tag(""); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; if (!stun_bind_media()) { // STUN request failed. Send a 500 on the INVITE. resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); resp->hdr_to.set_tag(local_tag); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; state = DS_TERMINATED; return; } } call_id = r->hdr_call_id.call_id; // Initialize local seqnr local_seqnr = NEW_SEQNR; local_resp_nr = NEW_SEQNR; remote_tag = r->hdr_from.tag; local_uri = r->hdr_to.uri; local_display = r->hdr_to.display; remote_uri = r->hdr_from.uri; remote_display = r->hdr_from.display; // Set remote target URI and display name remote_target_uri = r->hdr_contact.contact_list.front().uri; remote_target_display = r-> hdr_contact.contact_list.front().display; // Set route set if (r->hdr_record_route.is_populated()) { route_set = r->hdr_record_route.route_list; } // RFC 3261 13.2.1 // An initial INVITE should list all supported extensions. // Set supported extensions if (r->hdr_supported.is_populated()) { remote_extensions.insert(r->hdr_supported.features.begin(), r->hdr_supported.features.end()); } // Media information int warn_code; string warn_text; if (r->body) { switch(r->body->get_type()) { case BODY_SDP: if (session->process_sdp_offer((t_sdp*)r->body, warn_code, warn_text)) { session->recvd_offer = true; break; } // Unsupported media resp = r->create_response( R_488_NOT_ACCEPTABLE_HERE); resp->hdr_to.set_tag(local_tag); resp->hdr_warning.add_warning(t_warning(LOCAL_HOSTNAME, 0, warn_code, warn_text)); line->send_response(resp, tuid, tid); // Create call history record line->call_hist_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); line->call_hist_record.fail_call(resp); MEMMAN_DELETE(resp); delete resp; state = DS_TERMINATED; return; default: // Unsupported body type. Reject call. resp = r->create_response( R_415_UNSUPPORTED_MEDIA_TYPE); resp->hdr_to.set_tag(local_tag); // RFC 3261 21.4.13 SET_HDR_ACCEPT(resp->hdr_accept); // Create call history record line->call_hist_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); line->call_hist_record.fail_call(resp); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; state = DS_TERMINATED; return; } } resp = r->create_response(R_180_RINGING); resp->hdr_to.set_tag(local_tag); // RFC 3261 13.3.1.1 // A provisional response creates an early dialog, so // copy the Record-Route header and add a Contact // header. // Copy the Record-Route header from request to response if (r->hdr_record_route.is_populated()) { resp->hdr_record_route = r->hdr_record_route; } // Set Contact header t_contact_param contact; contact.uri.set_url(line->create_user_contact(h_ip2str(resp->get_local_ip()))); resp->hdr_contact.add_contact(contact); // RFC 3262 3 // Send 180 response reliable if needed if (r->hdr_require.contains(EXT_100REL) || (r->hdr_supported.contains(EXT_100REL) && (user_config->get_ext_100rel() == EXT_PREFERRED || user_config->get_ext_100rel() == EXT_REQUIRED))) { resp->hdr_require.add_feature(EXT_100REL); resp->hdr_rseq.set_resp_nr(++local_resp_nr); // RFC 3262 5 // Create SDP offer in first reliable response if no offer // was received in INVITE. // This implentation does not create an answer in an // reliable 1xx response if an offer was received. if (!session->recvd_offer) { session->create_sdp_offer(resp, SDP_O_USER); } // Keep a copy of the response for retransmission resp_1xx_invite = (t_response *)resp->copy(); // Start 100rel timeout and guard timers line->start_timer(LTMR_100REL_GUARD, get_object_id()); line->start_timer(LTMR_100REL_TIMEOUT, get_object_id()); } line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); MEMMAN_DELETE(resp); delete resp; ui->cb_incoming_call(user_config, line->get_line_number(), r); line->call_hist_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); state = DS_W4ANSWER; } // A provisional answer has been sent. Waiting for user to answer. void t_dialog::state_w4answer(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); bool tear_down = false; bool answer_call = false; t_call_script script_in_call_failed(user_config, t_call_script::TRIGGER_IN_CALL_FAILED, line->get_line_number() + 1); switch (r->method) { case CANCEL: // Cancel the request and terminate the dialog. // A response on the CANCEL is already given by dialog::recvd_cancel resp = req_in_invite->get_request()-> create_response(R_487_REQUEST_TERMINATED); resp->hdr_to.set_tag(local_tag); line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->call_hist_record.fail_call(resp); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; ui->cb_call_cancelled(line->get_line_number()); state = DS_TERMINATED; break; case BYE: // Send 200 on the BYE request resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; // Send a 487 response to terminate the pending request resp = req_in_invite->get_request()->create_response( R_487_REQUEST_TERMINATED); resp->hdr_to.set_tag(local_tag); line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->call_hist_record.fail_call(resp); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; ui->cb_far_end_hung_up(line->get_line_number()); state = DS_TERMINATED; break; case PRACK: // RFC 3262 3 if (respond_prack(r, tuid, tid)) { answer_call = answer_after_prack; // RFC 3262 5 // If an offer was sent in the 1xx response, then PRACK must // contain an answer if (session->sent_offer && r->body) { int warn_code; string warn_text; if (r->body->get_type() != BODY_SDP) { // Only SDP bodies are supported ui->cb_unsupported_content_type( line->get_line_number(), r); tear_down = true; } else if (session->process_sdp_answer((t_sdp *)r->body, warn_code, warn_text)) { session->recvd_answer = true; session->start_rtp(); } else { // SDP answer is not supported. // Tear down the call. ui->cb_sdp_answer_not_supported( line->get_line_number(), warn_text); tear_down = true; } } if (session->sent_offer && !r->body) { ui->cb_sdp_answer_missing(line->get_line_number()); tear_down = true; } } if (tear_down) { resp = req_in_invite->get_request()->create_response( R_400_BAD_REQUEST, "SDP answer in PRACK missing or unsupported"); resp->hdr_to.set_tag(local_tag); line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->call_hist_record.fail_call(resp); // Trigger call script t_call_script script(user_config, t_call_script::TRIGGER_IN_CALL_FAILED, line->get_line_number() + 1); script.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; state = DS_TERMINATED; } else if (answer_call) { answer(); } break; default: // INVITE transaction has not been completed. Deny // other requests within the dialog. resp = r->create_response(R_500_INTERNAL_SERVER_ERROR, "Session not yet established"); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } } void t_dialog::state_w4answer(t_line_timer timer) { t_ip_port ip_port; t_response *resp; t_user *user_config = phone_user->get_user_profile(); t_call_script script_in_call_failed(user_config, t_call_script::TRIGGER_IN_CALL_FAILED, line->get_line_number() + 1); // RFC 3262 3 switch(timer) { case LTMR_100REL_TIMEOUT: // Retransmit 1xx response. // Send the response directly to the sender thread // bypassing the transaction layer. As this is a retransmission // from the TU, the transaction layer does not need to know. resp_1xx_invite->get_destination(ip_port); if (ip_port.ipaddr == 0) { // This should not happen. The response has been // sent before so it should be possible to sent // it again. Ignore the timeout. When the 100rel // guard timer expires, the dialog will be // cleaned up. break; } evq_sender->push_network(resp_1xx_invite, ip_port); line->start_timer(LTMR_100REL_TIMEOUT, get_object_id()); break; case LTMR_100REL_GUARD: line->stop_timer(LTMR_100REL_TIMEOUT, get_object_id()); // PRACK was not received in time. Tear down the call. resp = req_in_invite->get_request()->create_response( R_500_INTERNAL_SERVER_ERROR, "100rel timeout"); resp->hdr_to.set_tag(local_tag); line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->call_hist_record.fail_call(resp); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; remove_client_request(&req_in_invite); MEMMAN_DELETE(resp_1xx_invite); delete resp_1xx_invite; resp_1xx_invite = NULL; state = DS_TERMINATED; log_file->write_report("LTMR_100REL_GUARD expired.", "t_dialog::state_w4answer"); ui->cb_100rel_timeout(line->get_line_number()); break; default: // Other timeouts are not expected. Ignore. break; } } // 200 OK has been sent. Waiting for ACK void t_dialog::state_w4ack(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); bool tear_down = false; t_client_request *cr; t_call_script script_out_call_failed(user_config, t_call_script::TRIGGER_OUT_CALL_FAILED, line->get_line_number() + 1); switch(r->method) { case ACK: // Dialog is established now. line->stop_timer(LTMR_ACK_TIMEOUT, get_object_id()); line->stop_timer(LTMR_ACK_GUARD, get_object_id()); remove_client_request(&req_in_invite); MEMMAN_DELETE(resp_invite); delete resp_invite; resp_invite = NULL; // If no offer was received in INVITE, then an offer // has been sent in 200 OK or reliable 1xx (RFC 3262). // Therefor an answer must be present in ACK if (!session->recvd_offer && r->body) { int warn_code; string warn_text; if (r->body->get_type() != BODY_SDP) { // Only SDP bodies are supported ui->cb_unsupported_content_type( line->get_line_number(), r); tear_down = true; } else if (session->process_sdp_answer((t_sdp *)r->body, warn_code, warn_text)) { session->recvd_answer = true; session->start_rtp(); } else { // SDP answer is not supported. // Tear down the call. ui->cb_sdp_answer_not_supported( line->get_line_number(), warn_text); tear_down = true; } } if (!session->recvd_offer && !r->body) { ui->cb_sdp_answer_missing(line->get_line_number()); tear_down = true; } if (end_after_ack) { ui->cb_far_end_hung_up(line->get_line_number()); state = DS_TERMINATED; } else { state = DS_CONFIRMED; if (tear_down) { send_bye(); } } ui->cb_call_established(line->get_line_number()); break; case BYE: // Send 200 on the BYE request resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); // Trigger call script script_out_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; line->call_hist_record.end_call(true); // The session will be ended when an ACK has been // received. end_after_ack = true; break; case PRACK: // RFC 3262 3 // This is a late PRACK as the call is answered already. // Respond in a normal way to the PRACK respond_prack(r, tuid, tid); break; default: // Queue the request as ACK needs to be received first. // Note that the tuid value is not stored in the queue. // For an incoming request tuid is always 0. cr = new t_client_request(user_config, r, tid); MEMMAN_NEW(cr); inc_req_queue.push_back(cr); log_file->write_header("t_dialog::state_w4ack", LOG_NORMAL, LOG_INFO); log_file->write_raw("Waiting for ACK.\n"); log_file->write_raw("Queue incoming "); log_file->write_raw(method2str(r->method, r->unknown_method)); log_file->write_endl(); log_file->write_footer(); break; } } void t_dialog::state_w4ack_re_invite(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); bool tear_down = false; t_call_script script_out_call_failed(user_config, t_call_script::TRIGGER_OUT_CALL_FAILED, line->get_line_number() + 1); switch(r->method) { case ACK: // re_INVITE is finished now line->stop_timer(LTMR_ACK_TIMEOUT, get_object_id()); line->stop_timer(LTMR_ACK_GUARD, get_object_id()); remove_client_request(&req_in_invite); MEMMAN_DELETE(resp_invite); delete resp_invite; resp_invite = NULL; // If no offer was received in INVITE, then an offer // has been sent in 200 OK or reliable 1xx (RFC 3262). // Therefor an answer must be present in ACK if (!session_re_invite->recvd_offer && r->body) { int warn_code; string warn_text; if (r->body->get_type() != BODY_SDP) { // Only SDP bodies are supported ui->cb_unsupported_content_type( line->get_line_number(), r); tear_down = true; } else if (session_re_invite->process_sdp_answer( (t_sdp *)r->body, warn_code, warn_text)) { session_re_invite->recvd_answer = true; } else { // SDP answer is not supported. // Tear down the call. ui->cb_sdp_answer_not_supported( line->get_line_number(), warn_text); tear_down = true; } } if (!session_re_invite->recvd_offer && !r->body) { ui->cb_sdp_answer_missing(line->get_line_number()); tear_down = true; } if (end_after_ack) { ui->cb_far_end_hung_up(line->get_line_number()); state = DS_TERMINATED; } else { state = DS_CONFIRMED; if (tear_down) { send_bye(); } else { // Make the new session description current activate_new_session(); } } break; case BYE: // Send 200 on the BYE request resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); // Trigger call script script_out_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; line->call_hist_record.end_call(true); // The session will be ended when an ACK has been // received. end_after_ack = true; break; default: // ACK has not been received. Handle other incoming request // as if we are in the confirmed state. These incoming requests // should not change state. state_confirmed(r, tuid, tid); assert(state == DS_W4ACK_RE_INVITE); break; } } // RFC 3261 13.3.1.4 void t_dialog::state_w4ack(t_line_timer timer) { t_ip_port ip_port; // NOTE: this code is also executed for re-INVITE ACK time-outs // timeout handling for INVITE/re-INVITE is the same switch(timer) { case LTMR_ACK_TIMEOUT: // Retransmit 2xx response. // Send the response directly to the sender thread // as the INVITE transaction completed already. // (see RFC 3261 17.2.1) if (!resp_invite) break; // there is no response to send resp_invite->get_destination(ip_port); if (ip_port.ipaddr == 0) { // This should not happen. The response has been // sent before so it should be possible to sent // it again. Ignore the timeout. When the ACK // guard timer expires, the dialog will be // cleaned up. break; } evq_sender->push_network(resp_invite, ip_port); line->start_timer(LTMR_ACK_TIMEOUT, get_object_id()); break; case LTMR_ACK_GUARD: line->stop_timer(LTMR_ACK_TIMEOUT, get_object_id()); // Consider dialog as established and tear down call remove_client_request(&req_in_invite); MEMMAN_DELETE(resp_invite); delete resp_invite; resp_invite = NULL; state = DS_CONFIRMED; log_file->write_report("LTMR_ACK_GUARD expired.", "t_dialog::state_w4ack"); if (end_after_ack) { state = DS_TERMINATED; } else { send_bye(); } ui->cb_ack_timeout(line->get_line_number()); break; default: // Other timeouts are not expected. Ignore. break; } } void t_dialog::state_w4ack_re_invite(t_line_timer timer) { state_w4ack(timer); } void t_dialog::state_w4re_invite_resp(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); t_call_script script_remote_release(user_config, t_call_script::TRIGGER_REMOTE_RELEASE, line->get_line_number() + 1); switch(r->method) { case BYE: resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); // Trigger call script script_remote_release.exec_notify(r); MEMMAN_DELETE(resp); delete resp; ui->cb_far_end_hung_up(line->get_line_number()); line->call_hist_record.end_call(true); if (!sub_refer) { state = DS_TERMINATED; } else { state = DS_CONFIRMED_SUB; if (sub_refer->get_role() == SR_SUBSCRIBER) { // End subscription sub_refer->unsubscribe(); } } break; case ACK: // Ignore ACK break; case OPTIONS: resp = line->create_options_response(r, true); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; case PRACK: // RFC 3262 3 // This is a late PRACK. Respond in a normal way. respond_prack(r, tuid, tid); break; case SUBSCRIBE: process_subscribe(r, tuid, tid); break; case NOTIFY: process_notify(r, tuid, tid); break; default: resp = r->create_response(R_500_INTERNAL_SERVER_ERROR, "Waiting for re-INVITE response"); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } } // In the confirmed state, requests will be responded. void t_dialog::state_confirmed(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); t_call_script script_remote_release(user_config, t_call_script::TRIGGER_REMOTE_RELEASE, line->get_line_number() + 1); switch(r->method) { case INVITE: // re-INVITE process_re_invite(r, tuid, tid); break; case BYE: resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); // Trigger call script script_remote_release.exec_notify(r); MEMMAN_DELETE(resp); delete resp; ui->cb_far_end_hung_up(line->get_line_number()); line->call_hist_record.end_call(true); if (!sub_refer) { state = DS_TERMINATED; } else { state = DS_CONFIRMED_SUB; if (sub_refer->get_role() == SR_SUBSCRIBER) { // End subscription sub_refer->unsubscribe(); } } break; case ACK: // Ignore ACK break; case OPTIONS: resp = line->create_options_response(r, true); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; case PRACK: // RFC 3262 3 // This is a late PRACK. Respond in a normal way. respond_prack(r, tuid, tid); break; case REFER: process_refer(r, tuid, tid); break; case SUBSCRIBE: process_subscribe(r, tuid, tid); break; case NOTIFY: process_notify(r, tuid, tid); break; case INFO: process_info(r, tuid, tid); break; case MESSAGE: process_message(r, tuid, tid); break; default: resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } } void t_dialog::state_confirmed(t_line_timer timer) { switch(timer) { case LTMR_GLARE_RETRY: switch(reinvite_purpose) { case REINVITE_HOLD: hold(); break; case REINVITE_RETRIEVE: retrieve(); line->retry_retrieve_succeeded(); // Note that the re-INVITE is not completed here yet. // If re-INVITE fails then line->failed_retrieve will // be called later. break; default: assert(false); } break; default: // Other timeouts are not exepcted. Ignore. break; } } void t_dialog::state_confirmed_sub(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; switch(r->method) { case OPTIONS: resp = line->create_options_response(r, true); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; case SUBSCRIBE: process_subscribe(r, tuid, tid); break; case NOTIFY: process_notify(r, tuid, tid); break; default: resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } if (!sub_refer) { // The subscription has been terminated already. state = DS_TERMINATED; } else if (sub_refer->get_state() == SS_TERMINATED) { MEMMAN_DELETE(sub_refer); delete sub_refer; sub_refer = NULL; state = DS_TERMINATED; } } void t_dialog::process_re_invite(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); session_re_invite = session->create_clean_copy(); // Media information int warn_code; string warn_text; if (r->body) { switch(r->body->get_type()) { case BODY_SDP: if (session_re_invite-> process_sdp_offer((t_sdp*)r->body, warn_code, warn_text)) { session_re_invite->recvd_offer = true; break; } // Unsupported media resp = r->create_response( R_488_NOT_ACCEPTABLE_HERE); resp->hdr_warning.add_warning(t_warning(LOCAL_HOSTNAME, 0, warn_code, warn_text)); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; MEMMAN_DELETE(session_re_invite); delete session_re_invite; session_re_invite = NULL; // Stay in the confirmed state. The sender of the // request has to determine if the dialog needs to // be torn down by sending a BYE. return; default: // Unsupported body type. Reject call. resp = r->create_response( R_415_UNSUPPORTED_MEDIA_TYPE); // RFC 3261 21.4.13 SET_HDR_ACCEPT(resp->hdr_accept); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; MEMMAN_DELETE(session_re_invite); delete session_re_invite; session_re_invite = NULL; // Stay in the confirmed state. return; } } // If STUN is enabled, then first send a STUN binding request to // discover the IP adderss and port for media if no RTP stream // is currently active. if (phone->use_stun(user_config) && !session->is_rtp_active()) { // The STUN transaction may take a while. // Send 100 Trying resp = r->create_response(R_100_TRYING); resp->hdr_to.set_tag(""); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; if (!stun_bind_media()) { // STUN request failed. Send a 500 on the INVITE. resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); resp->hdr_to.set_tag(local_tag); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; state = DS_TERMINATED; return; } } // Refresh target if (r->hdr_contact.is_populated() && r->hdr_contact.contact_list.size() > 0) { remote_target_uri = r->hdr_contact.contact_list.front().uri; remote_target_display = r-> hdr_contact.contact_list.front().display; } // Send 200 OK resp_invite = r->create_response(R_200_OK); resp_invite->hdr_to.set_tag(local_tag); // Set Contact header t_contact_param contact; contact.uri.set_url(line->create_user_contact(h_ip2str(resp_invite->get_local_ip()))); resp_invite->hdr_contact.add_contact(contact); // Set Allow and Supported headers SET_HDR_ALLOW(resp_invite->hdr_allow, user_config); SET_HDR_SUPPORTED(resp_invite->hdr_supported, user_config); // RFC 3261 13.3.1.4 // Create SDP offer if no offer was received in INVITE and no offer // was sent in a reliable 1xx response (RFC 3262 5). // Otherwise create an SDP answer. if (!session_re_invite->recvd_offer && !session_re_invite->sent_offer) { session_re_invite->create_sdp_offer(resp_invite, SDP_O_USER); } else { session_re_invite->create_sdp_answer(resp_invite, SDP_O_USER); } line->send_response(resp_invite, tuid, tid); line->start_timer(LTMR_ACK_GUARD, get_object_id()); line->start_timer(LTMR_ACK_TIMEOUT, get_object_id()); state = DS_W4ACK_RE_INVITE; } void t_dialog::process_refer(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); t_contact_param contact; refer_accepted = true; // RFC 3515 if (sub_refer || !user_config->get_allow_refer()) { // A reference is already in progress or REFER is not // allowed. resp = r->create_response(R_603_DECLINE); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; refer_accepted = false; return; } // Check if the URI scheme is supported if (r->hdr_refer_to.uri.get_scheme() != "sip") { resp = r->create_response(R_416_UNSUPPORTED_URI_SCHEME); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; refer_accepted = false; return; } resp = r->create_response(R_202_ACCEPTED); // RFC 3515 2.2 // Contact header is mandatory contact.uri.set_url(line->create_user_contact(h_ip2str(resp->get_local_ip()))); resp->hdr_contact.add_contact(contact); if (r->hdr_refer_sub.is_populated() && !r->hdr_refer_sub.create_refer_sub) { // RFC 4488 4 resp->hdr_refer_sub.set_create_refer_sub(false); } line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; if (r->hdr_refer_sub.is_populated() && !r->hdr_refer_sub.create_refer_sub) { // RFC 4488 // The REFER-issuer requested not to create an implicit refer // subscription. log_file->write_report( "REFER-issuer requested not to create a refer subscription.", "t_dialog::process_refer"); } else { // RFC 3515 // The event header of a NOTIFY to a first REFER MAY // include the id paramter. NOTIFY's to subsequent // REFERs MUST include the id parameter (CSeq from REFER). sub_refer = new t_sub_refer(this, SR_NOTIFIER, ulong2str(r->hdr_cseq.seqnr)); MEMMAN_NEW(sub_refer); // Send immediate NOTIFY resp = new t_response(R_100_TRYING); MEMMAN_NEW(resp); if (user_config->get_ask_user_to_refer()) { // If the user has to grant permission, then the // subscription is pending. sub_refer->send_notify(resp, SUBSTATE_PENDING); } else { sub_refer->send_notify(resp, SUBSTATE_ACTIVE); } MEMMAN_DELETE(resp); delete resp; } // Ask permission to refer if (user_config->get_ask_user_to_refer()) { if (r->hdr_referred_by.is_populated()) { ui->cb_ask_user_to_refer(user_config, r->hdr_refer_to.uri, r->hdr_refer_to.display, r->hdr_referred_by.uri, r->hdr_referred_by.display); } else { ui->cb_ask_user_to_refer(user_config, r->hdr_refer_to.uri, r->hdr_refer_to.display, t_url(), ""); } } else { ui->send_refer_permission(true); } // NOTE: refer_accepted = true, though the answer to permission // is not given yet. So this means, that the refer is not // rejected at this moment. It may be rejected by the user. } void t_dialog::recvd_refer_permission(bool permission, t_request *r) { t_response *resp; // NOTE: if the REFER-issuer requested not to create a refer // subscription (RFC 4488), then no NOTIFY can be sent to signal // the rejection. if (!permission && sub_refer) { // User denied REFER // RFC 3515 2.4.5 resp = new t_response(R_603_DECLINE); MEMMAN_NEW(resp); sub_refer->send_notify(resp, SUBSTATE_TERMINATED, EV_REASON_REJECTED); MEMMAN_DELETE(resp); delete resp; } refer_accepted = permission; } void t_dialog::process_subscribe(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; if (sub_refer && sub_refer->match(r)) { sub_refer->recv_subscribe(r, tuid, tid); if (sub_refer->get_state() == SS_TERMINATED) { MEMMAN_DELETE(sub_refer); delete sub_refer; sub_refer = NULL; } return; } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST, REASON_481_SUBSCRIPTION_NOT_EXIST); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; } void t_dialog::process_notify(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; if (!sub_refer && (refer_state == REFST_W4RESP || refer_state == REFST_W4NOTIFY)) { // First NOTIFY after sending a REFER sub_refer = new t_sub_refer(this, SR_SUBSCRIBER, r->hdr_event.id); MEMMAN_NEW(sub_refer); refer_state = REFST_PENDING; } if (sub_refer && sub_refer->match(r)) { sub_refer->recv_notify(r, tuid, tid); if (sub_refer->get_state() == SS_TERMINATED) { // Set the refer state to NULL before calling the UI // call back functions as the user interface might use // the refer state to render the correct status to the // user. refer_state = REFST_NULL; // Determine outcome of the reference switch(sub_refer->get_sr_result()) { case SRR_INPROG: // The outcome of the reference is unknown. // Treat it as a success as no new info will // come to the referrer. refer_succeeded = true; ui->cb_refer_result_inprog(line->get_line_number()); break; case SRR_FAILED: refer_succeeded = false; ui->cb_refer_result_failed(line->get_line_number()); break; case SRR_SUCCEEDED: refer_succeeded = true; ui->cb_refer_result_success(line->get_line_number()); break; default: assert(false); } MEMMAN_DELETE(sub_refer); delete sub_refer; sub_refer = NULL; } else if (!sub_refer->is_pending()) { refer_state = REFST_ACTIVE; } return; } // RFC 3265 3.2.4 resp = r->create_response(R_481_TRANSACTION_NOT_EXIST, REASON_481_SUBSCRIPTION_NOT_EXIST); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; } void t_dialog::process_info(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; // RFC 2976 2.2 // A 200 OK response MUST be sent by a UAS for an INFO request with // no message body if the INFO request was successfully received for // an existing call. if (!r->body) { resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } if (r->body->get_type() != BODY_DTMF_RELAY) { resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE); resp->hdr_accept.add_media(t_media("application", "dtmf-relay")); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } char dtmf_signal = ((t_sip_body_dtmf_relay *)r->body)->signal; if (!VALID_DTMF_SYM(dtmf_signal)) { resp = r->create_response(R_400_BAD_REQUEST, "Invalid DTMF signal"); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; ui->cb_dtmf_detected(line->get_line_number(), char2dtmf_ev(dtmf_signal)); } void t_dialog::process_message(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); log_file->write_report("Received in-dialog MESSAGE.", "t_dialog::process_message", LOG_NORMAL, LOG_DEBUG); if (!r->body || !MESSAGE_CONTENT_TYPE_SUPPORTED(*r)) { resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE); // RFC 3261 21.4.13 SET_MESSAGE_HDR_ACCEPT(resp->hdr_accept); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } if (r->body && r->body->get_type() == BODY_IM_ISCOMPOSING_XML) { // Message composing indication t_im_iscomposing_xml_body *sb = dynamic_cast(r->body); im::t_composing_state state = im::string2composing_state(sb->get_state()); time_t refresh = sb->get_refresh(); ui->cb_im_iscomposing_request(line->get_user(), r, state, refresh); resp = r->create_response(R_200_OK); } else { // Instant message bool accepted = ui->cb_message_request(line->get_user(), r); if (accepted) { resp = r->create_response(R_200_OK); } else { if (user_config->get_im_max_sessions() == 0) { resp = r->create_response(R_603_DECLINE); } else { resp = r->create_response(R_486_BUSY_HERE); } } } line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; } // INVITE sent. Waiting for a first non-100 response. void t_dialog::state_w4invite_resp(t_response *r, t_tuid tuid, t_tid tid) { if (r->hdr_cseq.method != INVITE) return; t_user *user_config = phone_user->get_user_profile(); // 1XX (except 100) and 2XX establish the dialog. // Update the state for dialog establishment. // RFC 3261 12.1.2 switch (r->get_class()) { case R_1XX: if (r->code == R_100_TRYING) break; // RFC 3262 4 // Discard retransmissions and out-of-sequence reliable // provisional responses. if (must_discard_100rel(r)) return; // fall thru case R_2XX: // Set remote tag remote_tag = r->hdr_to.tag; create_route_set(r); create_remote_target(r); // Set remote URI and display name remote_uri = r->hdr_to.uri; remote_display = r->hdr_to.display; process_1xx_2xx_invite_resp(r); break; default: break; } // RFC 3262 // Send PRACK if required send_prack_if_required(r); t_call_script script_out_call_answered(user_config, t_call_script::TRIGGER_OUT_CALL_ANSWERED, line->get_line_number() + 1); t_call_script script_out_call_failed(user_config, t_call_script::TRIGGER_OUT_CALL_FAILED, line->get_line_number() + 1); switch (r->get_class()) { case R_1XX: // Provisional response received. line->ci_set_last_provisional_reason(r->reason); ui->cb_provisional_resp_invite(line->get_line_number(), r); if (r->code > R_100_TRYING && r->hdr_to.tag.size() > 0) { state = DS_EARLY; } else { state = DS_W4INVITE_RESP2; } // User indicated that the request should be cancelled. // Now that the first provisional response has been received, // a CANCEL can be sent. if (request_cancelled) { send_cancel(true); } break; case R_2XX: // Stop cancel guard timer if it was running line->stop_timer(LTMR_CANCEL_GUARD, get_object_id()); // Success received. ack_2xx_invite(r); // Check for REFER support // If the Allow header is not present then assume REFER // is supported. if (!r->hdr_allow.is_populated() || r->hdr_allow.contains_method(REFER)) { line->ci_set_refer_supported(true); } // Trigger call script script_out_call_answered.exec_notify(r); ui->cb_call_answered(user_config, line->get_line_number(), r); line->call_hist_record.answer_call(r); state = DS_CONFIRMED; if (request_cancelled) { // User indicated that the request should be cancelled, // but no response was received yet. A final response // has been received. Instead of CANCEL a BYE will be // sent now. send_bye(); } else if (end_after_2xx_invite) { // Or user cancelled the request already, but the 2XX // glared with CANCEL. log_file->write_report("CANCEL / 2XX INVITE glare.", "t_dialog::state_w4invite_resp"); send_bye(); } break; case R_3XX: case R_4XX: case R_5XX: case R_6XX: default: // Stop cancel guard timer if it was running line->stop_timer(LTMR_CANCEL_GUARD, get_object_id()); // Final response (failure) received. // Treat unknown response classes as failure. // Trigger call script script_out_call_failed.exec_notify(r); ui->cb_stop_call_notification(line->get_line_number()); ui->cb_call_failed(user_config, line->get_line_number(), r); line->call_hist_record.fail_call(r); remove_client_request(&req_out_invite); state = DS_TERMINATED; break; } // Notify progress to the referror if this is a referred call if (is_referred_call) { get_phone()->notify_refer_progress(r, line->get_line_number()); } } void t_dialog::state_w4invite_resp(t_line_timer timer) { switch (timer) { case LTMR_CANCEL_GUARD: log_file->write_report("Timer LTMR_CANCEL_GUARD expired.", "t_dialog::state_w4invite_resp", LOG_NORMAL, LOG_WARNING); // CANCEL has been responded to, but 487 on INVITE was never // received. Abort the INVITE transaction. if (req_out_invite) { t_tid _tid = req_out_invite->get_tid(); if (_tid > 0) { evq_trans_mgr->push_abort_trans(_tid); } } break; default: // Ignore other timeouts break; } } // INVITE response sent. At least 1 provisional response (not 100 Trying) // received. void t_dialog::state_early(t_response *r, t_tuid tuid, t_tid tid) { if (r->hdr_cseq.method != INVITE) return; t_user *user_config = phone_user->get_user_profile(); switch (r->get_class()) { case R_1XX: // RFC 3262 4 // Discard retransmissiona and out-of-sequence reliable // provisional responses. if (must_discard_100rel(r)) return; // fall thru case R_2XX: create_route_set(r); create_remote_target(r); process_1xx_2xx_invite_resp(r); break; default: break; } // RFC 3262 // Send PRACK if required send_prack_if_required(r); t_call_script script_out_call_answered(user_config, t_call_script::TRIGGER_OUT_CALL_ANSWERED, line->get_line_number() + 1); t_call_script script_out_call_failed(user_config, t_call_script::TRIGGER_OUT_CALL_FAILED, line->get_line_number() + 1); switch (r->get_class()) { case R_1XX: // Provisional response received. line->ci_set_last_provisional_reason(r->reason); ui->cb_provisional_resp_invite(line->get_line_number(), r); if (request_cancelled) { send_cancel(true); } break; case R_2XX: // Stop cancel guard timer if it was running line->stop_timer(LTMR_CANCEL_GUARD, get_object_id()); // Success received. ack_2xx_invite(r); // Check for REFER support // If the Allow header is not present then assume REFER // is supported. if (!r->hdr_allow.is_populated() || r->hdr_allow.contains_method(REFER)) { line->ci_set_refer_supported(true); } // Trigger call script script_out_call_answered.exec_notify(r); ui->cb_call_answered(user_config, line->get_line_number(), r); line->call_hist_record.answer_call(r); state = DS_CONFIRMED; if (request_cancelled) { // User indicated that the request should be cancelled, // but no response was received yet. A final response // has been received. Instead of CANCEL a BYE will be // sent now. send_bye(); } else if (end_after_2xx_invite) { // Or user cancelled the request already, but the 2XX // glared with CANCEL. log_file->write_report("CANCEL / 2XX INVITE glare.", "t_dialog::state_w4invite_resp"); send_bye(); } break; case R_3XX: case R_4XX: case R_5XX: case R_6XX: default: // Stop cancel guard timer if it was running line->stop_timer(LTMR_CANCEL_GUARD, get_object_id()); // Final response (failure) received. // Treat unknown response classes as failure. // Trigger call script script_out_call_failed.exec_notify(r); ui->cb_stop_call_notification(line->get_line_number()); ui->cb_call_failed(user_config, line->get_line_number(), r); line->call_hist_record.fail_call(r); remove_client_request(&req_out_invite); state = DS_TERMINATED; break; } // Notify progress to the referror if this is a referred call if (is_referred_call) { get_phone()->notify_refer_progress(r, line->get_line_number()); } } void t_dialog::state_early(t_line_timer timer) { switch (timer) { case LTMR_CANCEL_GUARD: log_file->write_report("Timer LTMR_CANCEL_GUARD expired.", "t_dialog::state_early", LOG_NORMAL, LOG_WARNING); // CANCEL has been responded to, but 487 on INVITE was never // received. Abort the INVITE transaction. if (req_out_invite) { t_tid _tid = req_out_invite->get_tid(); if (_tid > 0) { evq_trans_mgr->push_abort_trans(_tid); } } break; default: // Ignore other timeouts break; } } // BYE sent. Waiting for response. void t_dialog::state_w4bye_resp(t_response *r, t_tuid tuid, t_tid tid) { if (r->hdr_cseq.method != BYE) return; switch (r->get_class()) { case R_1XX: // Provisional response received. Wait for final response. break; default: // All final responses terminate the dialog. remove_client_request(&req_out); if (!sub_refer) { state = DS_TERMINATED; } else { state = DS_CONFIRMED_SUB; if (sub_refer->get_role() == SR_SUBSCRIBER) { // End subscription sub_refer->unsubscribe(); } } break; } } void t_dialog::state_w4bye_resp(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; switch(r->method) { case BYE: resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; // A BYE glare situation. Keep waiting for the BYE // response. break; default: resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } } // Confirmed dialog. Responses are for mid-dialog requests. void t_dialog::state_confirmed_resp(t_response *r, t_tuid tuid, t_tid tid) { // 1XX responses are not expected. If they are received // then simply ignore them. if (r->is_provisional()) return; switch (r->hdr_cseq.method) { case OPTIONS: ui->cb_options_response(r); remove_client_request(&req_out); break; case REFER: remove_client_request(&req_refer); if (refer_state != REFST_W4RESP) { // NOTIFY has already been received. No need to // process the REFER response anymore. Interesting // issue might be: what if NOTIFY has been received and // now a failure response comes in? break; } if (!r->is_success()) { // REFER failed refer_state = REFST_NULL; refer_succeeded = false; // KLUDGE: only signal REFER failure in case of // non-408/481 responses. These responses // clear the line, so the upper layers should not // take action on the failed refer. if (r->code != R_408_REQUEST_TIMEOUT || r->code == R_481_TRANSACTION_NOT_EXIST) { out_refer_req_failed = true; } ui->cb_refer_failed(line->get_line_number(), r); break; } refer_state = REFST_W4NOTIFY; break; case INFO: remove_client_request(&req_info); if (!dtmf_queue.empty()) { char digit = dtmf_queue.front(); dtmf_queue.pop(); send_dtmf(digit, false, true); } break; default: // The received response should match the pending request. // So this point should never be reached. assert(false); break; } // RFC 3261 12.2.1.2 // If a mid-dialog request is timed out, or the call/transaction // does not exist anymore at the server, then terminate the // dialog. if (r->code == R_408_REQUEST_TIMEOUT || r->code == R_481_TRANSACTION_NOT_EXIST) { send_bye(); } } void t_dialog::state_w4re_invite_resp(t_response *r, t_tuid tuid, t_tid tid) { if (r->hdr_cseq.method != INVITE) return; switch (r->get_class()) { case R_1XX: if (r->code == R_100_TRYING) break; // RFC 3262 4 // Discard retransmissiona and out-of-sequence reliable // provisional responses. if (must_discard_100rel(r)) return; if (state == DS_W4RE_INVITE_RESP2) { // RFC 3262 // Discard retransmissions and out-of-order // reliable provisional responses. if (must_discard_100rel(r)) return; } // RFC 3262 // Send PRACK if required send_prack_if_required(r); // fall thru case R_2XX: // Process SDP answer if answer is present and no // answer has been received yet. if (!session_re_invite->recvd_answer && r->body) { int warn_code; string warn_text; if (r->body->get_type() != BODY_SDP) { // Only SDP bodies are supported ui->cb_unsupported_content_type( line->get_line_number(), r); request_cancelled = true; } else if (session_re_invite-> process_sdp_answer((t_sdp *)r->body, warn_code, warn_text)) { session_re_invite->recvd_answer = true; } else { // SDP answer is not supported. Cancel // the INVITE. request_cancelled = true; ui->cb_sdp_answer_not_supported( line->get_line_number(), warn_text); break; } } // This implementation always sends an offer in // INVITE. So an answer must be in a 2XX response // as PRACK is not supported. if (r->get_class() == R_2XX && !r->body) { request_cancelled = true; ui->cb_sdp_answer_missing(line->get_line_number()); break; } // Refresh target URI and display name if (r->get_class() == R_2XX && r->hdr_contact.is_populated() && r->hdr_contact.contact_list.size() > 0) { remote_target_uri = r-> hdr_contact.contact_list.front().uri; remote_target_display = r-> hdr_contact.contact_list.front().display; } break; default: break; } switch (r->get_class()) { case R_1XX: // Provisional response received. state = DS_W4RE_INVITE_RESP2; // Start re-INVITE guard timer (no RFC requirement) line->start_timer(LTMR_RE_INVITE_GUARD, get_object_id()); // User indicated that the request should be cancelled. // Now that the first provional response has been received, // a CANCEL can be sent. if (request_cancelled) { send_cancel(true); } break; case R_2XX: // Success received. line->stop_timer(LTMR_RE_INVITE_GUARD, get_object_id()); ack_2xx_invite(r); ui->cb_reinvite_success(line->get_line_number(), r); state = DS_CONFIRMED; if (request_cancelled) { // User indicated that the request should be cancelled, // but no response was received yet. A final response // has been received. Instead of CANCEL a BYE will be // sent now. send_bye(); } else if (end_after_2xx_invite) { // Or user cancelled the request already, but the 2XX // glared with CANCEL. log_file->write_report("CANCEL / 2XX INVITE glare.", "t_dialog::state_w4invite_resp"); send_bye(); } else { // Make the re-INIVTE session info the current info activate_new_session(); } break; case R_3XX: case R_4XX: case R_5XX: case R_6XX: default: // Final response (failure) received. // Treat unknown response classes as failure. line->stop_timer(LTMR_RE_INVITE_GUARD, get_object_id()); ui->cb_reinvite_failed(line->get_line_number(), r); remove_client_request(&req_out_invite); // RFC 3261 14.1 // delete re-INVITE session info. Old session info // stays as re-INVITE failed. MEMMAN_DELETE(session_re_invite); delete session_re_invite; session_re_invite = NULL; state = DS_CONFIRMED; switch(reinvite_purpose) { case REINVITE_HOLD: // A call hold may not fail for the user as // this cause problems with soundcard access and // showing line status in the GUI. Even though re-INVITE // failed, the RTP still stopped. So simply indicated // that the hold failed, such that a subsequent retrieve // can simply restart the RTP. hold_failed = true; break; case REINVITE_RETRIEVE: line->failed_retrieve(); if (r->code != R_491_REQUEST_PENDING) { ui->cb_retrieve_failed(line->get_line_number(), r); } break; default: assert(false); } // RFC 3261 14.1 // Start wait timer before retrying a re-INVITE after a // glare. if (r->code == R_491_REQUEST_PENDING) { line->start_timer(LTMR_GLARE_RETRY, get_object_id()); } // RFC 3261 14.1 if (r->code == R_408_REQUEST_TIMEOUT || r->code == R_481_TRANSACTION_NOT_EXIST) { send_bye(); } break; } } void t_dialog::state_w4re_invite_resp(t_line_timer timer) { switch(timer) { case LTMR_RE_INVITE_GUARD: // Abort the INVITE as the user cannot terminate // it in a normal way. if (req_out_invite) { t_tid _tid = req_out_invite->get_tid(); if (_tid > 0) { evq_trans_mgr->push_abort_trans(_tid); } } else { // Consider this as if a 408 Timeout response has // been received. Terminate the dialog. send_bye(); } break; default: break; } } void t_dialog::activate_new_session(void) { if (session->equal_audio(*session_re_invite)) { log_file->write_report("SDP in re-INVITE is a noop.", "t_dialog::activate_new_session"); MEMMAN_DELETE(session_re_invite); delete session_re_invite; session_re_invite = NULL; return; } log_file->write_report("Renew session as specified by SDP in re-INVITE.", "t_dialog::activate_new_session"); // Stop current session MEMMAN_DELETE(session); delete session; // Create new session session = session_re_invite; session_re_invite = NULL; session->start_rtp(); } void t_dialog::process_1xx_2xx_invite_resp(t_response *r) { t_user *user_config = phone_user->get_user_profile(); // Process SDP answer if answer is present and no // answer has been received yet. if (r->body) { int warn_code; string warn_text; if (r->body->get_type() != BODY_SDP) { // Only SDP bodies are supported ui->cb_unsupported_content_type(line->get_line_number(), r); request_cancelled = true; } else if (!session->recvd_answer || (user_config->get_allow_sdp_change() && ((t_sdp *)r->body)->origin.session_version != session->dst_sdp_version)) { // Only process SDP if no SDP was received yet (RFC 3261 // 13.3.1. Or process SDP if overridden by the // allow_sdp_change setting in the user profile. // A changed SDP must have a new version number (RFC 3264) if (session->process_sdp_answer((t_sdp *)r->body, warn_code, warn_text)) { // If this is a changed SDP, then stop the // current RTP stream based on the previous SDP. if (session->recvd_answer) session->stop_rtp(); session->recvd_answer = true; // The following code part handles the ugly interaction // between forking and early media (Vonage uses this). // In case of forking 1xx responses with SDP may com // from different destinations. Only the first 1xx will // create a media stream. Media streams on other legs cannot // be created as that would give sound conflicts. // When a 2xx response with SDP is received, an early media // stream on another leg must be killed. // Due to forking multiple 2xx repsonses from different // destinations may be received. Only the first 2xx response // will create a media session. The other dialogs receiving // a 2xx will be released immediately anyway (see line.cpp). bool start_media = true; t_dialog *d = line->get_dialog_with_active_session(); if (d != NULL) { if (r->get_class() == R_2XX && d->get_state() != DS_CONFIRMED) { log_file->write_header( "t_dialog::process_1xx_2xx_invite_resp"); log_file->write_raw( "Kill early media on another dialog, id="); log_file->write_raw(d->get_object_id()); log_file->write_endl(); log_file->write_footer(); d->kill_rtp(); } else { log_file->write_header( "t_dialog::process_1xx_2xx_invite_resp"); log_file->write_raw( "Cannot start media as another dialog (id="); log_file->write_raw(d->get_object_id()); log_file->write_raw(") already has media.\n"); log_file->write_footer(); start_media = false; } } if (start_media) { if (r->is_provisional()) { log_file->write_report("Starting early media.", "t_dialog::process_1xx_2xx_invite_resp"); } // Stop locally played tones to free the soundcard // for the voice stream ui->cb_stop_call_notification(line->get_line_number()); session->start_rtp(); } } else { // SDP answer is not supported. Cancel // the INVITE. request_cancelled = true; ui->cb_sdp_answer_not_supported( line->get_line_number(), warn_text); } } } else if (r->code == R_180_RINGING && !ringing_received && !session->recvd_answer) { // There is no SDP and far-end indicated that it is ringing // so generate ring back tone locally. ui->cb_play_ringback(user_config); ringing_received = true; } // This implementation always sends an offer in // INVITE. So an answer must be in a 2XX response if // no answer has been received in a provisional response. if (!session->recvd_answer && r->get_class() == R_2XX && !r->body) { request_cancelled = true; ui->cb_sdp_answer_missing(line->get_line_number()); } // RFC 3261 13.3.1.4 // A 2XX response to an INVITE should contain a Supported header // listing all supported extensions. // Set extensions supported by remote party if (r->get_class() == R_2XX && r->hdr_supported.is_populated()) { remote_extensions.insert(r->hdr_supported.features.begin(), r->hdr_supported.features.end()); } } void t_dialog::ack_2xx_invite(t_response *r) { t_ip_port ip_port; t_user *user_config = phone_user->get_user_profile(); if (ack) { // delete previous cached ACK MEMMAN_DELETE(ack); delete ack; } ack = create_request(ACK); ack->get_destination(ip_port, *user_config); // If for some strange reason the destination could // not be computed then wait for a retransmission of // 2XX. if (ip_port.ipaddr != 0 && ip_port.port != 0) { evq_sender->push_network(ack, ip_port); } else { log_file->write_header("t_dialog::ack_2xx_invite", LOG_SIP, LOG_CRITICAL); log_file->write_raw("Cannot determine destination IP address for ACK.\n\n"); log_file->write_raw(ack->encode()); log_file->write_footer(); } remove_client_request(&req_out_invite); } void t_dialog::send_prack_if_required(t_response *r) { t_user *user_config = phone_user->get_user_profile(); // RFC 3262 // Send PRACK if needed if (r->get_class() == R_1XX && r->code != R_100_TRYING) { // RFC 3262 4 // Send PRACK if the 1xx response is sent reliable and 100rel // is enabled. if (r->hdr_to.tag.size() > 0 && r->hdr_require.contains(EXT_100REL) && r->hdr_rseq.is_populated() && remote_target_uri.is_valid() && user_config->get_ext_100rel() != EXT_DISABLED) { t_request *prack = create_request(PRACK); prack->hdr_rack.set_method(r->hdr_cseq.method); prack->hdr_rack.set_cseq_nr(r->hdr_cseq.seqnr); prack->hdr_rack.set_resp_nr(r->hdr_rseq.resp_nr); // Delete previous PRACK request if it is still pending if (req_prack) { log_file->write_report("Previous PRACK still pending.", "t_dialog::send_prack_if_needed"); remove_client_request(&req_prack); } req_prack = new t_client_request(user_config, prack, 0); MEMMAN_NEW(req_prack); line->send_request(prack, req_prack->get_tuid()); MEMMAN_DELETE(prack); delete prack; } } } bool t_dialog::must_discard_100rel(t_response *r) { t_user *user_config = phone_user->get_user_profile(); // RFC 3262 4 // Discard retransmissiona and out-of-sequence reliable // provisional responses. if (r->code > R_100_TRYING && r->hdr_to.tag.size() > 0 && r->hdr_require.contains(EXT_100REL) && r->hdr_rseq.is_populated() && user_config->get_ext_100rel() != EXT_DISABLED) { if (remote_resp_nr == 0) { // This is the first response with a repsonse nr. // Initialize the remote response nr remote_resp_nr = r->hdr_rseq.resp_nr; return false; } if (r->hdr_rseq.resp_nr <= remote_resp_nr) { // This is a retransmission. // PRACK has already been sent. The transaction // layer takes care of retransmitting PRACK // if PRACK got lost. log_file->write_report("Discard 1xx retransmission.", "t_dialog::must_discard_100rel"); return true; } if (r->hdr_rseq.resp_nr != remote_resp_nr + 1) { // A provisional response has been lost. // Discard this response and wait for a retransmission // of the lost response. log_file->write_report("Discard out-of-order 1xx", "t_dialog::must_discard_100rel"); return true; } } remote_resp_nr = r->hdr_rseq.resp_nr; return false; } bool t_dialog::respond_prack(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; // RFC 3262 3 if (resp_1xx_invite && r->hdr_rack.method == resp_1xx_invite->hdr_cseq.method && r->hdr_rack.cseq_nr == resp_1xx_invite->hdr_cseq.seqnr && r->hdr_rack.resp_nr == resp_1xx_invite->hdr_rseq.resp_nr) { // The provisional response has been delivered now. line->stop_timer(LTMR_100REL_TIMEOUT, get_object_id()); line->stop_timer(LTMR_100REL_GUARD, get_object_id()); MEMMAN_DELETE(resp_1xx_invite); delete resp_1xx_invite; resp_1xx_invite = NULL; // Send 200 on the PRACK request resp = r->create_response(R_200_OK); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return true; } else { // PRACK does not match pending 1xx response // Send a 481 on the PRACK request resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return false; } } void t_dialog::send_request(t_request *r, t_tuid tuid) { line->send_request(r, tuid); } //////////// // Public //////////// t_dialog::t_dialog(t_line *_line) : t_abstract_dialog(_line->get_phone_user()) { line = _line; req_out = NULL; req_out_invite = NULL; req_in_invite = NULL; req_cancel = NULL; req_prack = NULL; req_refer = NULL; req_info = NULL; req_stun = NULL; request_cancelled = false; end_after_ack = false; end_after_2xx_invite = false; answer_after_prack = false; ringing_received = false; resp_invite = NULL; resp_1xx_invite = NULL; ack = NULL; state = DS_NULL; // Timers dur_ack_timeout = 0; id_ack_timeout = 0; id_ack_guard = 0; id_re_invite_guard = 0; id_glare_retry = 0; id_cancel_guard = 0; // RFC 3262 // Timers dur_100rel_timeout = 0; id_100rel_timeout = 0; id_100rel_guard = 0; t_user *user_config = phone_user->get_user_profile(); // Create session session = new t_session(this, USER_HOST(user_config, AUTO_IP4_ADDRESS), line->get_rtp_port()); MEMMAN_NEW(session); session_re_invite = NULL; // Subscription sub_refer = NULL; is_referred_call = false; refer_state = REFST_NULL; refer_accepted = false; refer_succeeded = false; out_refer_req_failed = false; } t_dialog::~t_dialog() { if (req_out) remove_client_request(&req_out); if (req_out_invite) remove_client_request(&req_out_invite); if (req_in_invite) remove_client_request(&req_in_invite); if (req_cancel) remove_client_request(&req_cancel); if (req_prack) remove_client_request(&req_prack); if (req_refer) remove_client_request(&req_refer); if (req_info) remove_client_request(&req_info); if (req_stun) remove_client_request(&req_stun); if (resp_invite) { MEMMAN_DELETE(resp_invite); delete resp_invite; } if (resp_1xx_invite) { MEMMAN_DELETE(resp_1xx_invite); delete resp_1xx_invite; } if (ack) { MEMMAN_DELETE(ack); delete ack; } if (session) { MEMMAN_DELETE(session); delete session; } if (session_re_invite) { MEMMAN_DELETE(session_re_invite); delete session_re_invite; } if (sub_refer) { MEMMAN_DELETE(sub_refer); delete sub_refer; } for (list::iterator i = inc_req_queue.begin(); i != inc_req_queue.end(); i++) { MEMMAN_DELETE(*i); delete *i; } } // Copy will only be used on the open dialog. t_dialog *t_dialog::copy(void) { t_dialog *d = new t_dialog(*this); MEMMAN_NEW(d); d->generate_new_id(); // Increment reference count on client request if (req_out) d->req_out->inc_ref_count(); if (req_out_invite) d->req_out_invite->inc_ref_count(); if (req_in_invite) d->req_in_invite->inc_ref_count(); if (req_prack) d->req_prack->inc_ref_count(); if (req_refer) d->req_refer->inc_ref_count(); if (req_stun) d->req_stun->inc_ref_count(); // The open dialog will handle the CANCEL, so delete it // from the copy. if (req_cancel) d->req_cancel = NULL; if (resp_invite) d->resp_invite = (t_response *)resp_invite->copy(); if (resp_1xx_invite) d->resp_1xx_invite = (t_response *)resp_1xx_invite->copy(); if (ack) d->ack = (t_request *)ack->copy(); dur_ack_timeout = 0; id_ack_timeout = 0; id_ack_guard = 0; dur_100rel_timeout = 0; id_100rel_timeout = 0; id_100rel_guard = 0; if (session) { d->session = new t_session(*session); MEMMAN_NEW(d->session); d->session->set_owner(d); // If an audio session was already created for early media // then the audio session will be moved to the copy of the // dialog. Only 1 dialog can have an audio session. // See process_1xx_2xx_invite_resp for more information on // early media problems. // Clear a possible audio session in the open dialog. t_audio_session *as = session->get_audio_session(); if (as) { as->set_session(d->session); session->set_audio_session(NULL); log_file->write_report( "An audio session was created on an open dialog.", "t_dialog::copy", LOG_NORMAL, LOG_DEBUG); } } log_file->write_header("t_dialog::copy", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Created dialog through copy, id="); log_file->write_raw(d->get_object_id()); log_file->write_endl(); log_file->write_footer(); return d; } void t_dialog::send_invite(const t_url &to_uri, const string &to_display, const string &subject, const t_hdr_referred_by &hdr_referred_by, const t_hdr_replaces &hdr_replaces, const t_hdr_require &hdr_require, const t_hdr_request_disposition &hdr_request_disposition, bool anonymous) { t_user *user_config = phone_user->get_user_profile(); if (state != DS_NULL) { throw X_DIALOG_ALREADY_ESTABLISHED; } // If STUN is enabled, then first send a STUN binding request to // discover the IP adderss and port for media. if (phone->use_stun(user_config)) { if (!stun_bind_media()) { ui->cb_stun_failed_call_ended(line->get_line_number()); state = DS_TERMINATED; return; } } t_request invite(INVITE); // RFC 3261 12.2.1.1 // Request URI and Route header invite.set_route(to_uri, phone_user->get_service_route()); // Set Call-ID header call_id = NEW_CALL_ID(user_config); invite.hdr_call_id.set_call_id(call_id); call_id_owner = true; // Set To header invite.hdr_to.set_uri(to_uri); invite.hdr_to.set_display(to_display); // Set From header local_tag = NEW_TAG; local_uri.set_url(line->create_user_uri()); local_display = user_config->get_display(anonymous); invite.hdr_from.set_uri(local_uri); invite.hdr_from.set_display(local_display); invite.hdr_from.set_tag(local_tag); // Privacy header if (line->get_hide_user()) { invite.hdr_privacy.add_privacy(PRIVACY_ID); } // Set P-Preferred-Identity header if (anonymous && user_config->get_send_p_preferred_id()) { t_identity identity; identity.set_uri(user_config->create_user_uri(false)); identity.set_display(user_config->get_display(false)); invite.hdr_p_preferred_identity.add_identity(identity); } // Set CSeq header local_seqnr = rand() % 1000 + 1; invite.hdr_cseq.set_method(INVITE); invite.hdr_cseq.set_seqnr(local_seqnr); // Set Max-Forwards header invite.hdr_max_forwards.set_max_forwards(MAX_FORWARDS); // User-Agent SET_HDR_USER_AGENT(invite.hdr_user_agent); // RFC 3261 13.2.1 // Allow and Supported headers SET_HDR_ALLOW(invite.hdr_allow, user_config); SET_HDR_SUPPORTED(invite.hdr_supported, user_config); // Extensions specific for INVITE if (user_config->get_ext_100rel() != EXT_DISABLED) { invite.hdr_supported.add_feature(EXT_100REL); } // Require header switch (user_config->get_ext_100rel()) { case EXT_PREFERRED: case EXT_REQUIRED: invite.hdr_require.add_feature(EXT_100REL); break; default: break; } // Subject header if (subject != "") { invite.hdr_subject.set_subject(subject); } // Organization if (!anonymous) { SET_HDR_ORGANIZATION(invite.hdr_organization, user_config); } // RFC 3892 Referred-By header if a call is initated because // of an incoming REFER. invite.hdr_referred_by = hdr_referred_by; // RFC 3891 Replaces header invite.hdr_replaces = hdr_replaces; // Add required extension passed by the upper layer if (hdr_require.is_populated()) { invite.hdr_require.add_features(hdr_require.features); } // RFC 3841 Request-Disposition header invite.hdr_request_disposition = hdr_request_disposition; // Calculate destinations // See create_request() for more comments invite.calc_destinations(*user_config); // The Contatc, Via header and SDP can only be created after the destinations // are calculated, because the destination deterimines which // local IP address should be used. // Create SDP offer session->create_sdp_offer(&invite, SDP_O_USER); // Set Via header unsigned long local_ip = invite.get_local_ip(); t_via via(USER_HOST(user_config, h_ip2str(local_ip)), PUBLIC_SIP_PORT(user_config)); invite.hdr_via.add_via(via); // Set Contact header t_contact_param contact; contact.uri.set_url(line->create_user_contact(h_ip2str(local_ip))); invite.hdr_contact.add_contact(contact); // Send INVITE req_out_invite = new t_client_request(user_config, &invite, 0); MEMMAN_NEW(req_out_invite); // Trigger call script t_call_script script(user_config, t_call_script::TRIGGER_OUT_CALL, line->get_line_number() + 1); script.exec_notify(&invite); line->send_request(&invite, req_out_invite->get_tuid()); line->call_hist_record.start_call(&invite, t_call_record::DIR_OUT, user_config->get_profile_name()); state = DS_W4INVITE_RESP; } bool t_dialog::resend_invite_auth(t_response *resp) { t_user *user_config = phone_user->get_user_profile(); if (!req_out_invite) return false; assert(state == DS_W4INVITE_RESP || state == DS_W4INVITE_RESP2); t_request *req = req_out_invite->get_request(); // Add authorization header, increment CSeq and create new branch id if (get_phone()->authorize(user_config, req, resp)) { resend_request(req_out_invite); // Reset state in case a 100 Trying was received state = DS_W4INVITE_RESP; return true; } return false; } bool t_dialog::resend_invite_unsupported(t_response *resp) { t_user *user_config = phone_user->get_user_profile(); if (!req_out_invite) return false; if (resp->code != R_420_BAD_EXTENSION) return false; if (!resp->hdr_unsupported.is_populated()) return false; if (resp->hdr_unsupported.features.empty()) return false; t_request *req = req_out_invite->get_request(); // If no extensions were required then return. if (!req->hdr_require.is_populated()) return false; if (req->hdr_require.features.empty()) return false; bool removed_ext = false; for (list::iterator i = resp->hdr_unsupported.features.begin(); i != resp->hdr_unsupported.features.end(); i++) { if (req->hdr_require.contains(*i)) { if (*i == EXT_100REL) { if (user_config->get_ext_100rel() == EXT_PREFERRED) { req->hdr_require.del_feature(*i); } else { // The 100rel is required. return false; } } else { // There is no specific requirement for // this extension so do not remove it. return false; } removed_ext = true; } } // Return if none of the unsupported extensions was required. if (!removed_ext) return false; if (req->hdr_require.features.empty()) { // There are no required features anymore req->hdr_require.unpopulate(); } resend_request(req_out_invite); // Reset state in case a 100 Trying was received state = DS_W4INVITE_RESP; return true; } bool t_dialog::redirect_invite(t_response *resp) { t_contact_param contact; t_user *user_config = phone_user->get_user_profile(); if (!req_out_invite) return false; // If the response is a 3XX response then add redirection contacts if (resp->get_class() == R_3XX && resp->hdr_contact.is_populated()) { req_out_invite->redirector.add_contacts( resp->hdr_contact.contact_list); } // Get next destination if (!req_out_invite->redirector.get_next_contact(contact)) { // There is no next destination return false; } assert(state == DS_W4INVITE_RESP || state == DS_W4INVITE_RESP2); t_request *req = req_out_invite->get_request(); // Ask user for permission to redirect if indicated by user config if (user_config->get_ask_user_to_redirect()) { if(!ui->cb_ask_user_to_redirect_invite(user_config, contact.uri, contact.display)) { // User did not permit to redirect return false; } } // Change the request URI to the new URI. // As the URI changes the destination set must be recalculated req->uri = contact.uri; req->calc_destinations(*user_config); ui->cb_redirecting_request(user_config, line->get_line_number(), contact); resend_request(req_out_invite); // Reset state in case a 100 Trying was received state = DS_W4INVITE_RESP; return true; } bool t_dialog::failover_invite(void) { if (!req_out_invite) return false; log_file->write_report("Failover to next destination.", "t_dialog::failover_invite"); t_request *req = req_out_invite->get_request(); // Get next destination if (!req->next_destination()) { log_file->write_report("No next destination for failover.", "t_dialog::failover_invite"); return false; } assert(state == DS_W4INVITE_RESP || state == DS_W4INVITE_RESP2); resend_request(req_out_invite); // Reset state in case a 100 Trying was received state = DS_W4INVITE_RESP; return true; } void t_dialog::send_bye(void) { t_user *user_config = phone_user->get_user_profile(); switch (state) { case DS_W4INVITE_RESP2: case DS_EARLY: case DS_CONFIRMED: break; case DS_W4RE_INVITE_RESP: case DS_W4RE_INVITE_RESP2: // send BYE after completion of re-INVITE request_cancelled = true; return; case DS_W4ACK: case DS_W4ACK_RE_INVITE: // send BYE after completion of re-INVITE request_cancelled = true; return; case DS_TERMINATED: // Dialog has already been terminated. Do not send BYE. return; default: log_file->write_header("t_dialog::failover_invite", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Cannot send BYE on dialog in state "); log_file->write_raw(state); log_file->write_endl(); log_file->write_footer(); return; } // If a previous request is still pending then remove it. if (req_out) { MEMMAN_DELETE(req_out); delete (req_out); } t_request *bye = create_request(BYE); req_out = new t_client_request(user_config, bye, 0); MEMMAN_NEW(req_out); // Trigger call script t_call_script script(user_config, t_call_script::TRIGGER_LOCAL_RELEASE, line->get_line_number() + 1); script.exec_notify(bye); line->send_request(bye, req_out->get_tuid()); line->call_hist_record.end_call(false); MEMMAN_DELETE(bye); delete bye; state = DS_W4BYE_RESP; ui->cb_call_ended(line->get_line_number()); } void t_dialog::send_options(void) { t_user *user_config = phone_user->get_user_profile(); // Request can only be sent in a confirmed dialog. if (state != DS_CONFIRMED) return; // If a previous request is still pending then remove it. if (req_out) { MEMMAN_DELETE(req_out); delete (req_out); } t_request *r = create_request(OPTIONS); // Accept r->hdr_accept.add_media(t_media("application","sdp")); req_out = new t_client_request(user_config, r, 0); MEMMAN_NEW(req_out); line->send_request(r, req_out->get_tuid()); MEMMAN_DELETE(r); delete r; } void t_dialog::send_cancel(bool early_dialog_exists) { t_request *cancel; t_user *user_config = phone_user->get_user_profile(); switch (state) { case DS_W4INVITE_RESP: case DS_W4RE_INVITE_RESP: if (!early_dialog_exists) { // wait for first response then send CANCEL or BYE request_cancelled = true; break; } // Fall through case DS_W4INVITE_RESP2: case DS_W4RE_INVITE_RESP2: case DS_EARLY: if (req_cancel) { // CANCEL has been sent already break; } cancel = create_request(CANCEL); req_cancel = new t_client_request(user_config, cancel, 0); MEMMAN_NEW(req_cancel); line->send_request(cancel, req_cancel->get_tuid()); MEMMAN_DELETE(cancel); delete cancel; // Make sure dialog is terminated if CANCEL glares with // 2XX on INVITE. set_end_after_2xx_invite(true); break; default: break; } ui->cb_call_ended(line->get_line_number()); } void t_dialog::set_end_after_2xx_invite(bool on) { end_after_2xx_invite = on; } void t_dialog::send_re_invite(void) { assert(session_re_invite); t_user *user_config = phone_user->get_user_profile(); // Request can only be sent in a confirmed dialog. if (state != DS_CONFIRMED) return; // Do nothing if a re-INVITE is already in progress if (req_out_invite) return; t_request *r = create_request(INVITE); // Set Contact header // INVITE must contain a contact header t_contact_param contact; contact.uri.set_url(line->create_user_contact(h_ip2str(r->get_local_ip()))); r->hdr_contact.add_contact(contact); // RFC 3261 13.2.1 // Allow and Supported headers SET_HDR_ALLOW(r->hdr_allow, user_config); SET_HDR_SUPPORTED(r->hdr_supported, user_config); // Extensions specific for INVITE if (user_config->get_ext_100rel() != EXT_DISABLED) { // If some weird far end implementation wants to send // a reliable provisional then support it. // As a provisional response not needed for a re-INVITE, // do not require the 100rel. r->hdr_supported.add_feature(EXT_100REL); } // Create SDP offer session_re_invite->create_sdp_offer(r, SDP_O_USER); // Send INVITE req_out_invite = new t_client_request(user_config, r, 0); MEMMAN_NEW(req_out_invite); line->send_request(r, req_out_invite->get_tuid()); MEMMAN_DELETE(r); delete r; state = DS_W4RE_INVITE_RESP; } bool t_dialog::resend_request_auth(t_response *resp) { t_client_request **current_cr; switch (resp->hdr_cseq.method) { case INVITE: // re-INVITE if (!req_out_invite) return false; assert(state == DS_W4RE_INVITE_RESP || state == DS_W4RE_INVITE_RESP2); current_cr = &req_out_invite; break; case PRACK: if (!req_prack) return false; current_cr = &req_prack; break; case REFER: if (!req_refer) return false; current_cr = &req_refer; break; case INFO: if (!req_info) return false; current_cr = &req_info; break; case SUBSCRIBE: case NOTIFY: if (!sub_refer) return false; if (!sub_refer->req_out) return false; current_cr = &(sub_refer->req_out); break; default: // other requests if (!req_out) return false; current_cr = &req_out; } if (t_abstract_dialog::resend_request_auth(*current_cr, resp)) { if (resp->hdr_cseq.method == INVITE) { // Reset state in case a 100 Trying was received state = DS_W4RE_INVITE_RESP; } return true; } return false; } bool t_dialog::redirect_request(t_response *resp) { t_client_request **current_cr; t_user *user_config = phone_user->get_user_profile(); if (resp->hdr_cseq.method == INVITE) { // re-INVITE if (!req_out_invite) return false; assert(state == DS_W4RE_INVITE_RESP || state == DS_W4RE_INVITE_RESP2); current_cr = &req_out_invite; } else { // non-INVITE if (!req_out) return false; current_cr = &req_out; } t_contact_param contact; if (!t_abstract_dialog::redirect_request(*current_cr, resp, contact)) return false; // Re-INVITE if (resp->hdr_cseq.method == INVITE) { // Reset state in case a 100 Trying was received state = DS_W4RE_INVITE_RESP; } ui->cb_redirecting_request(user_config, line->get_line_number(), contact); return true; } bool t_dialog::failover_request(t_response *resp) { t_client_request **current_cr; if (resp->hdr_cseq.method == INVITE) { // re-INVITE if (!req_out_invite) return false; assert(state == DS_W4RE_INVITE_RESP || state == DS_W4RE_INVITE_RESP2); current_cr = &req_out_invite; } else { // non-INVITE if (!req_out) return false; current_cr = &req_out; } if (!t_abstract_dialog::failover_request(*current_cr)) return false; // Re-INVITE if (resp->hdr_cseq.method == INVITE) { // Reset state in case a 100 Trying was received state = DS_W4RE_INVITE_RESP; } return true; } void t_dialog::hold(bool rtponly) { assert(!session_re_invite); // Stop glare retry timer if (id_glare_retry) { line->stop_timer(LTMR_GLARE_RETRY, get_object_id()); } reinvite_purpose = REINVITE_HOLD; if (rtponly) { session->stop_rtp(); session->hold(); // Stopping the RTP only is like a full call hold where // the re-INVITE failed. By setting the hold_failed flag, // a subsequent retrieve will only start RTP. hold_failed = true; return; } hold_failed = false; session_re_invite = session->create_call_hold(); send_re_invite(); // Stop the audio streams now. If we do not stop the stream now // the stream will be stopped when a 200 OK is received on the // re-INVITE. However, when the line is put on-hold because // the user switches to another line that already has a held call // a race condition might occur: // // 1. A re-INVITE on this line is sent to put it on-hold // 2. A re-INVITE on the other line is sent to retrieve the call // 3. If the 200 OK on the second re-INVITE comes in before the // the 200 OK on the first re-INVITE, then the audio streams // for the second line will be started already while the first // line still has the audio device open. On some systems this // causes a dead lock as the audio device may only be opened // once. // // Also if the re-INVITE to put the line on-hold fails, the // audio might not be stopped at all. It must be stopped however // as the user has switched to the other line. So stopping the // audio now will make sure the audio device is idle when the // second call is retrieved. session->stop_rtp(); // Prevent RTP stream from getting started even if the signaling // for hold fails. After all the user has put the phone locally // on-hold, so RTP should never be started. session->hold(); } void t_dialog::retrieve(void) { assert(!session_re_invite); t_user *user_config = phone_user->get_user_profile(); // Stop glare retry timer if (id_glare_retry) { line->stop_timer(LTMR_GLARE_RETRY, get_object_id()); } // Allow RTP stream to be started again. session->unhold(); // If the previous call-hold failed, then only RTP needs to // be restarted. The session description did never change // because of the failure. if (hold_failed) { session->start_rtp(); return; } // If STUN is enabled, then first send a STUN binding request to // discover the IP adderss and port for media. if (phone->use_stun(user_config)) { if (!stun_bind_media()) { // No re-INVITE can be sent. Simply return. // User will decide if the call should be // torn down. return; } } reinvite_purpose = REINVITE_RETRIEVE; session_re_invite = session->create_call_retrieve(); send_re_invite(); } void t_dialog::kill_rtp(void){ session->kill_rtp(); if (session_re_invite) session_re_invite->kill_rtp(); } void t_dialog::send_refer(const t_url &uri, const string &display) { t_user *user_config = phone_user->get_user_profile(); if (state != DS_CONFIRMED) return; if (refer_state != REFST_NULL) return; // If a previous refer is still in progress, then do nothing if (req_refer) { log_file->write_report("A REFER request is already in progress.", "t_dialog::send_refer"); return; } // If a refer subscription already exists, then do nothing if (sub_refer) { log_file->write_report("Refer subscription exists already.", "t_dialog::send_refer"); return; } t_request *refer = create_request(REFER); // Refer-To header refer->hdr_refer_to.set_uri(uri); refer->hdr_refer_to.set_display(display); // Referred-By header refer->hdr_referred_by.set_uri(line->create_user_uri()); refer->hdr_referred_by.set_display(user_config->get_display(line->get_hide_user())); req_refer = new t_client_request(user_config, refer, 0); MEMMAN_NEW(req_refer); line->send_request(refer, req_refer->get_tuid()); MEMMAN_DELETE(refer); delete refer; refer_succeeded = false; out_refer_req_failed = false; refer_state = REFST_W4RESP; } void t_dialog::send_dtmf(char digit, bool inband, bool info) { t_user *user_config = phone_user->get_user_profile(); if (info) { if (req_info) { // An INFO request is still in progress, put the // DTMF digit in the queue dtmf_queue.push(digit); } else { t_request *info_request = create_request(INFO); // Content-Type header info_request->hdr_content_type.set_media(t_media("application", "dtmf-relay")); // application/dtmf-relay body info_request->body = new t_sip_body_dtmf_relay(digit, user_config->get_dtmf_duration()); MEMMAN_NEW(info_request->body); req_info = new t_client_request(user_config, info_request, 0); MEMMAN_NEW(req_info); line->send_request(info_request, req_info->get_tuid()); MEMMAN_DELETE(info_request); delete info_request; ui->cb_send_dtmf(line->get_line_number(), char2dtmf_ev(digit)); } } else { if (session) session->send_dtmf(digit, inband); } } bool t_dialog::stun_bind_media(void) { t_user *user_config = phone_user->get_user_profile(); try { unsigned long mapped_ip; unsigned short mapped_port; int stun_err_code; string stun_err_reason; bool ret = get_stun_binding(user_config, line->get_rtp_port(), mapped_ip, mapped_port, stun_err_code, stun_err_reason); if (!ret) { // STUN request failed ui->cb_stun_failed(user_config, stun_err_code, stun_err_reason); log_file->write_header("t_dialog::stun_bind_media", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw("STUN bind request for media failed.\n"); log_file->write_raw(stun_err_code); log_file->write_raw(" "); log_file->write_raw(stun_err_reason); log_file->write_endl(); log_file->write_footer(); return false; } // STUN binding request succeeded. session->receive_host = h_ip2str(mapped_ip); session->receive_port = mapped_port; } catch (int err) { // STUN request failed ui->cb_stun_failed(user_config); log_file->write_header("t_dialog::stun_bind_media", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw("STUN bind request for media failed.\n"); log_file->write_raw(get_error_str(err)); log_file->write_endl(); log_file->write_footer(); return false; } return true; } void t_dialog::recvd_response(t_response *r, t_tuid tuid, t_tid tid) { t_user *user_config = phone_user->get_user_profile(); t_abstract_dialog::recvd_response(r, tuid, tid); if (r->hdr_cseq.method == INVITE && tuid == 0 && tid == 0 && !req_out_invite) { t_ip_port ip_port; // Only a retransmission of a 2XX INVITE is allowed. if (r->get_class() != R_2XX) return; if (!ack) return; if (r->hdr_cseq.seqnr != ack->hdr_cseq.seqnr) { // The 2XX response does not match the ACK return; } ack->get_destination(ip_port, *user_config); if (ip_port.ipaddr != 0 && ip_port.port != 0) { evq_sender->push_network(ack, ip_port); } return; } if (r->hdr_cseq.method == CANCEL) { if (!req_cancel) return; if (r->is_final()) { remove_client_request(&req_cancel); if (r->is_success()) { line->start_timer(LTMR_CANCEL_GUARD, get_object_id()); } else { // CANCEL request failed. ui->cb_cancel_failed(line->get_line_number(), r); // Abort the INVITE as the user cannot terminate // it in a normal way. if (req_out_invite) { t_tid _tid = req_out_invite->get_tid(); if (_tid > 0) { evq_trans_mgr->push_abort_trans(_tid); } } } } return; } // No processing done for PRACK responses. if (r->hdr_cseq.method == PRACK) { if (!req_prack) return; t_request *prack = req_prack->get_request(); if (r->hdr_cseq.seqnr != prack->hdr_cseq.seqnr) { // The response does not match the latest sent PRACK. // It might match a previous sent PRACK. However, when // a previous PRACK fails, then the latest PRACK will also // fail, so the failure will be handled in the end without // the overhead to keep a list of all pending PRACKs which // should be a rare case. return; } if (r->is_final()) { // PRACK is finished, so remove request remove_client_request(&req_prack); // Tear down the call if PRACK failed and call is // not yet established. if (!r->is_success() && state == DS_EARLY) { log_file->write_header("t_dialog::recvd_response", LOG_NORMAL, LOG_WARNING); log_file->write_raw("PRACK failed: "); log_file->write_raw(r->code); log_file->write_raw(" "); log_file->write_raw(r->reason); log_file->write_endl(); log_file->write_raw("Call will be cancelled.\n"); log_file->write_footer(); ui->cb_prack_failed(line->get_line_number(), r); send_cancel(true); // Ignore the failure in other states. // The call has been setup, so all seems fine. } } return; } // Determine if this is an INVITE or non-INVITE response t_client_request *req; bool send_to_sub_refer = false; switch(r->hdr_cseq.method) { case INVITE: req = req_out_invite; break; case SUBSCRIBE: case NOTIFY: if (!sub_refer) return; req = sub_refer->req_out; send_to_sub_refer = true; break; case REFER: req = req_refer; break; case INFO: req = req_info; break; default: req = req_out; } // Discard response if no request is pending if (!req) { return; } // Check cseq if (r->hdr_cseq.method != req->get_request()->method) { return; } if (r->hdr_cseq.seqnr != req->get_request()->hdr_cseq.seqnr) return; // Set the transaction identifier. This identifier is needed if the // transaction must be aborted at a later time. req->set_tid(tid); if (send_to_sub_refer) { sub_refer->recv_response(r, tuid, tid); if (sub_refer->get_state() == SS_TERMINATED) { MEMMAN_DELETE(sub_refer); delete sub_refer; sub_refer = NULL; if (state == DS_CONFIRMED_SUB) { state = DS_TERMINATED; } } return; } switch (state) { case DS_W4INVITE_RESP: case DS_W4INVITE_RESP2: state_w4invite_resp(r, tuid, tid); break; case DS_EARLY: state_early(r, tuid, tid); break; case DS_W4BYE_RESP: state_w4bye_resp(r, tuid, tid); break; case DS_CONFIRMED: state_confirmed_resp(r, tuid, tid); break; case DS_W4RE_INVITE_RESP: case DS_W4RE_INVITE_RESP2: state_w4re_invite_resp(r, tuid, tid); break; default: // No response expected in other states. Discard. break; } } void t_dialog::recvd_request(t_request *r, t_tuid tuid, t_tid tid) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); // CANCEL will be handled by recvd_cancel() t_abstract_dialog::recvd_request(r, tuid, tid); switch (r->method) { case ACK: // When ACK is received then the current incoming request // must be INVITE. if (!req_in_invite) return; if (req_in_invite->get_request()->hdr_cseq.seqnr != r->hdr_cseq.seqnr) { log_file->write_header("t_dialog::recvd_request", LOG_NORMAL, LOG_WARNING); log_file->write_raw("ACK does not match a pending INVITE.\n"); log_file->write_raw("Discard ACK.\n"); log_file->write_footer(); return; } break; case INVITE: if (remote_seqnr_set && r->hdr_cseq.seqnr <= remote_seqnr) { // Request received out of sequence. Discard. log_file->write_header("t_dialog::recvd_request", LOG_NORMAL, LOG_WARNING); log_file->write_raw("INVITE is received out of order.\n"); log_file->write_raw("Remote seqnr = "); log_file->write_raw(remote_seqnr); log_file->write_endl(); log_file->write_raw("Received seqnr = "); log_file->write_raw(r->hdr_cseq.seqnr); log_file->write_endl(); log_file->write_raw("Discard INVITE.\n"); log_file->write_footer(); return; } remote_seqnr = r->hdr_cseq.seqnr; remote_seqnr_set = true; if (req_in_invite) { // RFC 3261 14.2 // Another INVITE is received while the previous // one is not finished. resp = r->create_response(R_500_INTERNAL_SERVER_ERROR, "Previous INVITE still in progress"); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } else if (req_out_invite) { // RFC 3261 14.2 // re-INVITE glare resp = r->create_response(R_491_REQUEST_PENDING); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } else { req_in_invite = new t_client_request(user_config, r, tid); MEMMAN_NEW(req_in_invite); } break; case REFER: // Reset refer_accepted indication. refer_accepted = false; // fall thru default: // Check cseq // RFC 3261 12.2.2 if (remote_seqnr_set && r->hdr_cseq.seqnr <= remote_seqnr) { // Request received out of order. log_file->write_header("t_dialog::recvd_request", LOG_NORMAL, LOG_WARNING); log_file->write_raw("CSeq seqnr is out of sequence.\n"); log_file->write_raw("Reveived seqnr: "); log_file->write_raw(r->hdr_cseq.seqnr); log_file->write_endl(); log_file->write_raw("Remote seqnr: "); log_file->write_raw(remote_seqnr); log_file->write_endl(); log_file->write_footer(); resp = r->create_response(R_500_INTERNAL_SERVER_ERROR, "Request received out of order"); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; return; } remote_seqnr = r->hdr_cseq.seqnr; remote_seqnr_set = true; } t_dialog_state old_state = state; switch (state) { case DS_NULL: state_null(r, tuid, tid); break; case DS_W4ACK: state_w4ack(r, tuid, tid); break; case DS_W4ACK_RE_INVITE: state_w4ack_re_invite(r, tuid, tid); break; case DS_W4ANSWER: state_w4answer(r, tuid, tid); break; case DS_W4RE_INVITE_RESP: case DS_W4RE_INVITE_RESP2: state_w4re_invite_resp(r, tuid, tid); break; case DS_W4BYE_RESP: state_w4bye_resp(r, tuid, tid); break; case DS_CONFIRMED: state_confirmed(r, tuid, tid); break; case DS_CONFIRMED_SUB: state_confirmed_sub(r, tuid, tid); break; default: // No request expected in other states. Discard. resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); line->send_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; break; } // If the state has changed, then waiting requests needs to be // processed. if (state != old_state && !inc_req_queue.empty()) { t_client_request *queued_cr = inc_req_queue.front(); inc_req_queue.pop_front(); log_file->write_header("t_dialog::recvd_request", LOG_NORMAL, LOG_INFO); log_file->write_raw("Process queued "); log_file->write_raw(method2str(r->method, r->unknown_method)); log_file->write_endl(); log_file->write_footer(); recvd_request(queued_cr->get_request(), 0, queued_cr->get_tid()); MEMMAN_DELETE(queued_cr); delete queued_cr; } } // RFC 3261 9.2 void t_dialog::recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid) { t_response *resp; assert(r->method == CANCEL); // Send 200 as response to CANCEL resp = r->create_response(R_200_OK); // RFC 3261 9.2 // The To-tag in the response to the CANCEL should be the same // as the To-tag in the original request. resp->hdr_to.set_tag(local_tag); line->send_response(resp, 0, cancel_tid); MEMMAN_DELETE(resp); delete resp; switch (state) { case DS_W4ANSWER: state_w4answer(r, 0, cancel_tid); break; default: // Ignore CANCEL in other states. break; } } void t_dialog::recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid) { // Not used anymore. // STUN requests are performed in a synchronous way. } // RFC 3261 13.3.1.4 void t_dialog::answer(void) { t_user *user_config = phone_user->get_user_profile(); if (!req_in_invite) return; t_request *invite_req = req_in_invite->get_request(); // RFC 3262 3 // Delay the final response if we are still waiting for a PRACK // on a 1xx response containing SDP if (resp_1xx_invite && resp_1xx_invite->body) { answer_after_prack = true; return; } if (state != DS_W4ANSWER) { throw X_WRONG_STATE; } resp_invite = invite_req->create_response(R_200_OK); resp_invite->hdr_to.set_tag(local_tag); // Set Organization header SET_HDR_ORGANIZATION(resp_invite->hdr_organization, user_config); // RFC 3261 12.1.1 // Copy the Record-Route header from request to response if (invite_req->hdr_record_route.is_populated()) { resp_invite->hdr_record_route = invite_req->hdr_record_route; } // Set Contact header t_contact_param contact; contact.uri.set_url(line->create_user_contact(h_ip2str(resp_invite->get_local_ip()))); resp_invite->hdr_contact.add_contact(contact); // Set Allow and Supported headers SET_HDR_ALLOW(resp_invite->hdr_allow, user_config); SET_HDR_SUPPORTED(resp_invite->hdr_supported, user_config); // RFC 3261 13.3.1.4 // Create SDP offer if no offer was received in INVITE and no offer // was sent in a reliable 1xx response (RFC 3262 5) // Otherwise if no offer was sent in a reliable 1xx, create an SDP answer. if (!session->sent_offer) { if (!session->recvd_offer && !session->sent_offer) { session->create_sdp_offer(resp_invite, SDP_O_USER); } else { session->create_sdp_answer(resp_invite, SDP_O_USER); session->start_rtp(); } } // Trigger call script t_call_script script(user_config, t_call_script::TRIGGER_IN_CALL_ANSWERED, line->get_line_number() + 1); script.exec_notify(resp_invite); line->call_hist_record.answer_call(resp_invite); line->send_response(resp_invite, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->start_timer(LTMR_ACK_GUARD, get_object_id()); line->start_timer(LTMR_ACK_TIMEOUT, get_object_id()); // Stop 100rel timers if they are running. line->stop_timer(LTMR_100REL_GUARD, get_object_id()); line->stop_timer(LTMR_100REL_TIMEOUT, get_object_id()); state = DS_W4ACK; } void t_dialog::reject(int code, string reason) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); if (state != DS_W4ANSWER) { throw X_WRONG_STATE; } assert(req_in_invite); assert(code >= 400); resp = req_in_invite->get_request()->create_response(code, reason); resp->hdr_to.set_tag(local_tag); // Trigger call script t_call_script script(user_config, t_call_script::TRIGGER_IN_CALL_FAILED, line->get_line_number() + 1); script.exec_notify(resp); line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->call_hist_record.fail_call(resp); MEMMAN_DELETE(resp); delete resp; // Stop 100rel timers if they are running. line->stop_timer(LTMR_100REL_GUARD, get_object_id()); line->stop_timer(LTMR_100REL_TIMEOUT, get_object_id()); state = DS_TERMINATED; } void t_dialog::redirect(const list &destinations, int code, string reason) { t_response *resp; t_user *user_config = phone_user->get_user_profile(); if (state != DS_W4ANSWER) { throw X_WRONG_STATE; } assert(req_in_invite); assert(code >= 300 && code <= 399); resp = req_in_invite->get_request()->create_response(code, reason); resp->hdr_to.set_tag(local_tag); t_contact_param *contact; float q = 0.9; for (list::const_iterator i = destinations.begin(); i != destinations.end(); i++) { contact = new t_contact_param(); MEMMAN_NEW(contact); contact->display = i->display; contact->uri = i->url; contact->set_qvalue(q); resp->hdr_contact.add_contact(*contact); MEMMAN_DELETE(contact); delete contact; q = q - 0.1; if (q < 0.1) q = 0.1; } // Trigger call script t_call_script script(user_config, t_call_script::TRIGGER_IN_CALL_FAILED, line->get_line_number() + 1); script.exec_notify(resp); line->send_response(resp, req_in_invite->get_tuid(), req_in_invite->get_tid()); line->call_hist_record.fail_call(resp); MEMMAN_DELETE(resp); delete resp; // Stop 100rel timers if they are running. line->stop_timer(LTMR_100REL_GUARD, get_object_id()); line->stop_timer(LTMR_100REL_TIMEOUT, get_object_id()); state = DS_TERMINATED; } bool t_dialog::match_response(t_response *r, t_tuid tuid) { if (tuid != 0) { if (req_out && req_out->get_tuid() == tuid) return true; if (req_out_invite && req_out_invite->get_tuid() == tuid) { return true; } if (req_cancel && req_cancel->get_tuid() == tuid) { return true; } return false; } // The implementation sends CANCEL on the open dialog. // The tags of a CANCEL response will be identical to the tags of // the INVITE, so it matches all pending dialogs as well. // So a CANCEL should only match if the dialog has a CANCEL request // pending. if (r->hdr_cseq.method == CANCEL && !req_cancel) return false; return t_abstract_dialog::match_response(r, tuid); } bool t_dialog::match_response(StunMessage *r, t_tuid tuid) { if (tuid == 0) return false; if (!req_stun) return false; return (req_stun->get_tuid() == tuid); } bool t_dialog::match_cancel(t_request *r, t_tid target_tid) { return (req_in_invite && req_in_invite->get_tid() == target_tid); } bool t_dialog::is_invite_retrans(t_request *r) { assert(r->method == INVITE); // An INVITE can only be a retransmission if an incoming INVITE is // still in progress. if (!req_in_invite) return false; t_request *request = req_in_invite->get_request(); // RFC 3261 17.2.3 t_via &orig_top_via = request->hdr_via.via_list.front(); t_via &recv_top_via = r->hdr_via.via_list.front(); if (recv_top_via.rfc3261_compliant()) { if (orig_top_via.branch != recv_top_via.branch) return false; if (orig_top_via.host != recv_top_via.host) return false; if (orig_top_via.port != recv_top_via.port) return false; return (request->hdr_cseq.method == r->hdr_cseq.method); } // Matching rules for backward compatibiliy with RFC 2543 // TODO: verify rules for matching via headers return (request->uri.sip_match(r->uri) && request->hdr_to.tag == r->hdr_to.tag && request->hdr_from.tag == r->hdr_from.tag && request->hdr_call_id.call_id == r->hdr_call_id.call_id && request->hdr_cseq.seqnr == r->hdr_cseq.seqnr && orig_top_via.host == recv_top_via.host && orig_top_via.port == recv_top_via.port); } void t_dialog::process_invite_retrans(void) { t_ip_port ip_port; // Retransmit 2xx response. // Send the response directly to the sender thread // as the INVITE transaction completed already. // (see RFC 3261 17.2.1) if (!resp_invite) return; // there is no response to send resp_invite->get_destination(ip_port); if (ip_port.ipaddr == 0) { // This should not happen. The response has been // sent before so it should be possible to sent // it again. Ignore the timeout. When the ACK // guard timer expires, the dialog will be // cleaned up. return; } evq_sender->push_network(resp_invite, ip_port); } t_dialog_state t_dialog::get_state(void) const { return state; } void t_dialog::timeout(t_line_timer timer) { switch(state) { case DS_W4INVITE_RESP: case DS_W4INVITE_RESP2: state_w4invite_resp(timer); break; case DS_EARLY: state_early(timer); break; case DS_W4ACK: state_w4ack(timer); break; case DS_W4ACK_RE_INVITE: state_w4ack_re_invite(timer); break; case DS_W4RE_INVITE_RESP2: state_w4re_invite_resp(timer); break; case DS_W4ANSWER: state_w4answer(timer); break; case DS_CONFIRMED: state_confirmed(timer); break; default: // Timeout not expected in other states. Ignore. break; } } void t_dialog::timeout_sub(t_subscribe_timer timer, const string &event_type, const string &event_id) { if (sub_refer && sub_refer->get_event_type() == event_type && sub_refer->get_event_id() == event_id) { sub_refer->timeout(timer); } else { // Timeout does not match with the current subscription. // Ignore. return; } if (sub_refer->get_state() == SS_TERMINATED && state == DS_CONFIRMED_SUB) { MEMMAN_DELETE(sub_refer); delete sub_refer; sub_refer = NULL; state = DS_TERMINATED; } } t_phone *t_dialog::get_phone(void) const { return line->get_phone(); } t_line *t_dialog::get_line(void) const { return line; } t_session *t_dialog::get_session(void) const { return session; } t_audio_session *t_dialog::get_audio_session(void) const { if (!session) return NULL; return session->get_audio_session(); } bool t_dialog::has_active_session(void) const { if (session) return session->is_rtp_active(); return false; } // RFC 3515 // Send a NOTIFY with reference progress to the referror void t_dialog::notify_refer_progress(t_response *r) { if (!sub_refer) return; if (r->is_final()) { sub_refer->send_notify(r, SUBSTATE_TERMINATED, EV_REASON_NORESOURCE); } else { sub_refer->send_notify(r, SUBSTATE_ACTIVE); } } bool t_dialog::will_release(void) const { return state == DS_W4BYE_RESP || request_cancelled || end_after_2xx_invite || end_after_ack; } twinkle-1.4.2/src/sub_refer.cpp0000644000175000001440000002140711134637764013377 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sub_refer.h" #include "line.h" #include "log.h" #include "phone_user.h" #include "user.h" #include "userintf.h" #include "audits/memman.h" t_dialog *t_sub_refer::get_dialog(void) const { return dynamic_cast(dialog); } t_sub_refer::t_sub_refer(t_dialog *_dialog, t_subscription_role _role) : t_subscription(_dialog, _role, SIP_EVENT_REFER) { // A refer subscription is implicitly defined by the REFER // transaction state = SS_ESTABLISHED; // Start the subscription timer only for a notifier. // The subscriber will start a timer when it receives NOTIFY. if (role == SR_NOTIFIER) { unsigned long dur; if (user_config->get_ask_user_to_refer()) { dur = DUR_REFER_SUB_INTERACT * 1000; } else { dur = DUR_REFER_SUBSCRIPTION * 1000; } start_timer(STMR_SUBSCRIPTION, dur); } auto_refresh = user_config->get_auto_refresh_refer_sub(); subscription_expiry = DUR_REFER_SUBSCRIPTION; sr_result = SRR_INPROG; last_response = NULL; log_file->write_header("t_sub_refer::t_sub_refer"); log_file->write_raw("Refer "); if (role == SR_SUBSCRIBER) { log_file->write_raw("subscriber"); } else { log_file->write_raw("notifier"); } log_file->write_raw(" created: event = "); log_file->write_raw(event_type); log_file->write_endl(); log_file->write_footer(); } t_sub_refer::t_sub_refer(t_dialog *_dialog, t_subscription_role _role, const string &_event_id) : t_subscription(_dialog, _role, SIP_EVENT_REFER, _event_id) { state = SS_ESTABLISHED; if (role == SR_NOTIFIER) { unsigned long dur; if (user_config->get_ask_user_to_refer()) { dur = DUR_REFER_SUB_INTERACT * 1000; } else { dur = DUR_REFER_SUBSCRIPTION * 1000; } start_timer(STMR_SUBSCRIPTION, dur); } auto_refresh = user_config->get_auto_refresh_refer_sub(); subscription_expiry = DUR_REFER_SUBSCRIPTION; sr_result = SRR_INPROG; last_response = NULL; log_file->write_header("t_sub_refer::t_sub_refer"); log_file->write_raw("Refer "); if (role == SR_SUBSCRIBER) { log_file->write_raw("subscriber"); } else { log_file->write_raw("notifier"); } log_file->write_raw(" created: event = "); log_file->write_raw(event_type); log_file->write_raw(";id="); log_file->write_raw(event_id); log_file->write_endl(); log_file->write_footer(); } t_sub_refer::~t_sub_refer() { if (last_response) { MEMMAN_DELETE(last_response); delete last_response; } log_file->write_header("t_sub_refer::~t_sub_refer"); log_file->write_raw("Refer "); if (role == SR_SUBSCRIBER) { log_file->write_raw("subscriber"); } else { log_file->write_raw("notifier"); } log_file->write_raw(" destroyed: event = "); log_file->write_raw(event_type); if (!event_id.empty()) { log_file->write_raw(";id="); log_file->write_raw(event_id); } log_file->write_endl(); log_file->write_footer(); } void t_sub_refer::send_notify(t_response *r, const string &substate, const string reason) { t_request *notify; if (substate == SUBSTATE_TERMINATED) { // RFC 3515 2.4.7 notify = create_notify(substate, reason); stop_timer(STMR_SUBSCRIPTION); } else { notify = create_notify(substate); } // RFC 3515 2.4.4 // Create message/sipfrag body containing only the status line // of the response. t_response sipfrag(r->code, r->reason); notify->body = new t_sip_body_sipfrag(&sipfrag); MEMMAN_NEW(notify->body); notify->hdr_content_type.set_media(t_media("message", "sipfrag")); // If an outgoing NOTIFY is still pending, then store this // NOTIFY in the queue if (req_out) { queue_notify.push(notify); } else { // Send NOTIFY req_out = new t_client_request(user_config, notify,0); MEMMAN_NEW(req_out); send_request(user_config, notify, req_out->get_tuid()); MEMMAN_DELETE(notify); delete notify; } // Keep response and state such that it can be resend when // a SUBSCRIBE is received. if (last_response && last_response != r) { MEMMAN_DELETE(last_response); delete last_response; last_response = NULL; } if (!last_response) last_response = (t_response *)r->copy(); current_substate = substate; } bool t_sub_refer::recv_notify(t_request *r, t_tuid tuid, t_tid tid) { if (t_subscription::recv_notify(r, tuid, tid)) return true; // RFC 3515 2.4.5. // NOTIFY must have a sipfrag body if (!r->body || r->body->get_type() != BODY_SIPFRAG) { t_response *resp = r->create_response(R_400_BAD_REQUEST, "message/sipfrag body missing"); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } // RFC 3515 2.4.5 // The sipfrag body must start with a Status-Line if (((t_sip_body_sipfrag *)r->body)->sipfrag->get_type() != MSG_RESPONSE) { t_response *resp = r->create_response(R_400_BAD_REQUEST, "sipfrag body does not begin with Status-Line"); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } t_response *sipfrag = (t_response *)((t_sip_body_sipfrag *)r->body)->sipfrag; // Determine state of reference if (r->hdr_subscription_state.substate == SUBSTATE_TERMINATED) { if (r->hdr_subscription_state.reason == EV_REASON_REJECTED) { // Referee rejected to refer sr_result = SRR_FAILED; } else if (r->hdr_subscription_state.reason == EV_REASON_NORESOURCE) { // Reference is finished. The sipfrag body indicates // success or failure. if (sipfrag->is_success()) { sr_result = SRR_SUCCEEDED; } else { sr_result = SRR_FAILED; } } } // Inform user about progress ui->cb_notify_recvd(get_dialog()->get_line()->get_line_number(), r); t_response *resp = r->create_response(R_200_OK); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } bool t_sub_refer::recv_subscribe(t_request *r, t_tuid tuid, t_tid tid) { unsigned long expires; if (t_subscription::recv_subscribe(r, tuid, tid)) return true; // Determine value for Expires header if (!r->hdr_expires.is_populated() || r->hdr_expires.time > 2 * DUR_REFER_SUBSCRIPTION) { // User did not indicate an expiry time for subscription // refresh or a time larger then 2 times the default. // Just use the Twinkle default. stop_timer(STMR_SUBSCRIPTION); start_timer(STMR_SUBSCRIPTION, DUR_REFER_SUBSCRIPTION * 1000); expires = DUR_REFER_SUBSCRIPTION; } else { expires = r->hdr_expires.time; } t_response *resp = r->create_response(R_200_OK); // RFC 3265 7.1 // Contact header is mandatory t_contact_param contact; contact.uri.set_url(get_dialog()->get_line()->create_user_contact( h_ip2str(resp->get_local_ip()))); resp->hdr_contact.add_contact(contact); // Expires header is mandatory resp->hdr_expires.set_time(expires); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; // RFC 3265 3.2.2 // After a succesful SUBSCRIBE the notifier must immediately // send a NOTIFY. // If no last response has been kept then this is probably a // first SUBSCRIBE. The dialog has to send the initial NOTIFY. if (last_response) { if (expires == 0) { send_notify(last_response, SUBSTATE_TERMINATED, EV_REASON_TIMEOUT); } else { send_notify(last_response, current_substate); } } return true; } bool t_sub_refer::timeout(t_subscribe_timer timer) { if (t_subscription::timeout(timer)) return true; switch (timer) { case STMR_SUBSCRIPTION: switch (role) { case SR_NOTIFIER: // RFC 3265 3.1.6.4 // The subscription has expired // RFC 2.4.5 // Each NOTIFY MUST contain a body if (last_response) { // Repeat last response as body send_notify(last_response, SUBSTATE_TERMINATED, EV_REASON_TIMEOUT); } else { // This should never happen. Create a timeout // response for the body. t_response resp(R_408_REQUEST_TIMEOUT); send_notify(&resp, SUBSTATE_TERMINATED, EV_REASON_TIMEOUT); } log_file->write_report("Refer notifier timed out.", "t_sub_refer::timeout"); return true; case SR_SUBSCRIBER: // Should have been handled by parent class default: assert(false); } break; default: assert(false); } return false; } t_sub_refer_result t_sub_refer::get_sr_result(void) const { return sr_result; } twinkle-1.4.2/src/sender.cpp0000644000175000001440000003741311134637677012712 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include "events.h" #include "log.h" #include "phone.h" #include "sender.h" #include "translator.h" #include "userintf.h" #include "util.h" #include "sockets/connection_table.h" #include "sockets/socket.h" #include "parser/parse_ctrl.h" #include "parser/sip_message.h" #include "audits/memman.h" #include "stun/stun.h" #define MAX_TRANSMIT_RETRIES 3 // Maximum size of a message to be sent over an existing connection. // For larger message always a new connection is opened to avoid // head of line blocking. #define MAX_REUSE_CONN_SIZE 10240 extern t_socket_udp *sip_socket; extern t_connection_table *connection_table; extern t_event_queue *evq_sender; extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_trans_layer; extern t_phone *phone; // Number of consecutive non-icmp errors received static int num_non_icmp_errors = 0; // Check if the error is caused by an incoming ICMP error. If so, then deliver // the ICMP error to the transaction manager. // // err - error returned by sendto // dst_addr - destination IP address of packet that failed to be sent // dst_port - destination port of packet that failed to be sent // // Returns true if the packet that failed to be sent, should still be sent. // Returns false if the packet that failed to be sent, should be discarded. static bool handle_socket_err(int err, unsigned long dst_addr, unsigned short dst_port) { string log_msg; // Check if an ICMP error has been received t_icmp_msg icmp; if (sip_socket->get_icmp(icmp)) { log_msg = "Received ICMP from: "; log_msg += h_ip2str(icmp.icmp_src_ipaddr); log_msg += "\nICMP type: "; log_msg += int2str(icmp.type); log_msg += "\nICMP code: "; log_msg += int2str(icmp.code); log_msg += "\nDestination of packet causing ICMP: "; log_msg += h_ip2str(icmp.ipaddr); log_msg += ":"; log_msg += int2str(icmp.port); log_msg += "\nSocket error: "; log_msg += int2str(err); log_msg += " "; log_msg += get_error_str(err); log_file->write_report(log_msg, "::hanlde_socket_err", LOG_NORMAL); evq_trans_mgr->push_icmp(icmp); num_non_icmp_errors = 0; // If the ICMP error comes from the same destination as the // destination of the packet that failed to be sent, then the // packet should be discarded as it can most likely not be // delivered and would cause an infinite loop of ICMP errors // otherwise. if (icmp.ipaddr == dst_addr && icmp.port == dst_port) { return false; } } else { // Even if an ICMP message is received this code can get executed. // Sometimes the error is already present on the socket, but the ICMP // message is not yet queued. log_msg = "Failed to send to SIP UDP socket.\n"; log_msg += "Error code: "; log_msg += int2str(err); log_msg += "\n"; log_msg += get_error_str(err); log_file->write_report(log_msg, "::handle_socket_err"); num_non_icmp_errors++; /* * non-ICMP errors occur when a destination on the same * subnet cannot be reached. So this code seems to be * harmful. if (num_non_icmp_errors > 100) { log_msg = "Excessive number of socket errors."; log_file->write_report(log_msg, "::handle_socket_err", LOG_NORMAL, LOG_CRITICAL); log_msg = TRANSLATE("Excessive number of socket errors."); ui->cb_show_msg(log_msg, MSG_CRITICAL); exit(1); } */ } return true; } static void send_sip_udp(t_event *event) { t_event_network *e; e = (t_event_network *)event; assert(e->dst_addr != 0); assert(e->dst_port != 0); // Set correct transport in topmost Via header of a request. // For a response the Via header is copied from the incoming request. t_sip_message *sip_msg = e->get_msg(); if (sip_msg->get_type() == MSG_REQUEST) { sip_msg->hdr_via.via_list.front().transport = "UDP"; } string m = sip_msg->encode(); log_file->write_header("::send_sip_udp", LOG_SIP); log_file->write_raw("Send to: udp:"); log_file->write_raw(h_ip2str(e->dst_addr)); log_file->write_raw(":"); log_file->write_raw(e->dst_port); log_file->write_endl(); log_file->write_raw(m); log_file->write_endl(); log_file->write_footer(); bool msg_sent = false; int transmit_count = 0; while (!msg_sent && transmit_count++ <= MAX_TRANSMIT_RETRIES) { try { sip_socket->sendto(e->dst_addr, e->dst_port, m.c_str(), m.size()); num_non_icmp_errors = 0; msg_sent = true; } catch (int err) { if (!handle_socket_err(err, e->dst_addr, e->dst_port)) { // Discard packet. msg_sent = true; } else { if (transmit_count <= MAX_TRANSMIT_RETRIES) { // Sleep 100 ms struct timespec sleeptimer; sleeptimer.tv_sec = 0; sleeptimer.tv_nsec = 100000000; nanosleep(&sleeptimer, NULL); } } } } } static void send_sip_tcp(t_event *event) { t_event_network *e; bool new_connection = false; e = (t_event_network *)event; unsigned long dst_addr = e->dst_addr; unsigned short dst_port = e->dst_port; assert(dst_addr != 0); assert(dst_port != 0); // Set correct transport in topmost Via header of a request. // For a response the Via header is copied from the incoming request. t_sip_message *sip_msg = e->get_msg(); if (sip_msg->get_type() == MSG_REQUEST) { sip_msg->hdr_via.via_list.front().transport = "TCP"; } t_connection *conn = NULL; // If a connection exists then re-use this connection. Otherwise a new connection // must be opened. // For a request a connection to the destination address and port of the event // must be opened. // For a response a connection to the sent-by address and port in the Via header // must be opened. if (sip_msg->get_encoded_size() <= MAX_REUSE_CONN_SIZE) { // Re-use a connection only for small messages. Large messages cause // head of line blocking. conn = connection_table->get_connection(dst_addr, dst_port); } else { log_file->write_report( "Open new connection for large message.", "::send_sip_tcp", LOG_SIP, LOG_DEBUG); } if (!conn) { if (sip_msg->get_type() == MSG_RESPONSE) { t_ip_port dst_ip_port; sip_msg->hdr_via.get_response_dst(dst_ip_port); dst_addr = dst_ip_port.ipaddr; dst_port = dst_ip_port.port; } t_socket_tcp *tcp = new t_socket_tcp(); MEMMAN_NEW(tcp); log_file->write_header("::send_sip_tcp", LOG_SIP, LOG_DEBUG); log_file->write_raw("Open connection to "); log_file->write_raw(h_ip2str(dst_addr)); log_file->write_raw(":"); log_file->write_raw(dst_port); log_file->write_endl(); log_file->write_footer(); try { tcp->connect(dst_addr, dst_port); } catch (int err) { evq_trans_mgr->push_failure(FAIL_TRANSPORT, sip_msg->hdr_via.via_list.front().branch, sip_msg->hdr_cseq.method); log_file->write_header("::send_sip_tcp", LOG_SIP, LOG_WARNING); log_file->write_raw("Failed to open connection to "); log_file->write_raw(h_ip2str(dst_addr)); log_file->write_raw(":"); log_file->write_raw(dst_port); log_file->write_endl(); log_file->write_footer(); delete tcp; MEMMAN_DELETE(tcp); return; } conn = new t_connection(tcp); MEMMAN_NEW(conn); // For large messages always a new connection is established. // No other messages should be sent via this connection to avoid // head of line blocking. if (sip_msg->get_encoded_size() > MAX_REUSE_CONN_SIZE) { conn->set_reuse(false); } new_connection = true; } // NOTE: if an existing connection was found, the connection table is now locked. // If persistent TCP connections are required, then // 1) If the SIP message is a registration request, then add the URI from the To-header // to the registered URI set of the connection. // 2) If the SIP message is a de-registration request then remove the URI from the // To-header from the registered URI set of the connection. if (sip_msg->get_type() == MSG_REQUEST) { t_request *req = dynamic_cast(sip_msg); if (req->method == REGISTER) { t_phone_user *pu = phone->find_phone_user(req->hdr_to.uri); if (pu) { t_user *user_config = pu->get_user_profile(); assert(user_config); if (user_config->get_persistent_tcp()) { conn->update_registered_uri_set(req); } } else { log_file->write_header("::send_sip_tcp", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Cannot find phone user for "); log_file->write_raw(req->hdr_to.uri.encode()); log_file->write_endl(); log_file->write_footer(); } } } string m = sip_msg->encode(); log_file->write_header("::send_sip_tcp", LOG_SIP); log_file->write_raw("Send to: tcp:"); log_file->write_raw(h_ip2str(dst_addr)); log_file->write_raw(":"); log_file->write_raw(dst_port); log_file->write_endl(); log_file->write_raw(m); log_file->write_endl(); log_file->write_footer(); conn->async_send(m.c_str(), m.size()); if (new_connection) { connection_table->add_connection(conn); } else { connection_table->unlock(); } } static void send_stun(t_event *event) { t_event_stun_request *e; e = (t_event_stun_request *)event; assert(e->dst_addr != 0); assert(e->dst_port != 0); log_file->write_header("::send_stun", LOG_STUN); log_file->write_raw("Send to: "); log_file->write_raw(h_ip2str(e->dst_addr)); log_file->write_raw(":"); log_file->write_raw(e->dst_port); log_file->write_endl(); log_file->write_raw(stunMsg2Str(*e->get_msg())); log_file->write_footer(); StunAtrString stun_pass; stun_pass.sizeValue = 0; char m[STUN_MAX_MESSAGE_SIZE]; int msg_size = stunEncodeMessage(*e->get_msg(), m, STUN_MAX_MESSAGE_SIZE, stun_pass, false); bool msg_sent = false; int transmit_count = 0; while (!msg_sent && transmit_count++ <= MAX_TRANSMIT_RETRIES) { try { sip_socket->sendto(e->dst_addr, e->dst_port, m, msg_size); num_non_icmp_errors = 0; msg_sent = true; } catch (int err) { if (!handle_socket_err(err, e->dst_addr, e->dst_port)) { // Discard packet. msg_sent = true; } else { if (transmit_count <= MAX_TRANSMIT_RETRIES) { // Sleep 100 ms struct timespec sleeptimer; sleeptimer.tv_sec = 0; sleeptimer.tv_nsec = 100000000; nanosleep(&sleeptimer, NULL); } } } } } static void send_nat_keepalive(t_event *event) { t_event_nat_keepalive *e = dynamic_cast(event); assert(e); assert(e->dst_addr != 0); assert(e->dst_port != 0); char m[2] = { '\r', '\n' }; bool msg_sent = false; int transmit_count = 0; while (!msg_sent && transmit_count++ <= MAX_TRANSMIT_RETRIES) { try { sip_socket->sendto(e->dst_addr, e->dst_port, m, 2); num_non_icmp_errors = 0; msg_sent = true; } catch (int err) { if (!handle_socket_err(err, e->dst_addr, e->dst_port)) { // Discard packet. msg_sent = true; } else { if (transmit_count <= MAX_TRANSMIT_RETRIES) { // Sleep 100 ms struct timespec sleeptimer; sleeptimer.tv_sec = 0; sleeptimer.tv_nsec = 100000000; nanosleep(&sleeptimer, NULL); } } } } } static void send_tcp_ping(t_event *event) { string log_msg; t_event_tcp_ping *e = dynamic_cast(event); assert(e); t_connection *conn = connection_table->get_connection( e->get_dst_addr(), e->get_dst_port()); if (!conn) { // There is no connection to send the ping. log_msg = "Connection to "; log_msg += h_ip2str(e->get_dst_addr()); log_msg += ":"; log_msg += int2str(e->get_dst_port()); log_msg += " is gone."; log_file->write_report(log_msg, "::send_tcp_ping", LOG_SIP, LOG_WARNING); // Signal the transaction layer that the connection is gone. evq_trans_layer->push_broken_connection(e->get_user_uri()); return; } conn->async_send(TCP_PING_PACKET, strlen(TCP_PING_PACKET)); connection_table->unlock(); } void *tcp_sender_loop(void *arg) { string log_msg; list writable_connections; while(true) { writable_connections.clear(); writable_connections = connection_table->select_write(NULL); if (writable_connections.empty()) { // Another thread cancelled the select command. // Stop listening. break; } // NOTE: The connection table is now locked. for (list::iterator it = writable_connections.begin(); it != writable_connections.end(); ++it) { try { (*it)->write(); } catch (int err) { if (err == EAGAIN || err == EWOULDBLOCK || err == EINTR) { continue; } unsigned long remote_addr; unsigned short remote_port; (*it)->get_remote_address(remote_addr, remote_port); log_msg = "Got error on socket to "; log_msg += h_ip2str(remote_addr); log_msg += ":"; log_msg += int2str(remote_port); log_msg += " - "; log_msg += get_error_str(err); log_file->write_report(log_msg, "::tcp_sender_loop", LOG_SIP, LOG_WARNING); // Connection is broken. // Signal the transaction layer that the connection is broken for // all associated registered URI's. const list &uris = (*it)->get_registered_uri_set(); for (list::const_iterator it_uri = uris.begin(); it_uri != uris.end(); ++it_uri) { evq_trans_layer->push_broken_connection(*it_uri); } // Remove the broken connection. connection_table->remove_connection(*it); MEMMAN_DELETE(*it); delete *it; continue; } } connection_table->unlock(); } log_file->write_report("TCP sender terminated.", "::tcp_sender_loop"); return NULL; } void *sender_loop(void *arg) { t_event *event; t_event_network *ev_network; unsigned long local_ipaddr; bool quit = false; while (!quit) { event = evq_sender->pop(); switch(event->get_type()) { case EV_NETWORK: ev_network = dynamic_cast(event); local_ipaddr = get_src_ip4_address_for_dst(ev_network->dst_addr); if (local_ipaddr == 0) { log_file->write_header("::sender_loop", LOG_NORMAL, LOG_CRITICAL); log_file->write_raw("Cannot get source IP address for destination: "); log_file->write_raw(h_ip2str(ev_network->dst_addr)); log_file->write_endl(); log_file->write_footer(); evq_trans_mgr->push_failure(FAIL_TRANSPORT, ev_network->get_msg()->hdr_via.via_list.front().branch, ev_network->get_msg()->hdr_cseq.method); break; } if (!ev_network->get_msg()->local_ip_check()) { log_file->write_report("Local IP check failed", "::sender_loop", LOG_NORMAL, LOG_CRITICAL); break; } if (ev_network->transport == "udp") { send_sip_udp(event); } else if (ev_network->transport == "tcp") { send_sip_tcp(event); } else { log_file->write_header("::sender_loop", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Received unsupported transport: "); log_file->write_raw(ev_network->transport); log_file->write_endl(); log_file->write_footer(); } break; case EV_STUN_REQUEST: send_stun(event); break; case EV_NAT_KEEPALIVE: send_nat_keepalive(event); break; case EV_TCP_PING: send_tcp_ping(event); break; case EV_QUIT: quit = true; break; default: assert(false); } MEMMAN_DELETE(event); delete event; } return NULL; } twinkle-1.4.2/src/prohibit_thread.cpp0000644000175000001440000000252511127714056014562 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "prohibit_thread.h" void i_prohibit_thread::add_prohibited_thread(void) { prohibited_mutex.lock(); prohibited_threads.insert(t_thread::self()); prohibited_mutex.unlock(); } void i_prohibit_thread::remove_prohibited_thread(void) { prohibited_mutex.lock(); prohibited_threads.erase(t_thread::self()); prohibited_mutex.unlock(); } bool i_prohibit_thread::is_prohibited_thread(void) const { prohibited_mutex.lock(); bool result = (prohibited_threads.find(t_thread::self()) != prohibited_threads.end()); prohibited_mutex.unlock(); return result; } twinkle-1.4.2/src/transaction_layer.h0000644000175000001440000001017511127714047014601 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TRANSACTION_LAYER_H #define _TRANSACTION_LAYER_H #include "events.h" #include "prohibit_thread.h" #include "transaction.h" #include "parser/request.h" #include "parser/response.h" #include "stun/stun.h" #include "threads/mutex.h" typedef unsigned short t_tuid; class t_transaction_layer : public i_prohibit_thread { private: // Mutex to guarantee that only 1 thread at a time is // accessing the transaction layer. mutable t_recursive_mutex tl_mutex; void recvd_response(t_response *r, t_tuid tuid, t_tid tid); void recvd_request(t_request *r, t_tid tid, t_tid tid_cancel_target); void recvd_async_response(t_event_async_response *event); protected: // Client event handlers // After returning from this function, the response pointer // will be deleted. virtual void recvd_provisional(t_response *r, t_tuid tuid, t_tid tid) = 0; virtual void recvd_success(t_response *r, t_tuid tuid, t_tid tid) = 0; virtual void recvd_redirect(t_response *r, t_tuid tuid, t_tid tid) = 0; virtual void recvd_client_error(t_response *r, t_tuid tuid, t_tid tid) = 0; virtual void recvd_server_error(t_response *r, t_tuid tuid, t_tid tid) = 0; virtual void recvd_global_error(t_response *r, t_tuid tuid, t_tid tid) = 0; // General post processing for all responses virtual void post_process_response(t_response *r, t_tuid tuid, t_tid tid) = 0; // Server event handlers // After returning from this function, the request pointer // will be deleted. virtual void recvd_invite(t_request *r, t_tid tid) = 0; virtual void recvd_ack(t_request *r, t_tid tid) = 0; virtual void recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid) = 0; virtual void recvd_bye(t_request *r, t_tid tid) = 0; virtual void recvd_options(t_request *r, t_tid tid) = 0; virtual void recvd_register(t_request *r, t_tid tid) = 0; virtual void recvd_prack(t_request *r, t_tid tid) = 0; virtual void recvd_subscribe(t_request *r, t_tid tid) = 0; virtual void recvd_notify(t_request *r, t_tid tid) = 0; virtual void recvd_refer(t_request *r, t_tid tid) = 0; virtual void recvd_info(t_request *r, t_tid tid) = 0; virtual void recvd_message(t_request *r, t_tid tid) = 0; // General post processing for all requests virtual void post_process_request(t_request *r, t_tid cancel_tid, t_tid target_tid) = 0; // The transaction failed and is aborted virtual void failure(t_failure failure, t_tid tid) = 0; // STUN event handler virtual void recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid) = 0; // The user has granted or rejected an incoming REFER request. virtual void recvd_refer_permission(bool permission) = 0; /** * Handle timeout event. * @param e [in] Timeout event. */ virtual void handle_event_timeout(t_event_timeout *e) = 0; /** * Handle broken connection event. * @param e [in] Broken connection event. */ virtual void handle_broken_connection(t_event_broken_connection *e) = 0; public: virtual ~t_transaction_layer() {}; // Client primitives void send_request(t_user *user_config, t_request *r, t_tuid tuid); void send_request(t_user *user_config, StunMessage *r, t_tuid tuid); // Server primitives void send_response(t_response *r, t_tuid tuid, t_tid tid); // Main loop void run(void); // Lock and unlocking methods for dedicated access to the // transaction layer. void lock(void) const; void unlock(void) const; }; #endif twinkle-1.4.2/src/diamondcard.cpp0000644000175000001440000000711211151043744013651 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "diamondcard.h" #include #include "twinkle_config.h" #include "util.h" #include "sockets/url.h" #define DIAMONDCARD_DISTSITE "twinkle" #define DIAMONDCARD_URL_SIGNUP "https://www.diamondcard.us/exec/voip-login?act=sgn&spo=%DISTSITE" #define DIAMONDCARD_URL_ACTION "https://www.diamondcard.us/exec/voip-login?"\ "accId=%ACCID&pinCode=%PIN&act=%ACT&spo=%DISTSITE" string diamondcard_url(t_dc_action action, const string &accountId, const string &pinCode) { string url; if (action == DC_ACT_SIGNUP) { url = DIAMONDCARD_URL_SIGNUP; } else { url = DIAMONDCARD_URL_ACTION; url = replace_first(url, "%ACCID", t_url::escape_hnv(accountId)); url = replace_first(url, "%PIN", t_url::escape_hnv(pinCode)); switch (action) { case DC_ACT_BALANCE_HISTORY: url = replace_first(url, "%ACT", "bh"); break; case DC_ACT_RECHARGE: url = replace_first(url, "%ACT", "rch"); break; case DC_ACT_CALL_HISTORY: url = replace_first(url, "%ACT", "ch"); break; case DC_ACT_ADMIN_CENTER: url = replace_first(url, "%ACT", "log"); break; default: assert(false); } } url = replace_first(url, "%DISTSITE", DIAMONDCARD_DISTSITE); return url; } void diamondcard_set_user_config(t_user &user, const string &displayName, const string &accountId, const string &pinCode) { // User user.set_display(displayName); user.set_name(accountId); // The real domain name is "diamondcard.us", but Diamondcard // instructs users to use "sip.diamondcard.us" for the domain. // This latter name is resolvable by both a DNS SRV and A lookup. // So clients not capable of DNS SRV lookups van still work with // this domain name. To be consistent with other client settings // Twinkle uses this domain name too. user.set_domain("sip.diamondcard.us"); user.set_auth_name(accountId); user.set_auth_pass(pinCode); // SIP server user.set_use_outbound_proxy(true); user.set_outbound_proxy(t_url("sip:sip.diamondcard.us")); // Audio codecs list codecs; codecs.push_back(CODEC_G711_ULAW); codecs.push_back(CODEC_G711_ALAW); #ifdef HAVE_ILBC codecs.push_back(CODEC_ILBC); #endif codecs.push_back(CODEC_GSM); user.set_codecs(codecs); // Voice mail user.set_mwi_vm_address("80"); // IM user.set_im_send_iscomposing(false); // Presence user.set_pres_publish_startup(false); // NAT user.set_enable_nat_keepalive(true); user.set_timer_nat_keepalive(20); // Address format user.set_numerical_user_is_phone(true); } listdiamondcard_get_users(t_phone *phone) { list users = phone->ref_users(); list diamond_users; for (list::const_iterator it = users.begin(); it != users.end(); ++it) { if ((*it)->is_diamondcard_account()) { diamond_users.push_back(*it); } } return diamond_users; } twinkle-1.4.2/src/Makefile.am0000644000175000001440000000466311150245720012741 00000000000000AM_LDFLAGS = -L $(libdir) AM_CPPFLAGS = -Wall $(CCRTP_CFLAGS) $(XML2_CFLAGS) -DDATADIR=\"$(pkgdatadir)\" noinst_PROGRAMS = twinkle noinst_LIBRARIES = libtwinkle.a twinkle_SOURCES = main.cpp twinkle_LDADD = libtwinkle.a\ $(top_builddir)/src/parser/libsipparser.a\ $(top_builddir)/src/sdp/libsdpparser.a\ $(top_builddir)/src/sockets/libsocket.a\ $(top_builddir)/src/threads/libthread.a\ $(top_builddir)/src/audio/libaudio.a\ $(top_builddir)/src/audits/libaudits.a\ $(top_builddir)/src/stun/libstun.a\ $(top_builddir)/src/mwi/libmwi.a\ $(top_builddir)/src/im/libim.a\ $(top_builddir)/src/presence/libpresence.a\ $(top_builddir)/src/patterns/libpatterns.a\ $(top_builddir)/src/utils/libutils.a\ $(GSM_LIBS)\ $(CCRTP_LIBS)\ $(XML2_LIBS)\ -lncurses \ -lreadline \ -lsndfile\ -lmagic libtwinkle_a_SOURCES =\ abstract_dialog.cpp\ address_book.cpp\ auth.cpp\ call_history.cpp\ call_script.cpp\ client_request.cpp\ cmd_socket.cpp\ dialog.cpp\ diamondcard.cpp\ epa.cpp\ events.cpp\ id_object.cpp\ line.cpp\ listener.cpp\ log.cpp\ phone.cpp\ phone_user.cpp\ prohibit_thread.cpp\ redirect.cpp\ sender.cpp\ service.cpp\ session.cpp\ sub_refer.cpp\ subscription.cpp\ subscription_dialog.cpp\ sys_settings.cpp\ timekeeper.cpp\ transaction.cpp\ transaction_layer.cpp\ transaction_mgr.cpp\ user.cpp\ userintf.cpp\ util.cpp\ abstract_dialog.h\ address_book.h\ auth.h\ call_history.h\ call_script.h\ client_request.h\ cmd_socket.h\ dialog.h\ diamondcard.h\ epa.h\ events.h\ exceptions.h\ id_object.h\ line.h\ listener.h\ log.h\ phone.h\ phone_user.h\ prohibit_thread.h\ protocol.h\ redirect.h\ sender.h\ sequence_number.h\ service.h\ session.h\ sub_refer.h\ subscription.h\ subscription_dialog.h\ sys_settings.h\ timekeeper.h\ transaction.h\ transaction_layer.h\ transaction_mgr.h\ translator.h\ user.h\ userintf.h\ util.h SUBDIRS = audio audits im mwi parser patterns presence sdp sockets stun threads utils . gui gui/lang twinkle-1.4.2/src/Makefile.in0000644000175000001440000006442411151323405012751 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ noinst_PROGRAMS = twinkle$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/twinkle_config.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libtwinkle_a_AR = $(AR) $(ARFLAGS) libtwinkle_a_LIBADD = am_libtwinkle_a_OBJECTS = abstract_dialog.$(OBJEXT) \ address_book.$(OBJEXT) auth.$(OBJEXT) call_history.$(OBJEXT) \ call_script.$(OBJEXT) client_request.$(OBJEXT) \ cmd_socket.$(OBJEXT) dialog.$(OBJEXT) diamondcard.$(OBJEXT) \ epa.$(OBJEXT) events.$(OBJEXT) id_object.$(OBJEXT) \ line.$(OBJEXT) listener.$(OBJEXT) log.$(OBJEXT) \ phone.$(OBJEXT) phone_user.$(OBJEXT) prohibit_thread.$(OBJEXT) \ redirect.$(OBJEXT) sender.$(OBJEXT) service.$(OBJEXT) \ session.$(OBJEXT) sub_refer.$(OBJEXT) subscription.$(OBJEXT) \ subscription_dialog.$(OBJEXT) sys_settings.$(OBJEXT) \ timekeeper.$(OBJEXT) transaction.$(OBJEXT) \ transaction_layer.$(OBJEXT) transaction_mgr.$(OBJEXT) \ user.$(OBJEXT) userintf.$(OBJEXT) util.$(OBJEXT) libtwinkle_a_OBJECTS = $(am_libtwinkle_a_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) am_twinkle_OBJECTS = main.$(OBJEXT) twinkle_OBJECTS = $(am_twinkle_OBJECTS) am__DEPENDENCIES_1 = twinkle_DEPENDENCIES = libtwinkle.a \ $(top_builddir)/src/parser/libsipparser.a \ $(top_builddir)/src/sdp/libsdpparser.a \ $(top_builddir)/src/sockets/libsocket.a \ $(top_builddir)/src/threads/libthread.a \ $(top_builddir)/src/audio/libaudio.a \ $(top_builddir)/src/audits/libaudits.a \ $(top_builddir)/src/stun/libstun.a \ $(top_builddir)/src/mwi/libmwi.a \ $(top_builddir)/src/im/libim.a \ $(top_builddir)/src/presence/libpresence.a \ $(top_builddir)/src/patterns/libpatterns.a \ $(top_builddir)/src/utils/libutils.a $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libtwinkle_a_SOURCES) $(twinkle_SOURCES) DIST_SOURCES = $(libtwinkle_a_SOURCES) $(twinkle_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_LDFLAGS = -L $(libdir) AM_CPPFLAGS = -Wall $(CCRTP_CFLAGS) $(XML2_CFLAGS) -DDATADIR=\"$(pkgdatadir)\" noinst_LIBRARIES = libtwinkle.a twinkle_SOURCES = main.cpp twinkle_LDADD = libtwinkle.a\ $(top_builddir)/src/parser/libsipparser.a\ $(top_builddir)/src/sdp/libsdpparser.a\ $(top_builddir)/src/sockets/libsocket.a\ $(top_builddir)/src/threads/libthread.a\ $(top_builddir)/src/audio/libaudio.a\ $(top_builddir)/src/audits/libaudits.a\ $(top_builddir)/src/stun/libstun.a\ $(top_builddir)/src/mwi/libmwi.a\ $(top_builddir)/src/im/libim.a\ $(top_builddir)/src/presence/libpresence.a\ $(top_builddir)/src/patterns/libpatterns.a\ $(top_builddir)/src/utils/libutils.a\ $(GSM_LIBS)\ $(CCRTP_LIBS)\ $(XML2_LIBS)\ -lncurses \ -lreadline \ -lsndfile\ -lmagic libtwinkle_a_SOURCES = \ abstract_dialog.cpp\ address_book.cpp\ auth.cpp\ call_history.cpp\ call_script.cpp\ client_request.cpp\ cmd_socket.cpp\ dialog.cpp\ diamondcard.cpp\ epa.cpp\ events.cpp\ id_object.cpp\ line.cpp\ listener.cpp\ log.cpp\ phone.cpp\ phone_user.cpp\ prohibit_thread.cpp\ redirect.cpp\ sender.cpp\ service.cpp\ session.cpp\ sub_refer.cpp\ subscription.cpp\ subscription_dialog.cpp\ sys_settings.cpp\ timekeeper.cpp\ transaction.cpp\ transaction_layer.cpp\ transaction_mgr.cpp\ user.cpp\ userintf.cpp\ util.cpp\ abstract_dialog.h\ address_book.h\ auth.h\ call_history.h\ call_script.h\ client_request.h\ cmd_socket.h\ dialog.h\ diamondcard.h\ epa.h\ events.h\ exceptions.h\ id_object.h\ line.h\ listener.h\ log.h\ phone.h\ phone_user.h\ prohibit_thread.h\ protocol.h\ redirect.h\ sender.h\ sequence_number.h\ service.h\ session.h\ sub_refer.h\ subscription.h\ subscription_dialog.h\ sys_settings.h\ timekeeper.h\ transaction.h\ transaction_layer.h\ transaction_mgr.h\ translator.h\ user.h\ userintf.h\ util.h SUBDIRS = audio audits im mwi parser patterns presence sdp sockets stun threads utils . gui gui/lang all: twinkle_config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh twinkle_config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/twinkle_config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status src/twinkle_config.h $(srcdir)/twinkle_config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f twinkle_config.h stamp-h1 clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libtwinkle.a: $(libtwinkle_a_OBJECTS) $(libtwinkle_a_DEPENDENCIES) -rm -f libtwinkle.a $(libtwinkle_a_AR) libtwinkle.a $(libtwinkle_a_OBJECTS) $(libtwinkle_a_LIBADD) $(RANLIB) libtwinkle.a clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) twinkle$(EXEEXT): $(twinkle_OBJECTS) $(twinkle_DEPENDENCIES) @rm -f twinkle$(EXEEXT) $(CXXLINK) $(twinkle_LDFLAGS) $(twinkle_OBJECTS) $(twinkle_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abstract_dialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address_book.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/call_history.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/call_script.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_request.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diamondcard.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id_object.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/line.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/listener.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phone.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phone_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prohibit_thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redirect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sender.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub_refer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subscription.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subscription_dialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys_settings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timekeeper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transaction.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transaction_layer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transaction_mgr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/userintf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) twinkle_config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) twinkle_config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) twinkle_config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) twinkle_config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LIBRARIES) $(PROGRAMS) twinkle_config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ clean clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \ clean-recursive ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-hdr \ distclean-recursive distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/subscription.cpp0000644000175000001440000004532711127714056014146 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "subscription.h" #include "dialog.h" #include "line.h" #include "log.h" #include "phone_user.h" #include "audits/memman.h" #include "parser/hdr_event.h" extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_timekeeper; extern t_timekeeper *timekeeper; string t_subscription_state2str(t_subscription_state state) { switch (state) { case SS_NULL: return "SS_NULL"; case SS_ESTABLISHED: return "SS_ESTABLISHED"; case SS_UNSUBSCRIBING: return "SS_UNSUBSCRIBING"; case SS_UNSUBSCRIBED: return "SS_UNSUBSCRIBED"; case SS_TERMINATED: return "SS_TERMINATED"; } return "UNKNOWN"; } ///////////// // PROTECTED ///////////// void t_subscription::log_event() const { log_file->write_raw("Event: "); log_file->write_raw(event_type); log_file->write_endl(); log_file->write_raw("Event id: "); log_file->write_raw(event_id); log_file->write_endl(); } void t_subscription::remove_client_request(t_client_request **cr) { if ((*cr)->dec_ref_count() == 0) { MEMMAN_DELETE(*cr); delete *cr; } *cr = NULL; } t_request *t_subscription::create_subscribe(unsigned long expires) const { // RFC 3265 3.1.4 t_request *r = dialog->create_request(SUBSCRIBE); r->hdr_expires.set_time(expires); r->hdr_event.set_event_type(event_type); if (event_id.size() > 0) r->hdr_event.set_id(event_id); // Re-calculate the destination as the event type may // influence the route to be taken. // The destination has been calculated already at the // dialog level. r->calc_destinations(*user_config); return r; } t_request *t_subscription::create_notify(const string &sub_state, const string &reason) const { // RFC 3265 3.2.2 t_request *r = dialog->create_request(NOTIFY); r->hdr_event.set_event_type(event_type); if (event_id.size() > 0) r->hdr_event.set_id(event_id); r->hdr_subscription_state.set_substate(sub_state); // Subscription state specific parameters if (sub_state == SUBSTATE_ACTIVE || sub_state == SUBSTATE_PENDING) { // Add expires parameter with remaining time if (id_subscription_timeout) { long remaining = timekeeper-> get_remaining_time(id_subscription_timeout); r->hdr_subscription_state.set_expires(remaining / 1000); } } else if (sub_state == SUBSTATE_TERMINATED) { // Add reason parameter if (reason.size() > 0) { r->hdr_subscription_state.set_reason(reason); } } return r; } void t_subscription::send_request(t_user *user_config, t_request *r, t_tuid tuid) const { evq_trans_mgr->push_user(user_config, (t_sip_message *)r, tuid, 0); } void t_subscription::send_response(t_user *user_config, t_response *r, t_tuid tuid, t_tid tid) const { evq_trans_mgr->push_user(user_config, (t_sip_message *)r, tuid, tid); } void t_subscription::start_timer(t_subscribe_timer timer, long duration) { t_tmr_subscribe *t; t_object_id oid_line = 0; switch(timer) { case STMR_SUBSCRIPTION: if (dynamic_cast(dialog) != NULL) { oid_line = dynamic_cast(dialog)->get_line()->get_object_id(); } t = new t_tmr_subscribe(duration, timer, oid_line, dialog->get_object_id(), event_type, event_id); MEMMAN_NEW(t); id_subscription_timeout = t->get_object_id(); break; default: assert(false); } evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_subscription::stop_timer(t_subscribe_timer timer) { unsigned short *id; switch(timer) { case STMR_SUBSCRIPTION: id = &id_subscription_timeout; break; default: assert(false); } if (*id != 0) evq_timekeeper->push_stop_timer(*id); *id = 0; } ////////// // PUBLIC ////////// t_subscription::t_subscription(t_abstract_dialog *_dialog, t_subscription_role _role, const string &_event_type) { dialog = _dialog; user_config = dialog->get_user(); assert(user_config); role = _role; state = SS_NULL; resubscribe_after = 0; may_resubscribe = false; pending = true; id_subscription_timeout = 0; req_out = NULL; event_type = _event_type; auto_refresh = true; subscription_expiry = 3600; default_duration = 3600; } t_subscription::t_subscription(t_abstract_dialog *_dialog, t_subscription_role _role, const string &_event_type, const string &_event_id) { dialog = _dialog; user_config = dialog->get_user(); assert(user_config); role = _role; state = SS_NULL; resubscribe_after = 0; may_resubscribe = false; pending = true; id_subscription_timeout = 0; req_out = NULL; event_type = _event_type; event_id = _event_id; auto_refresh = true; subscription_expiry = 3600; default_duration = 3600; } t_subscription::~t_subscription() { if (req_out) remove_client_request(&req_out); if (id_subscription_timeout) stop_timer(STMR_SUBSCRIPTION); // Cleanup list of unsent NOTIFY messages while (!queue_notify.empty()) { t_request *r = queue_notify.front(); queue_notify.pop(); MEMMAN_DELETE(r); delete r; } } t_subscription_role t_subscription::get_role(void) const { return role; } t_subscription_state t_subscription::get_state(void) const { return state; } string t_subscription::get_reason_termination(void) const { return reason_termination; } unsigned long t_subscription::get_resubscribe_after(void) const { return resubscribe_after; } bool t_subscription::get_may_resubscribe(void) const { return may_resubscribe; } string t_subscription::get_event_type(void) const { return event_type; } string t_subscription::get_event_id(void) const { return event_id; } unsigned long t_subscription::get_expiry(void) const { return subscription_expiry; } bool t_subscription::recv_subscribe(t_request *r, t_tuid tuid, t_tid tid) { if (role != SR_NOTIFIER) { // Reject a SUBSCRIBE coming in for a SUBSCRIBER // TODO: is this ok?? log_file->write_header("t_subscription::recv_subscribe", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("SUBSCRIBER receives SUBSCRIBE.\n"); log_event(); log_file->write_endl(); log_file->write_raw(r->encode()); log_file->write_endl(); log_file->write_footer(); t_response *resp = r->create_response(R_603_DECLINE); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } // If the subscription is already in the terminated state // then a SUBSCRIBE is not allowed anymore. if (state == SS_TERMINATED) { t_response *resp = r->create_response(R_481_TRANSACTION_NOT_EXIST, REASON_481_SUBSCRIPTION_NOT_EXIST); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } if (state == SS_NULL) state = SS_ESTABLISHED; // If there is no expires header, then the implementation of // the event specific package must deal with this subscribe if (!r->hdr_expires.is_populated()) { return false; } // An expiry time of 0 is an unsubscribe if (r->hdr_expires.time == 0) { stop_timer(STMR_SUBSCRIPTION); state = SS_TERMINATED; return false; } // Check if the requested expiry is not too small if (r->hdr_expires.time < MIN_DUR_SUBSCRIPTION) { t_response *resp = r->create_response( R_423_INTERVAL_TOO_BRIEF); resp->hdr_min_expires.set_time(MIN_DUR_SUBSCRIPTION); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } // Restart subscription timer stop_timer(STMR_SUBSCRIPTION); start_timer(STMR_SUBSCRIPTION, r->hdr_expires.time * 1000); return false; } bool t_subscription::recv_notify(t_request *r, t_tuid tuid, t_tid tid) { if (role != SR_SUBSCRIBER) { // Reject a NOTIFY coming in for a NOTIFIER // TODO: is this ok?? log_file->write_header("t_subscription::recv_notify", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("NOTIFIER receives NOTIFY.\n"); log_event(); log_file->write_endl(); log_file->write_raw(r->encode()); log_file->write_endl(); log_file->write_footer(); t_response *resp = r->create_response(R_603_DECLINE); send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } if (state == SS_NULL) { log_file->write_header("t_subscription::recv_notify", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("NOTIFY establishes subscription.\n"); log_event(); log_file->write_footer(); state = SS_ESTABLISHED; } if (r->hdr_subscription_state.substate == SUBSTATE_ACTIVE && pending) { log_file->write_header("t_subscription::recv_notify", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("NOTIFY ends pending state.\n"); log_event(); log_file->write_footer(); pending = false; } if (r->hdr_subscription_state.substate == SUBSTATE_TERMINATED) { stop_timer(STMR_SUBSCRIPTION); state = SS_TERMINATED; reason_termination = r->hdr_subscription_state.reason; resubscribe_after = r->hdr_subscription_state.retry_after; // RFC 3264 3.2.4 if (resubscribe_after > 0) { may_resubscribe = true; } else { if (reason_termination == EV_REASON_DEACTIVATED || reason_termination == EV_REASON_TIMEOUT) { may_resubscribe = true; } else if (reason_termination == EV_REASON_PROBATION || reason_termination == EV_REASON_GIVEUP) { may_resubscribe = true; resubscribe_after = DUR_RESUBSCRIBE; } } log_file->write_header("t_subscription::recv_notify", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("NOTIFY terminates subscription.\n"); log_event(); log_file->write_raw("Termination reason: "); log_file->write_raw(reason_termination); log_file->write_endl(); log_file->write_raw("May resubscribe: "); log_file->write_bool(may_resubscribe); log_file->write_endl(); log_file->write_raw("Resubscribe after: "); log_file->write_raw(resubscribe_after); log_file->write_endl(); log_file->write_footer(); } if (r->hdr_subscription_state.expires > 0 && state == SS_ESTABLISHED) { log_file->write_header("t_subscription::recv_notify", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Received NOTIFY on established subscription.\n"); log_event(); log_file->write_footer(); unsigned long dur = r->hdr_subscription_state.expires; if (auto_refresh) { if (!id_subscription_timeout || timekeeper->get_remaining_time(id_subscription_timeout) >= dur * 1000) { // Adjust timer to expiry duration indicated // in NOTIFY. dur -= dur / 10; stop_timer(STMR_SUBSCRIPTION); start_timer(STMR_SUBSCRIPTION, dur * 1000); } } else { if (!id_subscription_timeout || timekeeper->get_remaining_time(id_subscription_timeout) < dur * 1000) { // Adjust timer to expiry duration indicated // in NOTIFY. dur += dur / 10; stop_timer(STMR_SUBSCRIPTION); start_timer(STMR_SUBSCRIPTION, dur * 1000); } } } return false; } bool t_subscription::recv_response(t_response *r, t_tuid tuid, t_tid tid) { switch (r->hdr_cseq.method) { case NOTIFY: return recv_notify_response(r, tuid, tid); break; case SUBSCRIBE: return recv_subscribe_response(r, tuid, tid); break; default: break; } return false; } bool t_subscription::recv_notify_response(t_response *r, t_tuid tuid, t_tid tid) { // Discard response if it does not match a pending request if (!req_out) return true; if (r->hdr_cseq.method != req_out->get_request()->method) return true; // Ignore provisional responses if (r->is_provisional()) return true; // Successful response if (r->is_success()) { if (req_out->get_request()->hdr_subscription_state.substate == SUBSTATE_TERMINATED) { // This is a 2XX respsone on a NOTIFY that terminates the // subscription. state = SS_TERMINATED; log_file->write_header("t_subscription::recv_notify_response", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Subscription terminated by 2XX NOTIFY.\n"); log_file->write_raw(r->code); log_file->write_raw(" " + r->reason + "\n"); log_event(); log_file->write_footer(); } remove_client_request(&req_out); } else { // RFC 3265 3.2.2 // NOTIFY failed, terminate subscription remove_client_request(&req_out); state = SS_TERMINATED; log_file->write_header("t_subscription::recv_notify_response", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Subscription terminated by NOTIFY failure response.\n"); log_file->write_raw(r->code); log_file->write_raw(" " + r->reason + "\n"); log_event(); log_file->write_footer(); return true; } // If there is a NOTIFY in the queue, then send it if (!queue_notify.empty()) { log_file->write_header("t_subscription::recv_notify_response", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Get NOTIFY from queue."); log_event(); log_file->write_footer(); t_request *notify = queue_notify.front(); queue_notify.pop(); req_out = new t_client_request(user_config, notify,0); MEMMAN_NEW(req_out); send_request(user_config, notify, req_out->get_tuid()); MEMMAN_DELETE(notify); delete notify; } return true; } bool t_subscription::recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid) { // Discard response if it does not match a pending request if (!req_out) return true; if (r->hdr_cseq.method != req_out->get_request()->method) return true; // Ignore provisional responses if (r->is_provisional()) return true; // Successful response if (r->is_success()) { if (state == SS_NULL) { log_file->write_header("t_subscription::recv_subscribe_response", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Subscription established by 2XX SUBSCRIBE.\n"); log_file->write_raw(r->code); log_file->write_raw(" " + r->reason + "\n"); log_event(); log_file->write_footer(); state = SS_ESTABLISHED; } // RFC 3265 7.1, 7.2 says that the Expires header is mandatory // in a 2XX response. Some SIP servers do not include this // however. To interoperate with such servers, assume that // the granted expiry time equals the requested expiry time. if (!r->hdr_expires.is_populated()) { r->hdr_expires.set_time( req_out->get_request()->hdr_expires.time); log_file->write_header( "t_subscription::recv_subscribe_response", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Mandatory Expires header missing.\n"); log_file->write_raw("Assuming expires = "); log_file->write_raw(r->hdr_expires.time); log_file->write_endl(); log_event(); log_file->write_footer(); } // If some faulty server sends a non-zero expiry time in // a response on an unsubscribe request, then ignore // the expiry time. if (r->hdr_expires.time == 0 || state == SS_UNSUBSCRIBING) { // Unsubscription succeeded. stop_timer(STMR_SUBSCRIPTION); // Start the unsubscribe guard. If the triggered // NOTIFY is never received, this guard assures, that // the subscription will be cleaned up at timeout. start_timer(STMR_SUBSCRIPTION, DUR_UNSUBSCRIBE_GUARD); // The subscription will only // terminate after a NOTIFY triggered by the unsubscribe // has been received or this guard timer expires. state = SS_UNSUBSCRIBED; auto_refresh = false; log_file->write_header("t_subscription::recv_subscribe_response", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Unsubcription succesful.\n"); log_event(); log_file->write_footer(); } else { // Start/refresh subscribe timer stop_timer(STMR_SUBSCRIPTION); unsigned long dur = r->hdr_expires.time; if (auto_refresh) { dur -= dur / 10; } else { dur += dur / 10; } start_timer(STMR_SUBSCRIPTION, dur * 1000); } remove_client_request(&req_out); return true; } // RFC 3265 3.1.4.1 // SUBSCRIBE failed, terminate subscription // NOTE: redirection and authentication responses should have // been handled already (eg. on line or phone user level). remove_client_request(&req_out); state = SS_TERMINATED; log_file->write_header("t_subscription::recv_subscribe_response", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Subscription terminated by SUBSCRIBE failure response.\n"); log_file->write_raw(r->code); log_file->write_raw(" " + r->reason + "\n"); log_event(); log_file->write_footer(); return true; } bool t_subscription::timeout(t_subscribe_timer timer) { switch (timer) { case STMR_SUBSCRIPTION: id_subscription_timeout = 0; if (role == SR_SUBSCRIBER) { log_file->write_header("t_subcription::timeout"); log_file->write_raw("Subscriber timed out.\n"); log_event(); log_file->write_footer(); if (auto_refresh) { // Refresh subscription refresh_subscribe(); } else { // The cause for timeout may be temporary. // Allow resubscription to overcome a transient problem. may_resubscribe = true; state = SS_TERMINATED; } return true; } break; default: assert(false); } return false; } bool t_subscription::match_timer(t_subscribe_timer timer, t_object_id id_timer) const { return id_timer == id_subscription_timeout; } bool t_subscription::match(t_request *r) const { if (!r->hdr_event.is_populated()) return false; // If the subscription has been terminated, then do not match // any request. if (state == SS_TERMINATED) return false; return (r->hdr_event.event_type == event_type && r->hdr_event.id == event_id); } bool t_subscription::is_pending(void) const { return pending; } void t_subscription::subscribe(unsigned long expires) { if (req_out) { // Delete previous outgoing request MEMMAN_DELETE(req_out); delete req_out; } if (expires > 0) { subscription_expiry = expires; } else { subscription_expiry = default_duration; } t_request *r = create_subscribe(subscription_expiry); req_out = new t_client_request(user_config, r ,0); MEMMAN_NEW(req_out); send_request(user_config, r, req_out->get_tuid()); MEMMAN_DELETE(r); delete r; } void t_subscription::unsubscribe(void) { if (state != SS_ESTABLISHED) { state = SS_TERMINATED; return; } if (req_out) { // Delete previous outgoing request MEMMAN_DELETE(req_out); delete req_out; } stop_timer(STMR_SUBSCRIPTION); t_request *r = create_subscribe(0); req_out = new t_client_request(user_config, r ,0); MEMMAN_NEW(req_out); send_request(user_config, r, req_out->get_tuid()); MEMMAN_DELETE(r); delete r; // NOTE: the subscription is only ended when the response is received. state = SS_UNSUBSCRIBING; } void t_subscription::refresh_subscribe(void) { if (state != SS_ESTABLISHED) return; stop_timer(STMR_SUBSCRIPTION); subscribe(subscription_expiry); } twinkle-1.4.2/src/line.h0000644000175000001440000004405611144342407012010 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _LINE_H #define _LINE_H #include #include #include "call_history.h" #include "dialog.h" #include "id_object.h" #include "phone.h" #include "protocol.h" #include "user.h" #include "audio/audio_codecs.h" #include "sockets/url.h" #include "parser/request.h" #include "parser/response.h" #include "stun/stun.h" using namespace std; // Forward declarations class t_dialog; class t_phone; // Info about the current call. // This info can be used by the user interface to render the // call state to the user. class t_call_info { public: t_url from_uri; string from_display; // Override of display for presentation to user, e.g. name from // address book lookup. string from_display_override; string from_organization; t_url to_uri; string to_display; string to_organization; string subject; bool dtmf_supported; bool dtmf_inband; // DTMF must be sent inband bool dtmf_info; // DTMF must be sent via SIP INFO t_hdr_referred_by hdr_referred_by; // The reason phrase of the last received provisional response // on an outgoing INVITE. string last_provisional_reason; t_audio_codec send_codec; t_audio_codec recv_codec; bool refer_supported; t_call_info(); void clear(void); // Get the from display name to show to the user. string get_from_display_presentation(void) const; }; class t_line : public t_id_object { friend class t_phone; private: t_line_state state; t_line_substate substate; bool is_on_hold; bool is_muted; bool hide_user; // Anonymous call // Indicates if a call is a consultation for a transfer bool is_transfer_consult; // The line about which this consultation handles. unsigned short consult_transfer_from_line; // Indicates if this call is to be transferred after consultation. bool to_be_transferred; // After consultation this line should be transferred to the // transfer_to_line. unsigned short consult_transfer_to_line; // Indicates if media encryption should be negotiated. bool try_to_encrypt; // Indicates if call must be auto answered bool auto_answer; // Line number (starting from 0) // The number of a line may change when it moves from the user lines // to the pool of dying lines. So a line number cannot be used as // unique line identification over longer times. unsigned short line_number; // The phone that owns this line t_phone *phone; // Dialog for which no response with a to-tag has been received. // Formally this is not a dialog yet. t_dialog *open_dialog; // Dialogs for which a response (1XX/2XX) with a to-tag has // been received. list pending_dialogs; // Outgoing call: The first dialog for which a 2XX has been received. // Incoming call: Dialog created by an incoming INVITE t_dialog *active_dialog; // Currently not used. list dying_dialogs; // Timers t_object_id id_invite_comp; t_object_id id_no_answer; // Call info t_call_info call_info; /** RTP port to be used for this line. */ unsigned short rtp_port; /** * Phone user using the line. * This member is only set when the line is not idle. * An idle line is not associated with a user. * @note The line object does not own the phone user. * Therefor the line object must never delete the phone user. */ t_phone_user *phone_user; // The incoming call script can return a specific ring tone // to be played for an incoming call. This ring tone is // stored here. If there is no specific ring tone to be played // then this attribute is empty string user_defined_ringtone; // Indicates if the line must go to seized state when it // becomes idle. bool keep_seized; // Find a dialog from the list that matches the response. t_dialog *match_response(t_response *r, const list &l) const; t_dialog *match_response(StunMessage *r, t_tuid tuid, const list &l) const; t_dialog *match_call_id_tags(const string &call_id, const string &to_tag, const string &from_tag, const list &l) const; // Get the dialog with id == did. If dialog does not exist // then NULL is returned. t_dialog *get_dialog(t_object_id did) const; // Clean up terminated dialogs void cleanup(void); // Cleanup all open and pending dialogs void cleanup_open_pending(void); // Forcefully cleanup all dialogs void cleanup_forced(void); // Cleanup state for a transfer with consultation. // If the call on this line is a consult, then the consult state of // the line that is to be transferred will be cleaned too. // If the call on this line is to be transferred, then the consult // state of the consultation line will be cleared too. void cleanup_transfer_consult_state(void); public: // Call history record t_call_record call_hist_record; t_line(t_phone *_phone, unsigned short _line_number); ~t_line(); t_line_state get_state(void) const; t_line_substate get_substate(void) const; t_refer_state get_refer_state(void) const; // Timer operations void start_timer(t_line_timer timer, t_object_id did = 0); void stop_timer(t_line_timer timer, t_object_id did = 0); /** @name Actions */ //@{ /** * Send INIVTE request. * @param pu The phone user making this call. * @param to_uri The URI to be used a request-URI and To header URI * @param to_display Display name for To header. * @param subject If not empty, this string will go into the Subject header. * @param hdr_referred_by The Reffered-By header to be put in the INVITE. * @param hdr_replaces The Replaces header to be put in the INVITE. * @param hdr_require Required extensions to be put in the Require header. * @param hdr_request_disposition Request-Disposition header to be put in the INVITE. * @param anonymous Inidicates if the INVITE should be sent anonymous. * * @pre The line is idle. */ void invite(t_phone_user *pu, const t_url &to_uri, const string &to_display, const string &subject, const t_hdr_referred_by &hdr_referred_by, const t_hdr_replaces &hdr_replaces, const t_hdr_require &hdr_require, const t_hdr_request_disposition &hdr_request_disposition, bool anonymous); /** * Send INIVTE request. * @param pu The phone user making this call. * @param to_uri The URI to be used a request-URI and To header URI * @param to_display Display name for To header. * @param subject If not empty, this string will go into the Subject header. * @param no_fork If true, put a no-fork request disposition in the outgoing INVITE * @param anonymous Inidicates if the INVITE should be sent anonymous. * * @pre The line is idle. */ void invite(t_phone_user *pu, const t_url &to_uri, const string &to_display, const string &subject, bool no_fork, bool anonymous); void answer(void); void reject(void); void redirect(const list &destinations, int code, string reason = ""); void end_call(void); void send_dtmf(char digit, bool inband, bool info); //@} // OPTIONS inside dialog void options(void); bool hold(bool rtponly = false); // returns false if call cannot be put on hold void retrieve(void); // Kill all RTP stream associated with this line void kill_rtp(void); void refer(const t_url &uri, const string &display); // Mute/unmute a call // - enable = true -> mute // - enable = false -> unmute void mute(bool enable); /** @name Handle incoming responses */ //@{ void recvd_provisional(t_response *r, t_tuid tuid, t_tid tid); void recvd_success(t_response *r, t_tuid tuid, t_tid tid); void recvd_redirect(t_response *r, t_tuid tuid, t_tid tid); void recvd_client_error(t_response *r, t_tuid tuid, t_tid tid); void recvd_server_error(t_response *r, t_tuid tuid, t_tid tid); void recvd_global_error(t_response *r, t_tuid tuid, t_tid tid); //@} /** @name Handle incoming requests */ //@{ void recvd_invite(t_phone_user *pu, t_request *r, t_tid tid, const string &ringtone); void recvd_ack(t_request *r, t_tid tid); void recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid); void recvd_bye(t_request *r, t_tid tid); void recvd_options(t_request *r, t_tid tid); void recvd_register(t_request *r, t_tid tid); void recvd_prack(t_request *r, t_tid tid); void recvd_subscribe(t_request *r, t_tid tid); void recvd_notify(t_request *r, t_tid tid); void recvd_info(t_request *r, t_tid tid); void recvd_message(t_request *r, t_tid tid); /** * Process REFER request. * @return true, if refer has been accepted sofar. The refer may still * be rejected by the user. * @return false, if the refer has been rejected. */ bool recvd_refer(t_request *r, t_tid tid); //@} // Handle the response from the user on the question for refer // permission. This response is received on the dialog that received // the REFER before. // The request (r) is the REFER request that was received. void recvd_refer_permission(bool permission, t_request *r); void recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid); void failure(t_failure failure, t_tid tid); void timeout(t_line_timer timer, t_object_id did); void timeout_sub(t_subscribe_timer timer, t_object_id did, const string &event_type, const string &event_id); // Return true if the response or request matches a dialog that // is owned by this line bool match(t_response *r, t_tuid tuid) const; bool match(t_request *r) const; bool match_cancel(t_request *r, t_tid target_tid) const; bool match(StunMessage *r, t_tuid tuid) const; /** * RFC 3891 Match info from Replaces header * Match call id, to-tag and from tag like an incoming request. * @param call_id [in] The Call ID of the Replaces header. * @param to_tag [in] to-tag of the Replaces header. * @param from_tag [in] from-tag of the Replaces header. * @param no_fork_req_disposition [in] Indicates if the incoming request * contains a no-fork request disposition. * @param early_matched [out] When a match is found, early_matched * indicates if the match was on an early dialog. * @return true if a match is found with an associated dialog. */ bool match_replaces(const string &call_id, const string &to_tag, const string &from_tag, bool no_fork_req_disposition, bool &early_matched) const; // Check if an incoming INVITE is a retransmission of an INVITE // that is already being processed by this line bool is_invite_retrans(t_request *r); // Process a retransmission of an incoming INVITE void process_invite_retrans(void); // Create user uri and contact uri string create_user_contact(const string &auto_ip) const; string create_user_uri(void) const; // Create a response to an OPTIONS request // Argument 'in-dialog' indicates if the OPTIONS response is // sent within a dialog. t_response *create_options_response(t_request *r, bool in_dialog = false) const; // Send a response/request void send_response(t_response *r, t_tuid tuid, t_tid tid); void send_request(t_request *r, t_tuid tuid); t_phone *get_phone(void) const; unsigned short get_line_number(void) const; bool get_is_on_hold(void) const; bool get_is_muted(void) const; bool get_hide_user(void) const; // If this is a transfer consult, then true will be returned and // lineno will be set to the line that must be transferred. bool get_is_transfer_consult(unsigned short &lineno) const; // When setting the transfer consult indication to true, the // line that must be transferred must be passed. void set_is_transfer_consult(bool enable, unsigned short lineno); // If this line is to be transferred after consultation, then // true will be returned and lineno will be set to the line // where this line should be transferred to. bool get_to_be_transferred(unsigned short &lineno) const; // When setting the to be transferred indication to true, the // line to which must be transferred must be passed. void set_to_be_transferred(bool enable, unsigned short lineno); bool get_is_encrypted(void) const; bool get_try_to_encrypt(void) const; bool get_auto_answer(void) const; void set_auto_answer(bool enable); bool is_refer_succeeded(void) const; bool has_media(void) const; /** @name Remote (target) uri/display */ //@{ /** * Get the remote target URI of the active dialog. * @return Remote target URI. If there is no active dialog, then an * empty URI is returned. */ t_url get_remote_target_uri(void) const; /** * Get the remote target URI of the first pending dialog. * @return Remote target URI. If there is no pending dialog, then an * empty URI is returned. */ t_url get_remote_target_uri_pending(void) const; /** * Get the remote target display name of the active dialog. * @return Remote target display name. If there is no active dialog, * then an empty string is returned. */ string get_remote_target_display(void) const; /** * Get the remote target display name of the first pending dialog. * @return Remote target display name. If there is no pending dialog, * then an empty string is returned. */ string get_remote_target_display_pending(void) const; /** * Get the remote URI of the active dialog. * @return Remote URI. If there is no active dialog, then an * empty URI is returned. */ t_url get_remote_uri(void) const; /** * Get the remote URI of the first pending dialog. * @return Remote URI. If there is no pending dialog, then an * empty URI is returned. */ t_url get_remote_uri_pending(void) const; /** * Get the remote display name of the active dialog. * @return Remote display name. If there is no active dialog, * then an empty string is returned. */ string get_remote_display(void) const; /** * Get the remote display name of the first pending dialog. * @return Remote display name. If there is no pending dialog, * then an empty string is returned. */ string get_remote_display_pending(void) const; //@} /** @name Call identification */ //@{ /** * Get the call-id of the active dialog * @return If there is no active dialog, then an empty string is returned. */ string get_call_id(void) const; /** * Get the call-id of the first pending dialog * @return If there is no pending dialog, then an empty string is returned. */ string get_call_id_pending(void) const; /** * Get the local tag of the active dialog * @return If there is no active dialog, then an empty string is returned. */ string get_local_tag(void) const; /** * Get the local tag of the first pending dialog * @return If there is no pending dialog, then an empty string is returned. */ string get_local_tag_pending(void) const; /** * Get the remote tag of the active dialog * @return If there is no active dialog, then an empty string is returned. */ string get_remote_tag(void) const; /** * Get the remote tag of the first pending dialog * @return If there is no pending dialog, then an empty string is returned. */ string get_remote_tag_pending(void) const; //@} // Returns true if the remote party of the active dialog supports // the extension. // If there is no active dialog, then false is returned. bool remote_extension_supported(const string &extension) const; // Seize the line. User wants to make an outgoing call, so // the line must be marked as busy, such that an incoming call // cannot take this line. // Returns false if seizure failed bool seize(void); // Unseize the line void unseize(void); // Return the (audio) session belonging to this line. // Returns NULL if there is no (audio) session t_session *get_session(void) const; t_audio_session *get_audio_session(void) const; void notify_refer_progress(t_response *r); // Called by dialog if retrieve/hold actions failed. void failed_retrieve(void); void failed_hold(void); // Called by dialog if retry of a retrieve after a glare (491 response) // succeeded. void retry_retrieve_succeeded(void); // Get the call info record t_call_info get_call_info(void) const; void ci_set_dtmf_supported(bool supported, bool inband = false, bool info = false); void ci_set_last_provisional_reason(const string &reason); void ci_set_send_codec(t_audio_codec codec); void ci_set_recv_codec(t_audio_codec codec); void ci_set_refer_supported(bool supported); // Initialize the RTP port for this line based on the settings // in the user profile. void init_rtp_port(void); /** Get the RTP port to be used for a call on this line. */ unsigned short get_rtp_port(void) const; /** * Get the user profile of the user using the phone. * @return a pointer to the user object owned by the line. * NOT a copy. */ t_user *get_user(void) const; /** * Get the phone user using the phone. * @return Pointer to the phone user. */ t_phone_user *get_phone_user(void) const; // Get the ring tone to be played for an incoming call string get_ringtone(void) const; // ZRTP actions void confirm_zrtp_sas(void); void reset_zrtp_sas_confirmation(void); void enable_zrtp(void); void zrtp_request_go_clear(void); void zrtp_go_clear_ok(void); // Force a line to the idle state (during termination of Twinkle) void force_idle(void); // Indicate if the line must be seized after releasing void set_keep_seized(bool seize); bool get_keep_seized(void) const; /** * Get a dialog that has an active session (RTP stream). * @return The dialog that has an active session. * @return NULL, if there is no dialog with an active session. * @note There can be at most 1 dialog with an active session. */ t_dialog *get_dialog_with_active_session(void) const; }; #endif twinkle-1.4.2/src/events.h0000644000175000001440000005304411127714050012360 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Threads communicate by passing events via event queues. */ #ifndef _EVENTS_H #define _EVENTS_H #include #include "protocol.h" #include "timekeeper.h" #include "stun/stun.h" #include "audio/audio_codecs.h" #include "parser/sip_message.h" #include "sockets/socket.h" #include "sockets/url.h" #include "threads/mutex.h" #include "threads/sema.h" using namespace std; // Forward declarations class t_userintf; /** Different types of events. */ enum t_event_type { EV_QUIT, /**< Generic quit event */ EV_NETWORK, /**< Network event, eg. SIP message from/to network */ EV_USER, /**< User event, eg. SIP message from/to user */ EV_TIMEOUT, /**< Timer expiry */ EV_FAILURE, /**< Failure, eg. transport failure */ EV_START_TIMER, /**< Start timer */ EV_STOP_TIMER, /**< Stop timer */ EV_ABORT_TRANS, /**< Abort transaction */ EV_STUN_REQUEST, /**< Outgoing STUN request */ EV_STUN_RESPONSE, /**< Received STUN response */ EV_NAT_KEEPALIVE, /**< Send a NAT keep alive packet */ EV_ICMP, /**< ICMP error */ EV_UI, /**< User interface event */ EV_ASYNC_RESPONSE, /**< Response on an asynchronous question */ EV_BROKEN_CONNECTION, /**< Persitent connection to SIP proxy broken */ EV_TCP_PING, /**< Send a TCP ping (double CRLF) */ }; /** Abstract parent class for all events */ class t_event { public: virtual ~t_event() {} /** Get the type of this event. */ virtual t_event_type get_type(void) const = 0; }; /** * Generic quit event. * The quit event instructs a thread to exit gracefully. */ class t_event_quit : public t_event { public: virtual ~t_event_quit(); virtual t_event_type get_type(void) const; }; /** * Network events. * A network event is a SIP message going from the transaction manager * to the network or v.v. */ class t_event_network : public t_event { private: /** The SIP message. */ t_sip_message *msg; public: unsigned int src_addr; /**< Source IP address of the SIP message (host order). */ unsigned short src_port; /**< Source port of the SIP message (host order). */ unsigned int dst_addr; /**< Destination IP address of the SIP message (host order). */ unsigned short dst_port; /**< Destination port of the SIP message (host order). */ string transport; /**< Transport protocol */ /** * Constructor. * The event will keep a copy of the SIP message. * @param m [in] The SIP message. */ t_event_network(t_sip_message *m); ~t_event_network(); t_event_type get_type(void) const; /** * Get the SIP message. * @return Pointer to the SIP message inside this event. */ t_sip_message *get_msg(void) const; }; /** * User events. * A user event is a SIP message going from the user to the * transaction manager or v.v. */ class t_event_user : public t_event { private: t_sip_message *msg; /**< The SIP message. */ unsigned short tuid; /**< Transaction user id. */ unsigned short tid; /**< Transaction id. */ /** * Transaction id that is the target of the CANCEL message. * Only set if tid is a CANCEL transaction and the event * is sent towards the user. */ unsigned short tid_cancel_target; /** User profile of the user sending/receiving the SIP message. */ t_user *user_config; public: /** Constructor. * @param u [in] User profile. * @param m [in] SIP message * @param _tuid [in] Transaction user id associated with this message. * @param _tid [in] Transaction id of the transaction for this message. */ t_event_user(t_user *u, t_sip_message *m, unsigned short _tuid, unsigned short _tid); /** Constructor for CANCEL request towards the user. * @param u [in] User profile. * @param m [in] SIP message. * @param _tuid [in] Transaction user id associated with this message. * @param _tid [in] Transaction id of the transaction for this message. * @param _tid_cancel_target [in] Id of the target transaction of a CANCEL request. */ t_event_user(t_user *u, t_sip_message *m, unsigned short _tuid, unsigned short _tid, unsigned short _tid_cancel_target); ~t_event_user(); t_event_type get_type(void) const; /** * Get the SIP message. * @return Pointer to the SIP message inside this event. */ t_sip_message *get_msg(void) const; /** Get transaction user id. */ unsigned short get_tuid(void) const; /** Get transaction id. */ unsigned short get_tid(void) const; /** Get the CANCEL target transaction id. */ unsigned short get_tid_cancel_target(void) const; /** * Get the user profile. * @return Pointer to the user profile inside the event. */ t_user *get_user_config(void) const; }; /** * Time out events. * Expiration of a timer is signalled by a time out event. */ class t_event_timeout : public t_event { private: /** * The epxired timer. * @note Timer pointer will be deleted upon destruction of the object. */ t_timer *timer; public: /** * Constructor. * @param t [in] The expired timer. * @note The event will keep a copy of the timer. */ t_event_timeout(t_timer *t); ~t_event_timeout(); t_event_type get_type(void) const; /** * Get the timer from the event. * @return The timer. */ t_timer *get_timer(void) const; }; /** * Failure events. */ class t_event_failure : public t_event { private: t_failure failure; /**< Type of failure. */ /** * Indicates if the tid value is populated. If the tid value is not * populated, then the branch and cseq_method are populated. */ bool tid_populated; unsigned short tid; /**< Id of transaction that failed. */ string branch; /**< Branch parameter of SIP message that failed. */ t_method cseq_method; /**< CSeq method of SIP message that failed. */ public: /** * Constructor. * @param f [in] Type of failure. * @param _tid [in] Transaction id. */ t_event_failure(t_failure f, unsigned short _tid); /** Constructor */ t_event_failure(t_failure f, const string &_branch, const t_method &_cseq_method); t_event_type get_type(void) const; /** * Get the type of failure. * @return Type of failure. */ t_failure get_failure(void) const; /** * Get the transaction id. * @return Transaction id. */ unsigned short get_tid(void) const; /** Get branch parameter. */ string get_branch(void) const; /** Get CSeq method. */ t_method get_cseq_method(void) const; /** Check if tid is populated. */ bool is_tid_populated(void) const; }; /** * Start timer event. * A start timer event instructs the time keeper to start a timer. */ class t_event_start_timer : public t_event { private: t_timer *timer; /**< The timer to start. */ public: /** * Constructor. * @param t [in] The timer to start. */ t_event_start_timer(t_timer *t); t_event_type get_type(void) const; /** * Get the timer. * @return Timer. */ t_timer *get_timer(void) const; }; /** * Stop timer event * A stop timer event instructs the time keeper to stop a timer. */ class t_event_stop_timer : public t_event { private: /** Id of the timer to stop. */ unsigned short timer_id; public: /** * Constructor. * @param id [in] Id of the timer to stop. */ t_event_stop_timer(unsigned short id); t_event_type get_type(void) const; /** * Get the timer id. * @return Timer id. */ unsigned short get_timer_id(void) const; }; /** * Abort transaction event. * With an abort transaction event, the requester asks the transaction * manager to abort a pending transaction. */ class t_event_abort_trans : public t_event { private: unsigned short tid; /**< Id of the transaction to abort. */ public: /** * Constructor. * @param _tid [in] Transaction id. */ t_event_abort_trans(unsigned short _tid); t_event_type get_type(void) const; /** * Get transaction id. * @return Transaction id. */ unsigned short get_tid(void) const; }; /** STUN event types. */ enum t_stun_event_type { TYPE_STUN_SIP, /**< Request to open a port for SIP. */ TYPE_STUN_MEDIA, /**< Request to open a port for media. */ }; /** * STUN request event. */ class t_event_stun_request : public t_event { private: StunMessage *msg; /**< STUN request to send. */ unsigned short tuid; /**< Transaction user id. */ unsigned short tid; /**< Transaction id. */ t_stun_event_type stun_event_type; /**< Type of STUN event. */ t_user *user_config; /**< User profile associated with this request. */ public: unsigned int dst_addr; /**< Destination address of request (host order). */ unsigned short dst_port; /**< Destination port of request (host order). */ unsigned short src_port; /**< Source port for media event type (host order). */ /** Constructor. */ t_event_stun_request(t_user *u, StunMessage *m, t_stun_event_type ev_type, unsigned short _tuid, unsigned short _tid); ~t_event_stun_request(); t_event_type get_type(void) const; /** Get STUN message. */ StunMessage *get_msg(void) const; /** Get transaction user id. */ unsigned short get_tuid(void) const; /** Get transaction id. */ unsigned short get_tid(void) const; /** Get STUN event type. */ t_stun_event_type get_stun_event_type(void) const; /** Get user profile. */ t_user *get_user_config(void) const; }; /** * STUN response event. */ class t_event_stun_response : public t_event { private: StunMessage *msg; /**< STUN request to send. */ unsigned short tuid; /**< Transaction user id. */ unsigned short tid; /**< Transaction id. */ public: /** Constructor. */ t_event_stun_response(StunMessage *m, unsigned short _tuid, unsigned short _tid); ~t_event_stun_response(); t_event_type get_type(void) const; /** Get STUN message. */ StunMessage *get_msg(void) const; /** Get transaction user id. */ unsigned short get_tuid(void) const; /** Get transaction id. */ unsigned short get_tid(void) const; }; /** * NAT keep alive event. * Request to send a NAT keep alive message. */ class t_event_nat_keepalive : public t_event { public: unsigned int dst_addr; /**< Destination address for keepalive (host order) */ unsigned short dst_port; /**< Destination port (host order) */ t_event_type get_type(void) const; }; /** * ICMP event. * This event signals the reception of an ICMP error. */ class t_event_icmp : public t_event { private: t_icmp_msg icmp; /**< The received ICMP message. */ public: /** * Constructor. * @param m [in] ICMP message. */ t_event_icmp(const t_icmp_msg &m); t_event_type get_type(void) const; /** * Get the ICMP message. * @return ICMP message. */ t_icmp_msg get_icmp(void) const; }; /** User interface callback types. */ enum t_ui_event_type { TYPE_UI_CB_DISPLAY_MSG, /**< Display a message */ TYPE_UI_CB_DTMF_DETECTED, /**< DTMF tone detected */ TYPE_UI_CB_SEND_DTMF, /**< Sending DTMF */ TYPE_UI_CB_RECV_CODEC_CHANGED, /**< Codec changed */ TYPE_UI_CB_LINE_STATE_CHANGED, /**< Line state changed */ TYPE_UI_CB_LINE_ENCRYPTED, /**< Line is now encrypted */ TYPE_UI_CB_SHOW_ZRTP_SAS, /**< Show the ZRTP SAS */ TYPE_UI_CB_ZRTP_CONFIRM_GO_CLEAR, /**< ZRTP Confirm go-clear */ TYPE_UI_CB_QUIT /**< Quit the user interface */ }; /** Display message priorities. */ enum t_msg_priority { MSG_NO_PRIO, MSG_INFO, MSG_WARNING, MSG_CRITICAL }; /** * User interface event. * Send a user interface callback to the user interface. * Most callbacks are called directly as a function call. * Sometimes an asynchronous callback is needed. That's where * this event is used for. */ class t_event_ui : public t_event { private: t_ui_event_type type; /**< User interface callback type. */ /** @name Parameters for call back functions */ //@{ int line; /**< Line number. */ t_audio_codec codec; /**< Audio codec. */ char dtmf_event; /**< DTMF event. */ bool encrypted; /**< Encryption indication. */ string cipher_mode; /**< Cipher mode (algorithm name). */ string zrtp_sas; /**< ZRTP SAS/ */ t_msg_priority msg_priority; /**< Priority of a display message. */ string msg; /**> Message to display. */ //@} public: /** * Constructor. * @param _type [in] Type of callback. */ t_event_ui(t_ui_event_type _type); t_event_type get_type(void) const; /** @name Set parameters for call back functions */ //@{ void set_line(int _line); void set_codec(t_audio_codec _codec); void set_dtmf_event(char _dtmf_event); void set_encrypted(bool on); void set_cipher_mode(const string &_cipher_mode); void set_zrtp_sas(const string &sas); void set_display_msg(const string &_msg, t_msg_priority &_msg_priority); //@} /** * Call the callback function. * @param user_intf [in] The user interface that receives the callback. */ void exec(t_userintf *user_intf); }; /** * Asynchronous response event. * A user interface can open an asynchronous message box to request * information from the user. Via this event the user interface signals * the response from the user. */ class t_event_async_response : public t_event { public: /** Response type */ enum t_response_type { RESP_REFER_PERMISSION /**< Response on permission to refer question */ }; private: t_response_type response_type; /**< Response type. */ bool bool_response; /**< Boolean response. */ public: /** * Constructor. * @param type [in] The response type. */ t_event_async_response(t_response_type type); t_event_type get_type(void) const; /** * Set the boolean response. * @param b [in] The response. */ void set_bool_response(bool b); /** * Get response type. * @return Response type. */ t_response_type get_response_type(void) const; /** * Get boolean response. * @return The response. */ bool get_bool_response(void) const; }; /** * Broken connection event. * A persistent connection to a SIP proxy is broken. With this event * the transport layer signals the transaction layer that a connection * is broken. */ class t_event_broken_connection : public t_event { private: /** The user URI (AoR) that the connection was associated with. */ t_url user_uri_; public: /** Constructor */ t_event_broken_connection(const t_url &url); t_event_type get_type(void) const; /** * Get the user URI. * @return The user URI. */ t_url get_user_uri(void) const; }; /** * TCP ping event. * Send a TCP ping (double CRLF). */ class t_event_tcp_ping : public t_event { private: /** The user URI (AoR) for which the ping must be sent. */ t_url user_uri_; unsigned int dst_addr_; /**< Destination address for ping (host order) */ unsigned short dst_port_; /**< Destination port (host order) */ public: /** Constructor */ t_event_tcp_ping(const t_url &url, unsigned int dst_addr, unsigned short dst_port); t_event_type get_type(void) const; /** @name Getters */ //@{ t_url get_user_uri(void) const; unsigned int get_dst_addr(void) const; unsigned short get_dst_port(void) const; //@} }; /** * Event queue. * An event queue is the communication pipe between multiple * threads. Multiple threads write events into the queue and * one thread reads the events from the queue and processes them * Access to the queue is protected by a mutex. A semaphore is * used to synchronize the reader with the writers of the queue. */ class t_event_queue { private: queue ev_queue; /**< Queue of events. */ t_mutex mutex_evq; /**< Mutex to protect access to the queue. */ t_semaphore sema_evq; /**< Semephore counting the number of events. */ /** * Semaphore to signal an interrupt. * Will be posted when the interrupt method is called. */ t_semaphore sema_caught_interrupt; public: /** Constructor. */ t_event_queue(); ~t_event_queue(); /** * Push an event into the queue. * @param e [in] Event */ void push(t_event *e); /** Push a quit event into the queue. */ void push_quit(void); /** * Create a network event and push it into the queue. * @param m [in] SIP message. * @param ipaddr [in] Destination address of the message (host order). * @param port [in] Port of the message (host order). */ void push_network(t_sip_message *m, const t_ip_port &ip_port); /** * Create a user event and push it into the queue. * The user event must be associated with a user profile. * @param user_config [in] The user profile. * @param m [in] SIP message. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void push_user(t_user *user_config, t_sip_message *m, unsigned short tuid, unsigned short tid); /** * Create a user event and push it into the queue. * The user event must be unrelated to a particular user profile. * @param m [in] SIP message. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void push_user(t_sip_message *m, unsigned short tuid, unsigned short tid); /** * Create a cancel event for a user. * @param user_config [in] The user profile. * @param m [in] SIP message. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void push_user_cancel(t_user *user_config, t_sip_message *m, unsigned short tuid, unsigned short tid, unsigned short target_tid); /** * Create a cancel event for a user. * @param m [in] SIP message. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void push_user_cancel(t_sip_message *m, unsigned short tuid, unsigned short tid, unsigned short target_tid); /** * Create a timeout event and push it into the queue. * @param t [in] The timer that expired. */ void push_timeout(t_timer *t); /** * Create failure event and push it into the queue. * @param f [in] Type of failure. * @param tid [in] Transaction id of failed transaction. */ void push_failure(t_failure f, unsigned short tid); /** * Create failure event and push it into the queue. * @param f [in] Type of failure. * @param branch [in] Branch parameter of failed transaction. * @param cseq_method [in] CSeq method of failed transaction. */ void push_failure(t_failure f, const string &branch, const t_method &cseq_method); /** * Create a start timer event. * @param t [in] Timer to start. */ void push_start_timer(t_timer *t); /** * Create a stop timer event. * @param timer_id [in] Timer id of timer to stop. */ void push_stop_timer(unsigned short timer_id); /** * Create an abort transaction event. * @param tid [in] Transaction id of transaction to abort. */ void push_abort_trans(unsigned short tid); /** * Create a STUN request event. * @param user_config [in] The user profile associated with the request. * @param m [in] STUN request. * @param ev_type [in] Type of STUN event. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @param ipaddr [in] Destination address (host order) * @param port [in] Destination port (host order) * @param src_port [in] Source port of media. This must only be passed for * a media STUN event. */ void push_stun_request(t_user *user_config, StunMessage *m, t_stun_event_type ev_type, unsigned short tuid, unsigned short tid, unsigned long ipaddr, unsigned short port, unsigned short src_port = 0); /** * Create a STUN response event. * @param m [in] STUN response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void push_stun_response(StunMessage *m, unsigned short tuid, unsigned short tid); /** * Create a NAT keepalive event. * @param ipaddr [in] Destination address (host order) * @param port [in] Destination port (host order) */ void push_nat_keepalive(unsigned long ipaddr, unsigned short port); /** * Create ICMP event. * @param m [in] ICMP message. */ void push_icmp(const t_icmp_msg &m); /** * Create a REFER pemission response event. * @param permission [in] Permission allowed?. */ void push_refer_permission_response(bool permission); /** * Create a broken connection event. * @param user_uri [in] The user URI (AoR) associated with the connection. */ void push_broken_connection(const t_url &user_uri); /** * Create a TCP ping event. * @param user_uri [in] The user URI (AoR) for which the TCP ping must be sent. * @param dst_addr [in] The destination IPv4 address for the ping. * @param dst_port [in] The destination TCP port for the ping. */ void push_tcp_ping(const t_url &user_uri, unsigned int dst_addr, unsigned short dst_port); /** * Pop an event from the queue. * If the queue is empty then the thread will be blocked until an * event arrives. * @return The popped event. */ t_event *pop(void); /** * Pop an event from the queue. * Same method as above, but this one can be interrupted by * calling the method interrupt. * @param interrupted [out] When the pop operation is interrupted this * parameter is set to true. Otherwise it is false. * @return NULL, when interrupted. * @return The popped event, otherwise. */ t_event *pop(bool &interrupted); /** * Send an interrupt. * This will cause the interruptable pop to return. * A non-interruptable pop will ignore the interrupt. * If pop is currently not suspending the thread execution then the * next call to pop will catch the interrupt. */ void interrupt(void); }; #endif twinkle-1.4.2/src/timekeeper.cpp0000644000175000001440000004451511134640206013543 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "events.h" #include "line.h" #include "log.h" #include "phone.h" #include "subscription.h" #include "timekeeper.h" #include "transaction_mgr.h" #include "threads/thread.h" #include "audits/memman.h" extern t_phone *phone; extern t_event_queue *evq_trans_layer; extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_timekeeper; extern t_timekeeper *timekeeper; extern bool threading_is_LinuxThreads; string timer_type2str(t_timer_type t) { switch(t) { case TMR_TRANSACTION: return "TMR_TRANSACTION"; case TMR_PHONE: return "TMR_PHONE"; case TMR_LINE: return "TMR_LINE"; case TMR_SUBSCRIBE: return "TMR_SUBSCRIBE"; case TMR_PUBLISH: return "TMR_PUBLISH"; case TMR_STUN_TRANSACTION: return "TMR_STUN_TRANSACTION"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_timer /////////////////////////////////////////////////////////// t_timer::t_timer(long dur) : t_id_object() { long d = dur; // HACK: if a timer is set to zero seconds, set it to 1 ms, otherwise // the timer will not expire. if (dur == 0) d++; duration = d; relative_duration = d; } long t_timer::get_duration(void) const { return duration; } long t_timer::get_relative_duration(void) const { return relative_duration; } void t_timer::set_relative_duration(long d) { relative_duration = d; } /////////////////////////////////////////////////////////// // class t_tmr_transaction /////////////////////////////////////////////////////////// t_tmr_transaction::t_tmr_transaction(long dur, t_sip_timer tmr, unsigned short tid) : t_timer(dur) { sip_timer = tmr; transaction_id = tid; } void t_tmr_transaction::expired(void) { // Create a timeout event for the transaction manager evq_trans_mgr->push_timeout(this); } t_timer *t_tmr_transaction::copy(void) const { t_tmr_transaction *t = new t_tmr_transaction(*this); MEMMAN_NEW(t); return t; } t_timer_type t_tmr_transaction::get_type(void) const { return TMR_TRANSACTION; } unsigned short t_tmr_transaction::get_tid(void) const { return transaction_id; } t_sip_timer t_tmr_transaction::get_sip_timer(void) const { return sip_timer; } string t_tmr_transaction::get_name(void) const { switch(sip_timer) { case TIMER_T1: return "TIMER_T1"; case TIMER_T2: return "TIMER_T2"; case TIMER_T4: return "TIMER_T4"; case TIMER_A: return "TIMER_A"; case TIMER_B: return "TIMER_B"; case TIMER_C: return "TIMER_C"; case TIMER_D: return "TIMER_D"; case TIMER_E: return "TIMER_E"; case TIMER_F: return "TIMER_F"; case TIMER_G: return "TIMER_G"; case TIMER_H: return "TIMER_H"; case TIMER_I: return "TIMER_I"; case TIMER_J: return "TIMER_J"; case TIMER_K: return "TIMER_K"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_tmr_phone /////////////////////////////////////////////////////////// t_tmr_phone::t_tmr_phone(long dur, t_phone_timer ptmr, t_phone *p) : t_timer(dur) { phone_timer = ptmr; the_phone = p; } void t_tmr_phone::expired(void) { evq_trans_layer->push_timeout(this); } t_timer *t_tmr_phone::copy(void) const { t_tmr_phone *t = new t_tmr_phone(*this); MEMMAN_NEW(t); return t; } t_timer_type t_tmr_phone::get_type(void) const { return TMR_PHONE; } t_phone_timer t_tmr_phone::get_phone_timer(void) const { return phone_timer; } t_phone *t_tmr_phone::get_phone(void) const { return the_phone; } string t_tmr_phone::get_name(void) const { switch(phone_timer) { case PTMR_REGISTRATION: return "PTMR_REGISTRATION"; case PTMR_NAT_KEEPALIVE: return "PTMR_NAT_KEEPALIVE"; case PTMR_TCP_PING: return "PTMR_TCP_PING"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_tmr_line /////////////////////////////////////////////////////////// t_tmr_line::t_tmr_line(long dur, t_line_timer ltmr, t_object_id lid, t_object_id d) : t_timer(dur) { line_timer = ltmr; line_id = lid; dialog_id = d; } void t_tmr_line::expired(void) { evq_trans_layer->push_timeout(this); } t_timer *t_tmr_line::copy(void) const { t_tmr_line *t = new t_tmr_line(*this); MEMMAN_NEW(t); return t; } t_timer_type t_tmr_line::get_type(void) const { return TMR_LINE; } t_line_timer t_tmr_line::get_line_timer(void) const { return line_timer; } t_object_id t_tmr_line::get_line_id(void) const { return line_id; } t_object_id t_tmr_line::get_dialog_id(void) const { return dialog_id; } string t_tmr_line::get_name(void) const { switch(line_timer) { case LTMR_ACK_TIMEOUT: return "LTMR_ACK_TIMEOUT"; case LTMR_ACK_GUARD: return "LTMR_ACK_GUARD"; case LTMR_INVITE_COMP: return "LTMR_INVITE_COMP"; case LTMR_NO_ANSWER: return "LTMR_NO_ANSWER"; case LTMR_RE_INVITE_GUARD: return "LTMR_RE_INVITE_GUARD"; case LTMR_100REL_TIMEOUT: return "LTMR_100REL_TIMEOUT"; case LTMR_100REL_GUARD: return "LTMR_100REL_GUARD"; case LTMR_CANCEL_GUARD: return "LTMR_CANCEL_GUARD"; case LTMR_GLARE_RETRY: return "LTMR_GLARE_RETRY"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_tmr_subscribe /////////////////////////////////////////////////////////// t_tmr_subscribe::t_tmr_subscribe(long dur, t_subscribe_timer stmr, t_object_id lid, t_object_id d, const string &event_type, const string &event_id) : t_timer(dur) { subscribe_timer = stmr; line_id = lid; dialog_id = d; sub_event_type = event_type; sub_event_id = event_id; } void t_tmr_subscribe::expired(void) { evq_trans_layer->push_timeout(this); } t_timer *t_tmr_subscribe::copy(void) const { t_tmr_subscribe *t = new t_tmr_subscribe(*this); MEMMAN_NEW(t); return t; } t_timer_type t_tmr_subscribe::get_type(void) const { return TMR_SUBSCRIBE; } t_subscribe_timer t_tmr_subscribe::get_subscribe_timer(void) const { return subscribe_timer; } t_object_id t_tmr_subscribe::get_line_id(void) const { return line_id; } t_object_id t_tmr_subscribe::get_dialog_id(void) const { return dialog_id; } string t_tmr_subscribe::get_sub_event_type(void) const { return sub_event_type; } string t_tmr_subscribe::get_sub_event_id(void) const { return sub_event_id; } string t_tmr_subscribe::get_name(void) const { switch(subscribe_timer) { case STMR_SUBSCRIPTION: return "STMR_SUBSCRIPTION"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_tmr_publish /////////////////////////////////////////////////////////// t_tmr_publish::t_tmr_publish(long dur, t_publish_timer ptmr, const string &_event_type) : t_timer(dur), publish_timer(ptmr), event_type(_event_type) {} void t_tmr_publish::expired(void) { evq_trans_layer->push_timeout(this); } t_timer *t_tmr_publish::copy(void) const { t_tmr_publish *t = new t_tmr_publish(*this); MEMMAN_NEW(t); return t; } t_timer_type t_tmr_publish::get_type(void) const { return TMR_PUBLISH; } t_publish_timer t_tmr_publish::get_publish_timer(void) const { return publish_timer; } string t_tmr_publish::get_name(void) const { switch (publish_timer) { case PUBLISH_TMR_PUBLICATION: return "PUBLISH_TMR_PUBLICATION"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_tmr_stun_trans /////////////////////////////////////////////////////////// t_tmr_stun_trans::t_tmr_stun_trans(long dur, t_stun_timer tmr, unsigned short tid) : t_timer(dur) { stun_timer = tmr; transaction_id = tid; } void t_tmr_stun_trans::expired(void) { // Create a timeout event for the transaction manager evq_trans_mgr->push_timeout(this); } t_timer *t_tmr_stun_trans::copy(void) const { t_tmr_stun_trans *t = new t_tmr_stun_trans(*this); MEMMAN_NEW(t); return t; } t_timer_type t_tmr_stun_trans::get_type(void) const { return TMR_STUN_TRANSACTION; } unsigned short t_tmr_stun_trans::get_tid(void) const { return transaction_id; } t_stun_timer t_tmr_stun_trans::get_stun_timer(void) const { return stun_timer; } string t_tmr_stun_trans::get_name(void) const { switch(stun_timer) { case STUN_TMR_REQ_TIMEOUT: return "STUN_TMR_REQ_TIMEOUT"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_timekeeper /////////////////////////////////////////////////////////// t_timekeeper::t_timekeeper() : mutex() { stopped = false; timer_expired = false; } void t_timekeeper::start(void (*timeout_handler)(int)) { signal(SIGALRM, timeout_handler); } t_timekeeper::~t_timekeeper() { struct itimerval itimer; mutex.lock(); log_file->write_header("t_timekeeper::~t_timekeeper", LOG_NORMAL, LOG_INFO); log_file->write_raw("Clean up timekeeper.\n"); // Stop timers itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, NULL); for (list::iterator i = timer_list.begin(); i != timer_list.end(); i++) { log_file->write_raw("\nDeleting timer:\n"); log_file->write_raw("Id: "); log_file->write_raw((*i)->get_object_id()); log_file->write_raw(", Type: "); log_file->write_raw(timer_type2str((*i)->get_type())); log_file->write_raw(", Timer: "); log_file->write_raw((*i)->get_name()); log_file->write_raw("\nDuration: "); log_file->write_raw((*i)->get_duration()); log_file->write_raw(", Relative duration: "); log_file->write_raw((*i)->get_relative_duration()); log_file->write_endl(); if ((*i)->get_type() == TMR_TRANSACTION) { log_file->write_raw("Transaction id: "); log_file->write_raw( ((t_tmr_transaction *)(*i))->get_tid()); log_file->write_endl(); } MEMMAN_DELETE(*i); delete *i; } if (threading_is_LinuxThreads) { signal(SIGALRM, SIG_DFL); } log_file->write_footer(); mutex.unlock(); } void t_timekeeper::lock(void) { mutex.lock(); } void t_timekeeper::unlock(void) { mutex.unlock(); if (timer_expired) { timer_expired = false; report_expiry(); } } void t_timekeeper::start_timer(t_timer *t) { struct itimerval itimer; long remain_msec; lock(); // The next interval option is not used itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; // Get duration of the timer to start long d = t->get_relative_duration(); // If no timer is currently running then simply start the timer if (timer_list.empty()) { timer_list.push_back(t); itimer.it_value.tv_sec = d / 1000; itimer.it_value.tv_usec = (d % 1000) * 1000; setitimer(ITIMER_REAL, &itimer, NULL); unlock(); return; } // Get remaining duration of current running timer getitimer(ITIMER_REAL, &itimer); remain_msec = itimer.it_value.tv_sec * 1000 + itimer.it_value.tv_usec / 1000; // If the new timer is shorter than the current timer. // then the new timer should be run first. if (d < remain_msec) { // Change running timer to new timer itimer.it_value.tv_sec = d / 1000; itimer.it_value.tv_usec = (d % 1000) * 1000; setitimer(ITIMER_REAL, &itimer, NULL); // Calculate the relative duration the timer // that was running. t_timer *old_timer = timer_list.front(); old_timer->set_relative_duration(remain_msec - d); // Add new timer at the front of the list timer_list.push_front(t); unlock(); return; } // Calculate the relative duration for the new timer long new_duration = d - remain_msec; // Insert the new timer at the right position in the list. list::iterator i; for (i = timer_list.begin(); i != timer_list.end(); i++) { // skip the first timer if (i == timer_list.begin()) continue; long dur = (*i)->get_relative_duration(); if (new_duration < dur) { // Adjust relative duration existing timer (*i)->set_relative_duration(dur - new_duration); // Insert new timer before existing timer t->set_relative_duration(new_duration); timer_list.insert(i, t); unlock(); return; } new_duration -= dur; } // Add the new timer to the end of the list t->set_relative_duration(new_duration); timer_list.push_back(t); unlock(); } void t_timekeeper::stop_timer(t_object_id id) { struct itimerval itimer; long remain_msec; lock(); // The next interval option is not used itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; if (timer_list.empty()) { // Timer already expired or stopped unlock(); return; } // Find timer list::iterator i = timer_list.begin(); while (i != timer_list.end()) { if ((*i)->get_object_id() == id) break; i++; } if (i == timer_list.end()) { // Timer already expired or stopped. unlock(); return; } // If it is the current running timer, then it must be stopped if (i == timer_list.begin()) { getitimer(ITIMER_REAL, &itimer); // If remaining time is less then 100 msec then let it // expire to prevent race condition when timer expires // while stopping it now. remain_msec = itimer.it_value.tv_sec * 1000 + itimer.it_value.tv_usec / 1000; if (remain_msec < 100) { stopped = true; unlock(); return; } // Stop timer itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, NULL); // Remove the timer MEMMAN_DELETE(timer_list.front()); delete timer_list.front(); timer_list.pop_front(); // If a next timer exists then adjust its relative // duration and start it. if (!timer_list.empty()) { t_timer *next_timer = timer_list.front(); long dur = next_timer->get_relative_duration(); dur += remain_msec; next_timer->set_relative_duration(dur); itimer.it_value.tv_sec = dur / 1000; itimer.it_value.tv_usec = (dur % 1000) * 1000; setitimer(ITIMER_REAL, &itimer, NULL); } unlock(); return; } // Timer is not the current running timer, so delete it // and adjust relative duration of the next timer. list::iterator next = i; next++; if (next == timer_list.end()) { // There is no next timer MEMMAN_DELETE(timer_list.back()); delete timer_list.back(); timer_list.pop_back(); unlock(); return; } long dur = (*i)->get_relative_duration(); long dur_next = (*next)->get_relative_duration(); (*next)->set_relative_duration(dur + dur_next); MEMMAN_DELETE(*i); delete *i; timer_list.erase(i); unlock(); } void t_timekeeper::report_expiry(void) { lock(); if (timer_list.empty()) { unlock(); return; } t_timer *t = timer_list.front(); // Trigger action if timer was not stopped if (!stopped) { t->expired(); } stopped = false; // Remove the timer MEMMAN_DELETE(timer_list.front()); delete timer_list.front(); timer_list.pop_front(); if (timer_list.empty()) { unlock(); return; } // If the relative duration of the next timer is 0, then // it also expired. Action should be triggerd. If not, then // it should be started. t_timer *next = timer_list.front(); long dur = next->get_relative_duration(); while (dur == 0) { next->expired(); MEMMAN_DELETE(next); delete next; timer_list.pop_front(); if (timer_list.empty()) break; next = timer_list.front(); dur = next->get_relative_duration(); } if (!timer_list.empty()) { struct itimerval itimer; itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = dur / 1000; itimer.it_value.tv_usec = (dur % 1000) * 1000; setitimer(ITIMER_REAL, &itimer, NULL); } unlock(); } unsigned long t_timekeeper::get_remaining_time(t_object_id timer_id) { struct itimerval itimer; unsigned long remain_msec = 0; unsigned long duration = 0; lock(); // The next interval option is not used itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; // Get remaining duration of current running timer getitimer(ITIMER_REAL, &itimer); remain_msec = itimer.it_value.tv_sec * 1000 + itimer.it_value.tv_usec / 1000; // Find the timer list::iterator i = timer_list.begin(); while (i != timer_list.end()) { if (i != timer_list.begin()) { remain_msec += (*i)->get_relative_duration(); } if ((*i)->get_object_id() == timer_id) break; i++; } // Return duration to originator of get event if (i == timer_list.end()) { duration = 0; } else { duration = remain_msec; } unlock(); return duration; } // SIGALRM handler void timeout_handler(int signum) { signal(SIGALRM, timeout_handler); // timekeeper.report_expiry(); // This will signal an interrupt to the call to pop in the // main look t_timekeeper::run evq_timekeeper->interrupt(); } void t_timekeeper::run(void) { t_event *event; t_event_start_timer *ev_start; t_event_stop_timer *ev_stop; bool timeout; // The timekeeper should not try to take the phone lock as // it may lead to a deadlock. Make sure an assert is raised // if this situation ever happens. phone->add_prohibited_thread(); if (threading_is_LinuxThreads) { // In LinuxThreads SIGALRM caused by the expiration of a timer // started with setitimer is always delivered to the thread calling // setitimer. So the sigwait() call from another thread does not // work. Use a signal handler instead. start(timeout_handler); } bool quit = false; while (!quit) { event = evq_timekeeper->pop(timeout); if (timeout) { report_expiry(); continue; } switch(event->get_type()) { case EV_START_TIMER: ev_start = (t_event_start_timer *)event; start_timer(ev_start->get_timer()); break; case EV_STOP_TIMER: ev_stop = (t_event_stop_timer *)event; stop_timer(ev_stop->get_timer_id()); break; case EV_QUIT: quit = true; break; default: assert(false); } MEMMAN_DELETE(event); delete event; } } void *timekeeper_main(void *arg) { timekeeper->run(); return NULL; } void *timekeeper_sigwait(void *arg) { sigset_t sigset; int sig; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); while (true) { // When SIGCONT is received after SIGSTOP, sigwait returns // with EINTR ?? if (sigwait(&sigset, &sig) == EINTR) continue; evq_timekeeper->interrupt(); } } twinkle-1.4.2/src/translator.h0000644000175000001440000000324311134645746013256 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TRANSLATOR_H #define _TRANSLATOR_H #include #define TRANSLATE(s) (translator ? translator->translate(s) : s) #define TRANSLATE2(c, s) (translator ? translator->translate2(c, s) : s) using namespace std; // This class provides an interface for languague translations. // The default implementation does not perform any translation. // The class may be subclassed to provide translation services. class t_translator { public: virtual ~t_translator() {}; // The default implementation simply returns the passed // string. A subclass should reimplement this method to // provide translation. virtual string translate(const string &s) { return s; }; // The name of the context parameter is in comments to avoid // unused argument warnings. virtual string translate2(const string &/*context*/, const string &s) { return s; }; }; extern t_translator *translator; #endif twinkle-1.4.2/src/parser/0000777000175000001440000000000011151327745012265 500000000000000twinkle-1.4.2/src/parser/hdr_via.h0000644000175000001440000000353211127714050013761 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Via header #ifndef _H_HDR_VIA #define _H_HDR_VIA #include #include #include "header.h" #include "parameter.h" class t_via { public: string protocol_name; string protocol_version; string transport; string host; int port; int ttl; string maddr; string received; string branch; // RFC 3581: symetric response routing bool rport_present; int rport; list extensions; t_via(); t_via(const string &_host, const int _port, bool add_rport = true); void add_extension(const t_parameter &p); string encode(void) const; // Get the response destination void get_response_dst(t_ip_port &ip_port) const; // Returns true if branch starts with RFC 3261 magic cookie bool rfc3261_compliant(void) const; }; class t_hdr_via : public t_header { public: list via_list; t_hdr_via(); void add_via(const t_via &v); string encode(void) const; string encode_multi_header(void) const; string encode_value(void) const; // Get the response destination void get_response_dst(t_ip_port &ip_port) const; }; #endif twinkle-1.4.2/src/parser/hdr_replaces.cpp0000644000175000001440000000347011127714057015343 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_replaces.h" t_hdr_replaces::t_hdr_replaces() : t_header("Replaces"), early_only(false) {} void t_hdr_replaces::set_call_id(const string &id) { populated = true; call_id = id; } void t_hdr_replaces::set_to_tag(const string &tag) { populated = true; to_tag = tag; } void t_hdr_replaces::set_from_tag(const string &tag) { populated = true; from_tag = tag; } void t_hdr_replaces::set_early_only(const bool on) { populated = true; early_only = on; } void t_hdr_replaces::set_params(const list &l) { populated = true; params = l; } void t_hdr_replaces::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_replaces::encode_value(void) const { string s; if (!populated) return s; s += call_id; s += ";to-tag="; s += to_tag; s += ";from-tag="; s += from_tag; if (early_only) { s += ";early-only"; } s += param_list2str(params); return s; } bool t_hdr_replaces::is_valid(void) const { return !(call_id.empty() || to_tag.empty() || from_tag.empty()); } twinkle-1.4.2/src/parser/hdr_rseq.h0000644000175000001440000000221411127714050014150 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RSeq header // RFC 3262 #ifndef _HDR_RSEQ #define _HDR_RSEQ #include #include "header.h" #include "definitions.h" using namespace std; class t_hdr_rseq : public t_header { public: unsigned long resp_nr; t_hdr_rseq(); void set_resp_nr(unsigned long l); string encode_value(void) const; bool operator==(const t_hdr_rseq &h) const; }; #endif twinkle-1.4.2/src/parser/hdr_to.cpp0000644000175000001440000000332111127714057014162 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_to.h" #include "definitions.h" #include "parse_ctrl.h" #include "util.h" t_hdr_to::t_hdr_to() : t_header("To", "t") {} void t_hdr_to::set_display(const string &d) { populated = true; display = d; } void t_hdr_to::set_uri(const string &u) { populated = true; uri.set_url(u); } void t_hdr_to::set_uri(const t_url &u) { populated = true; uri = u; } void t_hdr_to::set_tag(const string &t) { populated = true; tag = t; } void t_hdr_to::set_params(const list &l) { populated = true; params = l; } void t_hdr_to::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_to::encode_value(void) const { string s; if (!populated) return s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; if (tag != "") { s += ";tag="; s += tag; } s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/hdr_unsupported.cpp0000644000175000001440000000312711127714057016134 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_unsupported.h" t_hdr_unsupported::t_hdr_unsupported() : t_header("Unsupported") {}; void t_hdr_unsupported::add_feature(const string &f) { populated = true; features.push_back(f); } void t_hdr_unsupported::set_features(const list &_features) { populated = true; features = _features; } bool t_hdr_unsupported::contains(const string &f) const { if (!populated) return false; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (*i == f) return true; } return false; } string t_hdr_unsupported::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (i != features.begin()) s += ","; s += *i; } return s; } twinkle-1.4.2/src/parser/route.cpp0000644000175000001440000000235411127714057014046 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "route.h" #include "parse_ctrl.h" #include "util.h" void t_route::add_param(const t_parameter &p) { params.push_back(p); } void t_route::set_params(const list &l) { params = l; } string t_route::encode(void) const { string s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/hdr_reply_to.cpp0000644000175000001440000000312411127714057015376 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_reply_to.h" #include "definitions.h" t_hdr_reply_to::t_hdr_reply_to() : t_header("Reply-To") {} void t_hdr_reply_to::set_display(const string &d) { populated = true; display = d; } void t_hdr_reply_to::set_uri(const string &u) { populated = true; uri.set_url(u); } void t_hdr_reply_to::set_uri(const t_url &u) { populated = true; uri = u; } void t_hdr_reply_to::set_params(const list &l) { populated = true; params = l; } void t_hdr_reply_to::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_reply_to::encode_value(void) const { string s; if (!populated) return s; if (display.size() > 0) { s += '"'; s += display; s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/media_type.cpp0000644000175000001440000000425311134633366015031 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "media_type.h" #include "util.h" #include "utils/mime_database.h" using namespace std; using namespace utils; t_media::t_media() : q(1.0) {} t_media::t_media(const string &t, const string &s) : type(t), subtype(s), q(1.0) {} t_media::t_media(const string &mime_type) : q(1.0) { vector v = split(mime_type, '/'); if (v.size() == 2) { type = v[0]; subtype = v[1]; } } void t_media::add_params(const list &l) { list::const_iterator i = l.begin(); media_param_list.clear(); accept_extension_list.clear(); // Add media parameters while (i != l.end() && i->name != "q") { if (i->name == "charset") { charset = i->value; } else { media_param_list.push_back(*i); } ++i; } // Set the quality factor if (i != l.end()) { q = atof(i->value.c_str()); i++; } // Add accept extension parameters while (i != l.end()) { accept_extension_list.push_back(*i); i++; } } string t_media::encode(void) const { string s; s = type + '/' + subtype; if (!charset.empty()) { s += ";charset="; s += charset; } s += param_list2str(media_param_list); if (q != 1) { s += ";q="; s += float2str(q, 1); } s += param_list2str(accept_extension_list); return s; } string t_media::get_file_glob(void) const { string file_glob = mime_database->get_glob(type + '/' + subtype); return file_glob; } twinkle-1.4.2/src/parser/hdr_record_route.h0000644000175000001440000000237411127714050015701 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Record-Route header #ifndef _H_HDR_RECORD_ROUTE #define _H_HDR_RECORD_ROUTE #include #include #include "route.h" #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_record_route : public t_header { public: list route_list; t_hdr_record_route(); void add_route(const t_route &r); string encode(void) const; string encode_multi_header(void) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_call_id.h0000644000175000001440000000210311127714050014562 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Call-ID header #ifndef _HDR_CALL_ID_H #define _HDR_CALL_ID_H #include #include "header.h" using namespace std; class t_hdr_call_id : public t_header { public: string call_id; t_hdr_call_id(); void set_call_id(const string &id); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_allow_events.cpp0000644000175000001440000000242411127714057016245 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_allow_events.h" #include "parse_ctrl.h" t_hdr_allow_events::t_hdr_allow_events() : t_header("Allow-Events", "u") {} void t_hdr_allow_events::add_event_type(const string &t) { populated = true; event_types.push_back(t); } string t_hdr_allow_events::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = event_types.begin(); i != event_types.end(); i++) { if (i != event_types.begin()) s += ","; s += *i; } return s; } twinkle-1.4.2/src/parser/definitions.cpp0000644000175000001440000000362711127714057015227 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "definitions.h" #include "parse_ctrl.h" string method2str(const t_method &m, const string &unknown) { switch (m) { case INVITE: return "INVITE"; case ACK: return "ACK"; case OPTIONS: return "OPTIONS"; case BYE: return "BYE"; case CANCEL: return "CANCEL"; case REGISTER: return "REGISTER"; case PRACK: return "PRACK"; case SUBSCRIBE: return "SUBSCRIBE"; case NOTIFY: return "NOTIFY"; case REFER: return "REFER"; case INFO: return "INFO"; case MESSAGE: return "MESSAGE"; case PUBLISH: return "PUBLISH"; case METHOD_UNKNOWN: return unknown; default: assert(false); } } t_method str2method(const string &s) { if (s == "INVITE") return INVITE; if (s == "ACK") return ACK; if (s == "OPTIONS") return OPTIONS; if (s == "BYE") return BYE; if (s == "CANCEL") return CANCEL; if (s == "REGISTER") return REGISTER; if (s == "PRACK") return PRACK; if (s == "SUBSCRIBE") return SUBSCRIBE; if (s == "NOTIFY") return NOTIFY; if (s == "REFER") return REFER; if (s == "INFO") return INFO; if (s == "MESSAGE") return MESSAGE; if (s == "PUBLISH") return PUBLISH; return METHOD_UNKNOWN; } twinkle-1.4.2/src/parser/hdr_accept.cpp0000644000175000001440000000251211127714057015000 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_accept.h" #include "definitions.h" t_hdr_accept::t_hdr_accept() : t_header("Accept") {}; void t_hdr_accept::add_media(const t_media &media) { populated = true; media_list.push_back(media); } void t_hdr_accept::set_empty(void) { populated = true; media_list.clear(); } string t_hdr_accept::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = media_list.begin(); i != media_list.end(); i++) { if (i != media_list.begin()) s += ","; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_authorization.h0000644000175000001440000000274411127714050016106 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Authorization header #ifndef _HDR_AUTHORIZATION_H #define _HDR_AUTHORIZATION_H #include #include #include "credentials.h" #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_authorization : public t_header { public: list credentials_list; t_hdr_authorization(); void add_credentials(const t_credentials &c); string encode(void) const; string encode_value(void) const; // Return true if the header contains credentials for a realm/dest bool contains(const string &realm, const t_url &uri) const; // Remove credentials for a realm/dest void remove_credentials(const string &realm, const t_url &uri); }; #endif twinkle-1.4.2/src/parser/hdr_rack.cpp0000644000175000001440000000312011127714057014455 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_rack.h" #include "util.h" t_hdr_rack::t_hdr_rack() : t_header("RAck") { cseq_nr = 0; resp_nr = 0; method = INVITE; } void t_hdr_rack::set_cseq_nr(unsigned long l) { populated = true; cseq_nr = l; } void t_hdr_rack::set_resp_nr(unsigned long l) { populated = true; resp_nr = l; } void t_hdr_rack::set_method(t_method m, const string &unknown) { populated = true; method = m; unknown_method = unknown; } void t_hdr_rack::set_method(const string &s) { populated = true; method = str2method(s); if (method == METHOD_UNKNOWN) { unknown_method = s; } } string t_hdr_rack::encode_value(void) const { string s; if (!populated) return s; s = ulong2str(resp_nr) + ' '; s += ulong2str(cseq_nr); s += ' '; s += method2str(method, unknown_method); return s; } twinkle-1.4.2/src/parser/parser.cxx0000644000175000001440000051640211142401140014207 00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_NUM = 258, T_TOKEN = 259, T_QSTRING = 260, T_COMMENT = 261, T_LINE = 262, T_URI = 263, T_URI_WILDCARD = 264, T_DISPLAY = 265, T_LANG = 266, T_WORD = 267, T_WKDAY = 268, T_MONTH = 269, T_GMT = 270, T_SIP = 271, T_METHOD = 272, T_AUTH_DIGEST = 273, T_AUTH_OTHER = 274, T_IPV6ADDR = 275, T_PARAMVAL = 276, T_HDR_ACCEPT = 277, T_HDR_ACCEPT_ENCODING = 278, T_HDR_ACCEPT_LANGUAGE = 279, T_HDR_ALERT_INFO = 280, T_HDR_ALLOW = 281, T_HDR_ALLOW_EVENTS = 282, T_HDR_AUTHENTICATION_INFO = 283, T_HDR_AUTHORIZATION = 284, T_HDR_CALL_ID = 285, T_HDR_CALL_INFO = 286, T_HDR_CONTACT = 287, T_HDR_CONTENT_DISP = 288, T_HDR_CONTENT_ENCODING = 289, T_HDR_CONTENT_LANGUAGE = 290, T_HDR_CONTENT_LENGTH = 291, T_HDR_CONTENT_TYPE = 292, T_HDR_CSEQ = 293, T_HDR_DATE = 294, T_HDR_ERROR_INFO = 295, T_HDR_EVENT = 296, T_HDR_EXPIRES = 297, T_HDR_FROM = 298, T_HDR_IN_REPLY_TO = 299, T_HDR_MAX_FORWARDS = 300, T_HDR_MIN_EXPIRES = 301, T_HDR_MIME_VERSION = 302, T_HDR_ORGANIZATION = 303, T_HDR_P_ASSERTED_IDENTITY = 304, T_HDR_P_PREFERRED_IDENTITY = 305, T_HDR_PRIORITY = 306, T_HDR_PRIVACY = 307, T_HDR_PROXY_AUTHENTICATE = 308, T_HDR_PROXY_AUTHORIZATION = 309, T_HDR_PROXY_REQUIRE = 310, T_HDR_RACK = 311, T_HDR_RECORD_ROUTE = 312, T_HDR_SERVICE_ROUTE = 313, T_HDR_REFER_SUB = 314, T_HDR_REFER_TO = 315, T_HDR_REFERRED_BY = 316, T_HDR_REPLACES = 317, T_HDR_REPLY_TO = 318, T_HDR_REQUIRE = 319, T_HDR_REQUEST_DISPOSITION = 320, T_HDR_RETRY_AFTER = 321, T_HDR_ROUTE = 322, T_HDR_RSEQ = 323, T_HDR_SERVER = 324, T_HDR_SIP_ETAG = 325, T_HDR_SIP_IF_MATCH = 326, T_HDR_SUBJECT = 327, T_HDR_SUBSCRIPTION_STATE = 328, T_HDR_SUPPORTED = 329, T_HDR_TIMESTAMP = 330, T_HDR_TO = 331, T_HDR_UNSUPPORTED = 332, T_HDR_USER_AGENT = 333, T_HDR_VIA = 334, T_HDR_WARNING = 335, T_HDR_WWW_AUTHENTICATE = 336, T_HDR_UNKNOWN = 337, T_CRLF = 338, T_ERROR = 339, T_NULL = 340 }; #endif /* Tokens. */ #define T_NUM 258 #define T_TOKEN 259 #define T_QSTRING 260 #define T_COMMENT 261 #define T_LINE 262 #define T_URI 263 #define T_URI_WILDCARD 264 #define T_DISPLAY 265 #define T_LANG 266 #define T_WORD 267 #define T_WKDAY 268 #define T_MONTH 269 #define T_GMT 270 #define T_SIP 271 #define T_METHOD 272 #define T_AUTH_DIGEST 273 #define T_AUTH_OTHER 274 #define T_IPV6ADDR 275 #define T_PARAMVAL 276 #define T_HDR_ACCEPT 277 #define T_HDR_ACCEPT_ENCODING 278 #define T_HDR_ACCEPT_LANGUAGE 279 #define T_HDR_ALERT_INFO 280 #define T_HDR_ALLOW 281 #define T_HDR_ALLOW_EVENTS 282 #define T_HDR_AUTHENTICATION_INFO 283 #define T_HDR_AUTHORIZATION 284 #define T_HDR_CALL_ID 285 #define T_HDR_CALL_INFO 286 #define T_HDR_CONTACT 287 #define T_HDR_CONTENT_DISP 288 #define T_HDR_CONTENT_ENCODING 289 #define T_HDR_CONTENT_LANGUAGE 290 #define T_HDR_CONTENT_LENGTH 291 #define T_HDR_CONTENT_TYPE 292 #define T_HDR_CSEQ 293 #define T_HDR_DATE 294 #define T_HDR_ERROR_INFO 295 #define T_HDR_EVENT 296 #define T_HDR_EXPIRES 297 #define T_HDR_FROM 298 #define T_HDR_IN_REPLY_TO 299 #define T_HDR_MAX_FORWARDS 300 #define T_HDR_MIN_EXPIRES 301 #define T_HDR_MIME_VERSION 302 #define T_HDR_ORGANIZATION 303 #define T_HDR_P_ASSERTED_IDENTITY 304 #define T_HDR_P_PREFERRED_IDENTITY 305 #define T_HDR_PRIORITY 306 #define T_HDR_PRIVACY 307 #define T_HDR_PROXY_AUTHENTICATE 308 #define T_HDR_PROXY_AUTHORIZATION 309 #define T_HDR_PROXY_REQUIRE 310 #define T_HDR_RACK 311 #define T_HDR_RECORD_ROUTE 312 #define T_HDR_SERVICE_ROUTE 313 #define T_HDR_REFER_SUB 314 #define T_HDR_REFER_TO 315 #define T_HDR_REFERRED_BY 316 #define T_HDR_REPLACES 317 #define T_HDR_REPLY_TO 318 #define T_HDR_REQUIRE 319 #define T_HDR_REQUEST_DISPOSITION 320 #define T_HDR_RETRY_AFTER 321 #define T_HDR_ROUTE 322 #define T_HDR_RSEQ 323 #define T_HDR_SERVER 324 #define T_HDR_SIP_ETAG 325 #define T_HDR_SIP_IF_MATCH 326 #define T_HDR_SUBJECT 327 #define T_HDR_SUBSCRIPTION_STATE 328 #define T_HDR_SUPPORTED 329 #define T_HDR_TIMESTAMP 330 #define T_HDR_TO 331 #define T_HDR_UNSUPPORTED 332 #define T_HDR_USER_AGENT 333 #define T_HDR_VIA 334 #define T_HDR_WARNING 335 #define T_HDR_WWW_AUTHENTICATE 336 #define T_HDR_UNKNOWN 337 #define T_CRLF 338 #define T_ERROR 339 #define T_NULL 340 /* Copy the first part of user declarations. */ #line 19 "parser.yxx" #include #include #include #include "media_type.h" #include "parameter.h" #include "parse_ctrl.h" #include "request.h" #include "response.h" #include "util.h" #include "audits/memman.h" using namespace std; extern int yylex(void); void yyerror(const char *s); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 49 "parser.yxx" { int yyt_int; ulong yyt_ulong; float yyt_float; string *yyt_str; t_parameter *yyt_param; list *yyt_params; t_media *yyt_media; t_coding *yyt_coding; t_language *yyt_language; t_alert_param *yyt_alert_param; t_info_param *yyt_info_param; list *yyt_contacts; t_contact_param *yyt_contact; t_error_param *yyt_error_param; t_identity *yyt_from_addr; t_route *yyt_route; t_server *yyt_server; t_via *yyt_via; t_warning *yyt_warning; t_digest_response *yyt_dig_resp; t_credentials *yyt_credentials; t_digest_challenge *yyt_dig_chlg; t_challenge *yyt_challenge; } /* Line 193 of yacc.c. */ #line 310 "parser.cxx" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 323 "parser.cxx" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 734 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 99 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 254 /* YYNRULES -- Number of rules. */ #define YYNRULES 432 /* YYNRULES -- Number of states. */ #define YYNSTATES 791 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 340 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 2, 88, 2, 96, 86, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 89, 91, 90, 92, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 4, 7, 9, 11, 14, 18, 19, 20, 27, 28, 33, 37, 38, 39, 40, 48, 49, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, 485, 489, 493, 497, 501, 505, 509, 513, 517, 521, 525, 529, 533, 537, 540, 543, 546, 549, 552, 555, 558, 561, 564, 567, 570, 573, 576, 579, 582, 585, 588, 591, 594, 597, 600, 603, 606, 609, 612, 615, 618, 621, 624, 627, 630, 633, 636, 639, 642, 645, 648, 651, 654, 657, 660, 663, 666, 669, 672, 675, 678, 681, 684, 687, 690, 693, 696, 699, 702, 705, 708, 711, 714, 717, 718, 721, 726, 730, 731, 735, 737, 738, 739, 745, 747, 749, 751, 755, 757, 760, 763, 764, 767, 768, 773, 775, 776, 780, 782, 786, 787, 788, 795, 797, 801, 802, 803, 807, 809, 813, 815, 819, 820, 821, 828, 829, 830, 834, 836, 838, 842, 845, 846, 847, 851, 852, 853, 854, 862, 863, 865, 867, 870, 872, 876, 877, 880, 881, 886, 887, 888, 892, 895, 896, 897, 902, 903, 904, 918, 920, 924, 925, 926, 933, 934, 935, 939, 940, 944, 945, 948, 949, 950, 957, 958, 959, 963, 964, 965, 971, 972, 973, 977, 978, 979, 983, 985, 986, 987, 991, 992, 995, 999, 1000, 1003, 1007, 1009, 1011, 1015, 1017, 1021, 1023, 1027, 1028, 1029, 1037, 1039, 1043, 1044, 1045, 1050, 1051, 1055, 1057, 1061, 1062, 1063, 1069, 1070, 1071, 1072, 1078, 1080, 1084, 1086, 1089, 1091, 1094, 1099, 1100, 1101, 1105, 1106, 1108, 1112, 1113, 1116, 1118, 1121, 1123, 1127, 1129, 1133, 1134, 1138, 1140, 1144, 1146, 1149, 1151, 1155, 1159, 1165, 1167, 1168, 1169, 1175, 1177, 1178, 1179, 1185, 1186, 1187, 1193, 1195, 1199, 1200, 1201, 1207, 1208, 1209, 1213, 1215, 1217, 1221, 1223, 1227, 1229, 1233, 1234, 1238, 1239, 1243, 1244, 1247, 1249, 1253, 1254, 1258, 1259, 1263, 1264, 1267, 1268, 1271, 1272, 1275, 1276, 1277, 1281, 1282, 1283, 1289, 1292, 1294, 1298, 1301, 1302, 1306, 1307, 1311, 1314, 1316, 1318, 1320 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 100, 0, -1, -1, 101, 102, -1, 103, -1, 109, -1, 1, 85, -1, 104, 114, 83, -1, -1, -1, 17, 105, 8, 106, 107, 83, -1, -1, 16, 108, 86, 4, -1, 110, 114, 83, -1, -1, -1, -1, 107, 111, 3, 112, 7, 113, 83, -1, -1, 114, 115, -1, 116, 176, 83, -1, 117, 183, 83, -1, 118, 186, 83, -1, 119, 191, 83, -1, 120, 195, 83, -1, 121, 343, 83, -1, 122, 318, 83, -1, 123, 324, 83, -1, 124, 196, 83, -1, 125, 200, 83, -1, 126, 204, 83, -1, 127, 216, 83, -1, 128, 217, 83, -1, 129, 218, 83, -1, 130, 221, 83, -1, 131, 224, 83, -1, 132, 225, 83, -1, 133, 228, 83, -1, 135, 342, 83, -1, 134, 231, 83, -1, 136, 235, 83, -1, 137, 238, 83, -1, 138, 244, 83, -1, 139, 249, 83, -1, 140, 252, 83, -1, 141, 255, 83, -1, 142, 256, 83, -1, 143, 259, 83, -1, 144, 261, 83, -1, 145, 263, 83, -1, 146, 264, 83, -1, 147, 330, 83, -1, 148, 332, 83, -1, 149, 265, 83, -1, 150, 339, 83, -1, 151, 266, 83, -1, 152, 349, 83, -1, 153, 345, 83, -1, 154, 347, 83, -1, 155, 271, 83, -1, 156, 274, 83, -1, 157, 276, 83, -1, 158, 352, 83, -1, 159, 277, 83, -1, 160, 283, 83, -1, 161, 336, 83, -1, 162, 284, 83, -1, 163, 270, 83, -1, 164, 350, 83, -1, 165, 351, 83, -1, 166, 286, 83, -1, 167, 344, 83, -1, 168, 289, 83, -1, 169, 290, 83, -1, 170, 295, 83, -1, 171, 297, 83, -1, 172, 298, 83, -1, 173, 299, 83, -1, 174, 310, 83, -1, 175, 334, 83, -1, 82, 87, 314, 83, -1, 116, 1, 83, -1, 117, 1, 83, -1, 118, 1, 83, -1, 119, 1, 83, -1, 120, 1, 83, -1, 121, 1, 83, -1, 122, 1, 83, -1, 123, 1, 83, -1, 124, 1, 83, -1, 125, 1, 83, -1, 126, 1, 83, -1, 127, 1, 83, -1, 128, 1, 83, -1, 129, 1, 83, -1, 130, 1, 83, -1, 131, 1, 83, -1, 132, 1, 83, -1, 133, 1, 83, -1, 134, 1, 83, -1, 135, 1, 83, -1, 136, 1, 83, -1, 137, 1, 83, -1, 138, 1, 83, -1, 139, 1, 83, -1, 140, 1, 83, -1, 141, 1, 83, -1, 142, 1, 83, -1, 143, 1, 83, -1, 144, 1, 83, -1, 145, 1, 83, -1, 146, 1, 83, -1, 147, 1, 83, -1, 148, 1, 83, -1, 149, 1, 83, -1, 150, 1, 83, -1, 151, 1, 83, -1, 152, 1, 83, -1, 153, 1, 83, -1, 154, 1, 83, -1, 155, 1, 83, -1, 156, 1, 83, -1, 157, 1, 83, -1, 158, 1, 83, -1, 159, 1, 83, -1, 160, 1, 83, -1, 161, 1, 83, -1, 162, 1, 83, -1, 163, 1, 83, -1, 164, 1, 83, -1, 165, 1, 83, -1, 166, 1, 83, -1, 167, 1, 83, -1, 168, 1, 83, -1, 169, 1, 83, -1, 170, 1, 83, -1, 171, 1, 83, -1, 172, 1, 83, -1, 173, 1, 83, -1, 174, 1, 83, -1, 175, 1, 83, -1, 22, 87, -1, 23, 87, -1, 24, 87, -1, 25, 87, -1, 26, 87, -1, 27, 87, -1, 28, 87, -1, 29, 87, -1, 30, 87, -1, 31, 87, -1, 32, 87, -1, 33, 87, -1, 34, 87, -1, 35, 87, -1, 36, 87, -1, 37, 87, -1, 38, 87, -1, 39, 87, -1, 40, 87, -1, 41, 87, -1, 42, 87, -1, 43, 87, -1, 44, 87, -1, 45, 87, -1, 46, 87, -1, 47, 87, -1, 48, 87, -1, 49, 87, -1, 50, 87, -1, 51, 87, -1, 52, 87, -1, 53, 87, -1, 54, 87, -1, 55, 87, -1, 56, 87, -1, 57, 87, -1, 59, 87, -1, 60, 87, -1, 61, 87, -1, 62, 87, -1, 63, 87, -1, 64, 87, -1, 65, 87, -1, 66, 87, -1, 67, 87, -1, 68, 87, -1, 69, 87, -1, 58, 87, -1, 70, 87, -1, 71, 87, -1, 72, 87, -1, 73, 87, -1, 74, 87, -1, 75, 87, -1, 76, 87, -1, 77, 87, -1, 78, 87, -1, 79, 87, -1, 80, 87, -1, 81, 87, -1, -1, 177, 178, -1, 176, 88, 177, 178, -1, 4, 86, 4, -1, -1, 178, 89, 179, -1, 4, -1, -1, -1, 4, 90, 180, 182, 181, -1, 21, -1, 5, -1, 184, -1, 183, 88, 184, -1, 4, -1, 4, 185, -1, 89, 179, -1, -1, 187, 189, -1, -1, 186, 88, 188, 189, -1, 11, -1, -1, 11, 190, 185, -1, 192, -1, 191, 88, 192, -1, -1, -1, 91, 193, 8, 194, 92, 178, -1, 4, -1, 195, 88, 4, -1, -1, -1, 197, 199, 198, -1, 12, -1, 12, 93, 12, -1, 201, -1, 200, 88, 201, -1, -1, -1, 91, 202, 8, 203, 92, 178, -1, -1, -1, 205, 9, 206, -1, 207, -1, 208, -1, 207, 88, 208, -1, 209, 178, -1, -1, -1, 210, 8, 211, -1, -1, -1, -1, 212, 215, 91, 213, 8, 214, 92, -1, -1, 10, -1, 5, -1, 4, 178, -1, 184, -1, 217, 88, 184, -1, -1, 219, 189, -1, -1, 218, 88, 220, 189, -1, -1, -1, 222, 3, 223, -1, 177, 178, -1, -1, -1, 226, 3, 227, 4, -1, -1, -1, 229, 13, 88, 3, 14, 3, 3, 87, 3, 87, 3, 15, 230, -1, 232, -1, 231, 88, 232, -1, -1, -1, 91, 233, 8, 234, 92, 178, -1, -1, -1, 236, 3, 237, -1, -1, 239, 240, 178, -1, -1, 8, 241, -1, -1, -1, 215, 91, 242, 8, 243, 92, -1, -1, -1, 245, 199, 246, -1, -1, -1, 244, 88, 247, 199, 248, -1, -1, -1, 250, 3, 251, -1, -1, -1, 253, 3, 254, -1, 4, -1, -1, -1, 257, 7, 258, -1, -1, 260, 240, -1, 259, 88, 240, -1, -1, 262, 240, -1, 261, 88, 240, -1, 4, -1, 4, -1, 264, 89, 4, -1, 4, -1, 265, 88, 4, -1, 267, -1, 266, 88, 267, -1, -1, -1, 268, 215, 91, 8, 269, 92, 178, -1, 267, -1, 270, 88, 267, -1, -1, -1, 272, 199, 273, 178, -1, -1, 275, 240, 178, -1, 4, -1, 265, 88, 4, -1, -1, -1, 278, 3, 279, 280, 178, -1, -1, -1, -1, 94, 281, 6, 282, 95, -1, 267, -1, 283, 88, 267, -1, 285, -1, 284, 285, -1, 280, -1, 4, 280, -1, 4, 86, 4, 280, -1, -1, -1, 287, 7, 288, -1, -1, 4, -1, 289, 88, 4, -1, -1, 291, 292, -1, 293, -1, 293, 294, -1, 3, -1, 3, 96, 3, -1, 3, -1, 3, 96, 3, -1, -1, 296, 240, 178, -1, 4, -1, 297, 88, 4, -1, 285, -1, 298, 285, -1, 300, -1, 299, 88, 300, -1, 301, 302, 178, -1, 4, 86, 4, 86, 4, -1, 4, -1, -1, -1, 4, 87, 303, 3, 304, -1, 307, -1, -1, -1, 307, 87, 305, 3, 306, -1, -1, -1, 97, 308, 20, 309, 98, -1, 311, -1, 310, 88, 311, -1, -1, -1, 312, 3, 313, 302, 5, -1, -1, -1, 315, 7, 316, -1, 179, -1, 317, -1, 318, 88, 317, -1, 179, -1, 319, 88, 179, -1, 179, -1, 320, 88, 179, -1, -1, 18, 322, 319, -1, -1, 19, 323, 320, -1, -1, 325, 321, -1, 179, -1, 326, 88, 179, -1, -1, 18, 328, 326, -1, -1, 19, 329, 320, -1, -1, 331, 327, -1, -1, 333, 321, -1, -1, 335, 327, -1, -1, -1, 337, 3, 338, -1, -1, -1, 340, 3, 3, 341, 4, -1, 4, 178, -1, 4, -1, 343, 88, 4, -1, 4, 178, -1, -1, 346, 240, 178, -1, -1, 348, 240, 178, -1, 4, 178, -1, 4, -1, 4, -1, 4, -1, 352, 88, 4, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 244, 244, 244, 247, 248, 249, 269, 278, 278, 278, 296, 296, 300, 307, 307, 308, 307, 318, 319, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 386, 388, 390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, 480, 482, 484, 486, 488, 490, 492, 494, 496, 498, 500, 502, 504, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537, 539, 541, 543, 545, 547, 549, 551, 553, 555, 557, 559, 561, 563, 565, 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, 587, 589, 591, 593, 595, 597, 599, 601, 603, 605, 607, 609, 611, 613, 615, 617, 619, 621, 623, 625, 627, 629, 631, 633, 635, 638, 639, 644, 651, 657, 658, 664, 668, 668, 668, 675, 677, 681, 684, 689, 693, 700, 707, 707, 710, 710, 715, 720, 720, 727, 730, 735, 735, 735, 750, 753, 758, 758, 758, 763, 764, 771, 774, 779, 779, 779, 794, 794, 794, 796, 801, 806, 812, 828, 828, 828, 839, 839, 839, 839, 854, 855, 859, 862, 878, 881, 886, 886, 889, 889, 894, 894, 894, 898, 905, 905, 905, 911, 914, 911, 925, 928, 933, 933, 933, 948, 948, 948, 952, 952, 967, 967, 978, 978, 978, 993, 993, 993, 996, 996, 996, 1001, 1001, 1001, 1005, 1005, 1005, 1009, 1014, 1014, 1014, 1019, 1019, 1022, 1027, 1027, 1030, 1035, 1040, 1043, 1048, 1051, 1056, 1059, 1064, 1064, 1064, 1082, 1085, 1090, 1090, 1090, 1112, 1112, 1120, 1123, 1128, 1128, 1128, 1144, 1145, 1145, 1145, 1149, 1152, 1157, 1160, 1165, 1170, 1177, 1188, 1188, 1188, 1193, 1195, 1198, 1203, 1203, 1206, 1208, 1213, 1214, 1219, 1220, 1225, 1225, 1240, 1243, 1248, 1251, 1256, 1259, 1264, 1292, 1303, 1308, 1308, 1308, 1316, 1321, 1321, 1321, 1329, 1329, 1329, 1336, 1339, 1344, 1344, 1344, 1355, 1355, 1355, 1358, 1378, 1379, 1382, 1390, 1398, 1403, 1409, 1409, 1415, 1415, 1424, 1424, 1429, 1437, 1445, 1445, 1451, 1451, 1460, 1460, 1465, 1465, 1471, 1471, 1476, 1476, 1476, 1480, 1480, 1480, 1487, 1501, 1504, 1509, 1535, 1535, 1543, 1543, 1558, 1569, 1574, 1579, 1583 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "T_NUM", "T_TOKEN", "T_QSTRING", "T_COMMENT", "T_LINE", "T_URI", "T_URI_WILDCARD", "T_DISPLAY", "T_LANG", "T_WORD", "T_WKDAY", "T_MONTH", "T_GMT", "T_SIP", "T_METHOD", "T_AUTH_DIGEST", "T_AUTH_OTHER", "T_IPV6ADDR", "T_PARAMVAL", "T_HDR_ACCEPT", "T_HDR_ACCEPT_ENCODING", "T_HDR_ACCEPT_LANGUAGE", "T_HDR_ALERT_INFO", "T_HDR_ALLOW", "T_HDR_ALLOW_EVENTS", "T_HDR_AUTHENTICATION_INFO", "T_HDR_AUTHORIZATION", "T_HDR_CALL_ID", "T_HDR_CALL_INFO", "T_HDR_CONTACT", "T_HDR_CONTENT_DISP", "T_HDR_CONTENT_ENCODING", "T_HDR_CONTENT_LANGUAGE", "T_HDR_CONTENT_LENGTH", "T_HDR_CONTENT_TYPE", "T_HDR_CSEQ", "T_HDR_DATE", "T_HDR_ERROR_INFO", "T_HDR_EVENT", "T_HDR_EXPIRES", "T_HDR_FROM", "T_HDR_IN_REPLY_TO", "T_HDR_MAX_FORWARDS", "T_HDR_MIN_EXPIRES", "T_HDR_MIME_VERSION", "T_HDR_ORGANIZATION", "T_HDR_P_ASSERTED_IDENTITY", "T_HDR_P_PREFERRED_IDENTITY", "T_HDR_PRIORITY", "T_HDR_PRIVACY", "T_HDR_PROXY_AUTHENTICATE", "T_HDR_PROXY_AUTHORIZATION", "T_HDR_PROXY_REQUIRE", "T_HDR_RACK", "T_HDR_RECORD_ROUTE", "T_HDR_SERVICE_ROUTE", "T_HDR_REFER_SUB", "T_HDR_REFER_TO", "T_HDR_REFERRED_BY", "T_HDR_REPLACES", "T_HDR_REPLY_TO", "T_HDR_REQUIRE", "T_HDR_REQUEST_DISPOSITION", "T_HDR_RETRY_AFTER", "T_HDR_ROUTE", "T_HDR_RSEQ", "T_HDR_SERVER", "T_HDR_SIP_ETAG", "T_HDR_SIP_IF_MATCH", "T_HDR_SUBJECT", "T_HDR_SUBSCRIPTION_STATE", "T_HDR_SUPPORTED", "T_HDR_TIMESTAMP", "T_HDR_TO", "T_HDR_UNSUPPORTED", "T_HDR_USER_AGENT", "T_HDR_VIA", "T_HDR_WARNING", "T_HDR_WWW_AUTHENTICATE", "T_HDR_UNKNOWN", "T_CRLF", "T_ERROR", "T_NULL", "'/'", "':'", "','", "';'", "'='", "'<'", "'>'", "'@'", "'('", "')'", "'.'", "'['", "']'", "$accept", "sip_message", "@1", "sip_message2", "request", "request_line", "@2", "@3", "sip_version", "@4", "response", "status_line", "@5", "@6", "@7", "headers", "header", "hd_accept", "hd_accept_encoding", "hd_accept_language", "hd_alert_info", "hd_allow", "hd_allow_events", "hd_authentication_info", "hd_authorization", "hd_call_id", "hd_call_info", "hd_contact", "hd_content_disp", "hd_content_encoding", "hd_content_language", "hd_content_length", "hd_content_type", "hd_cseq", "hd_date", "hd_error_info", "hd_event", "hd_expires", "hd_from", "hd_in_reply_to", "hd_max_forwards", "hd_min_expires", "hd_mime_version", "hd_organization", "hd_p_asserted_identity", "hd_p_preferred_identity", "hd_priority", "hd_privacy", "hd_proxy_authenticate", "hd_proxy_authorization", "hd_proxy_require", "hd_rack", "hd_record_route", "hd_refer_sub", "hd_refer_to", "hd_referred_by", "hd_replaces", "hd_reply_to", "hd_require", "hd_request_disposition", "hd_retry_after", "hd_route", "hd_rseq", "hd_server", "hd_service_route", "hd_sip_etag", "hd_sip_if_match", "hd_subject", "hd_subscription_state", "hd_supported", "hd_timestamp", "hd_to", "hd_unsupported", "hd_user_agent", "hd_via", "hd_warning", "hd_www_authenticate", "hdr_accept", "media_range", "parameters", "parameter", "@8", "@9", "parameter_val", "hdr_accept_encoding", "content_coding", "q_factor", "hdr_accept_language", "@10", "@11", "language", "@12", "hdr_alert_info", "alert_param", "@13", "@14", "hdr_allow", "hdr_call_id", "@15", "@16", "call_id", "hdr_call_info", "info_param", "@17", "@18", "hdr_contact", "@19", "@20", "contacts", "contact_param", "contact_addr", "@21", "@22", "@23", "@24", "@25", "display_name", "hdr_content_disp", "hdr_content_encoding", "hdr_content_language", "@26", "@27", "hdr_content_length", "@28", "@29", "hdr_content_type", "hdr_cseq", "@30", "@31", "hdr_date", "@32", "@33", "hdr_error_info", "error_param", "@34", "@35", "hdr_expires", "@36", "@37", "hdr_from", "@38", "from_addr", "@39", "@40", "@41", "hdr_in_reply_to", "@42", "@43", "@44", "@45", "hdr_max_forwards", "@46", "@47", "hdr_min_expires", "@48", "@49", "hdr_mime_version", "hdr_organization", "@50", "@51", "hdr_p_asserted_identity", "@52", "hdr_p_preferred_identity", "@53", "hdr_priority", "hdr_privacy", "hdr_proxy_require", "hdr_record_route", "rec_route", "@54", "@55", "hdr_service_route", "hdr_replaces", "@56", "@57", "hdr_reply_to", "@58", "hdr_require", "hdr_retry_after", "@59", "@60", "comment", "@61", "@62", "hdr_route", "hdr_server", "server", "hdr_subject", "@63", "@64", "hdr_supported", "hdr_timestamp", "@65", "hdr_timestamp1", "timestamp", "delay", "hdr_to", "@66", "hdr_unsupported", "hdr_user_agent", "hdr_via", "via_parm", "sent_protocol", "host", "@67", "@68", "@69", "@70", "ipv6reference", "@71", "@72", "hdr_warning", "warning", "@73", "@74", "hdr_unknown", "@75", "@76", "ainfo", "hdr_authentication_info", "digest_response", "auth_params", "credentials", "@77", "@78", "hdr_authorization", "@79", "digest_challenge", "challenge", "@80", "@81", "hdr_proxy_authenticate", "@82", "hdr_proxy_authorization", "@83", "hdr_www_authenticate", "@84", "hdr_rseq", "@85", "@86", "hdr_rack", "@87", "@88", "hdr_event", "hdr_allow_events", "hdr_subscription_state", "hdr_refer_to", "@89", "hdr_referred_by", "@90", "hdr_refer_sub", "hdr_sip_etag", "hdr_sip_if_match", "hdr_request_disposition", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 47, 58, 44, 59, 61, 60, 62, 64, 40, 41, 46, 91, 93 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { 0, 99, 101, 100, 102, 102, 102, 103, 105, 106, 104, 108, 107, 109, 111, 112, 113, 110, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 176, 176, 177, 178, 178, 179, 180, 181, 179, 182, 182, 183, 183, 184, 184, 185, 187, 186, 188, 186, 189, 190, 189, 191, 191, 193, 194, 192, 195, 195, 197, 198, 196, 199, 199, 200, 200, 202, 203, 201, 205, 206, 204, 204, 207, 207, 208, 210, 211, 209, 212, 213, 214, 209, 215, 215, 215, 216, 217, 217, 219, 218, 220, 218, 222, 223, 221, 224, 226, 227, 225, 229, 230, 228, 231, 231, 233, 234, 232, 236, 237, 235, 239, 238, 241, 240, 242, 243, 240, 245, 246, 244, 247, 248, 244, 250, 251, 249, 253, 254, 252, 255, 257, 258, 256, 260, 259, 259, 262, 261, 261, 263, 264, 264, 265, 265, 266, 266, 268, 269, 267, 270, 270, 272, 273, 271, 275, 274, 276, 276, 278, 279, 277, 280, 281, 282, 280, 283, 283, 284, 284, 285, 285, 285, 287, 288, 286, 289, 289, 289, 291, 290, 292, 292, 293, 293, 294, 294, 296, 295, 297, 297, 298, 298, 299, 299, 300, 301, 302, 303, 304, 302, 302, 305, 306, 302, 308, 309, 307, 310, 310, 312, 313, 311, 315, 316, 314, 317, 318, 318, 319, 319, 320, 320, 322, 321, 323, 321, 325, 324, 326, 326, 328, 327, 329, 327, 331, 330, 333, 332, 335, 334, 337, 338, 336, 340, 341, 339, 342, 343, 343, 344, 346, 345, 348, 347, 349, 350, 351, 352, 352 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 1, 1, 2, 3, 0, 0, 6, 0, 4, 3, 0, 0, 0, 7, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 4, 3, 0, 3, 1, 0, 0, 5, 1, 1, 1, 3, 1, 2, 2, 0, 2, 0, 4, 1, 0, 3, 1, 3, 0, 0, 6, 1, 3, 0, 0, 3, 1, 3, 1, 3, 0, 0, 6, 0, 0, 3, 1, 1, 3, 2, 0, 0, 3, 0, 0, 0, 7, 0, 1, 1, 2, 1, 3, 0, 2, 0, 4, 0, 0, 3, 2, 0, 0, 4, 0, 0, 13, 1, 3, 0, 0, 6, 0, 0, 3, 0, 3, 0, 2, 0, 0, 6, 0, 0, 3, 0, 0, 5, 0, 0, 3, 0, 0, 3, 1, 0, 0, 3, 0, 2, 3, 0, 2, 3, 1, 1, 3, 1, 3, 1, 3, 0, 0, 7, 1, 3, 0, 0, 4, 0, 3, 1, 3, 0, 0, 5, 0, 0, 0, 5, 1, 3, 1, 2, 1, 2, 4, 0, 0, 3, 0, 1, 3, 0, 2, 1, 2, 1, 3, 1, 3, 0, 3, 1, 3, 1, 2, 1, 3, 3, 5, 1, 0, 0, 5, 1, 0, 0, 5, 0, 0, 5, 1, 3, 0, 0, 5, 0, 0, 3, 1, 1, 3, 1, 3, 1, 3, 0, 3, 0, 3, 0, 2, 1, 3, 0, 3, 0, 3, 0, 2, 0, 2, 0, 2, 0, 0, 3, 0, 0, 5, 2, 1, 3, 2, 0, 3, 0, 3, 2, 1, 1, 1, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint16 yydefact[] = { 2, 0, 0, 1, 0, 11, 8, 3, 4, 18, 14, 5, 18, 6, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 13, 12, 0, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 188, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 386, 0, 0, 0, 205, 0, 215, 0, 213, 0, 0, 0, 0, 227, 0, 225, 0, 230, 0, 0, 421, 0, 0, 207, 389, 390, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 237, 0, 0, 0, 245, 246, 205, 0, 256, 0, 205, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 278, 0, 276, 0, 205, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 256, 0, 0, 256, 0, 313, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 318, 256, 0, 205, 0, 0, 0, 256, 0, 0, 256, 0, 0, 0, 0, 0, 256, 0, 316, 0, 0, 0, 431, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 335, 336, 343, 0, 341, 0, 323, 0, 0, 429, 0, 0, 430, 0, 0, 0, 0, 0, 205, 0, 0, 350, 0, 0, 0, 0, 0, 0, 256, 0, 362, 0, 0, 364, 0, 0, 0, 0, 366, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 20, 0, 202, 82, 0, 216, 21, 0, 83, 22, 220, 222, 219, 84, 0, 23, 0, 85, 24, 0, 86, 25, 0, 87, 208, 26, 0, 88, 27, 396, 398, 401, 89, 28, 235, 233, 90, 0, 29, 0, 91, 30, 243, 252, 248, 250, 258, 257, 0, 92, 259, 31, 93, 32, 0, 94, 33, 264, 263, 95, 34, 267, 96, 269, 35, 97, 36, 271, 98, 37, 0, 99, 0, 39, 0, 100, 420, 38, 101, 40, 282, 102, 41, 286, 0, 205, 103, 42, 294, 292, 104, 43, 298, 105, 44, 301, 106, 45, 107, 46, 305, 108, 47, 256, 308, 109, 48, 256, 311, 110, 49, 111, 50, 0, 112, 51, 404, 406, 409, 113, 52, 411, 114, 53, 0, 115, 54, 0, 116, 55, 320, 0, 117, 428, 56, 118, 57, 205, 119, 58, 205, 120, 59, 326, 121, 60, 205, 122, 0, 61, 123, 62, 0, 124, 63, 333, 125, 64, 320, 126, 65, 415, 127, 0, 344, 0, 66, 342, 128, 67, 320, 129, 68, 130, 69, 131, 70, 347, 132, 423, 71, 133, 72, 0, 134, 73, 356, 353, 354, 135, 74, 205, 136, 75, 0, 137, 76, 365, 138, 0, 77, 0, 370, 378, 205, 374, 139, 78, 383, 384, 140, 79, 413, 16, 10, 80, 387, 204, 205, 0, 217, 214, 0, 0, 228, 226, 231, 422, 0, 391, 0, 0, 0, 234, 240, 238, 244, 247, 251, 253, 261, 0, 268, 0, 0, 279, 277, 283, 287, 288, 285, 0, 293, 299, 302, 306, 309, 312, 315, 0, 0, 317, 418, 319, 0, 425, 427, 205, 329, 317, 432, 335, 340, 416, 335, 337, 324, 348, 351, 0, 358, 355, 361, 363, 0, 367, 371, 0, 368, 375, 382, 0, 0, 388, 203, 206, 221, 224, 0, 212, 211, 209, 392, 397, 394, 399, 236, 0, 0, 265, 272, 0, 0, 0, 295, 402, 405, 407, 0, 321, 327, 205, 345, 0, 357, 0, 0, 0, 379, 0, 0, 17, 205, 210, 0, 0, 205, 254, 0, 205, 289, 296, 0, 419, 0, 334, 338, 359, 369, 372, 0, 376, 385, 229, 393, 395, 241, 0, 0, 280, 0, 403, 205, 373, 380, 377, 255, 0, 290, 322, 0, 0, 0, 0, 274, 275 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 2, 7, 8, 9, 15, 147, 10, 14, 11, 12, 17, 409, 707, 16, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 211, 212, 417, 232, 643, 748, 716, 215, 216, 420, 218, 219, 637, 427, 638, 222, 223, 429, 713, 226, 239, 240, 648, 450, 243, 244, 452, 722, 246, 247, 651, 248, 249, 250, 251, 653, 252, 723, 772, 499, 255, 258, 260, 261, 656, 263, 264, 657, 267, 269, 270, 658, 272, 273, 790, 276, 277, 487, 727, 282, 283, 662, 285, 286, 500, 663, 728, 775, 288, 289, 667, 666, 756, 291, 292, 668, 294, 295, 669, 298, 300, 301, 670, 303, 304, 306, 307, 310, 313, 322, 327, 328, 329, 759, 369, 340, 341, 682, 343, 344, 348, 353, 354, 686, 364, 580, 738, 357, 365, 366, 377, 378, 692, 384, 386, 387, 602, 603, 696, 389, 390, 393, 396, 399, 400, 401, 619, 742, 778, 744, 780, 620, 702, 765, 403, 404, 405, 706, 411, 412, 708, 233, 234, 718, 720, 446, 645, 646, 236, 237, 731, 533, 674, 675, 315, 316, 318, 319, 407, 408, 359, 360, 688, 324, 325, 733, 280, 229, 381, 334, 335, 337, 338, 332, 372, 375, 351 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -413 static const yytype_int16 yypact[] = { -413, 90, 99, -413, -37, -413, -413, -413, -413, -413, -413, -413, -413, -413, 18, 119, 506, 133, 568, 152, -413, 77, 107, 139, 145, 168, 177, 194, 198, 199, 200, 201, 202, 203, 204, 206, 208, 209, 210, 211, 216, 217, 221, 222, 223, 225, 228, 229, 230, 231, 232, 233, 234, 239, 240, 244, 254, 255, 256, 259, 260, 261, 262, 263, 266, 270, 273, 274, 277, 278, 280, 281, 283, 284, 285, 286, 287, 288, 289, 291, 294, 295, -413, -413, 58, 147, 120, 20, 205, 207, 212, 67, 81, 34, 17, 213, 214, 123, 257, 219, 258, 64, 37, 220, 264, 23, 95, 267, 268, 226, 88, 29, 42, 227, 235, 73, 100, 236, 271, 31, 237, 48, 56, 111, 62, 241, 242, 272, 70, 275, 11, 78, 243, 247, 128, 248, 83, 276, 68, 252, 16, 253, 279, 125, -413, -413, -413, 87, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 136, 215, 66, -413, 224, 245, 69, -413, 246, 72, 167, 269, -413, 75, -413, 301, -413, 79, 302, -413, 82, 303, 238, -413, -413, 85, 304, 305, 164, 306, 307, 282, 308, -413, 89, -413, 309, 310, 290, 218, -413, -413, 292, 140, 311, -413, 312, 314, -413, 91, 315, 92, 167, 316, 317, 319, 318, -413, 320, 321, 322, 327, 323, 324, 300, 325, -413, 93, -413, 326, -413, 328, 329, 330, 332, 331, 333, 132, 334, 101, 282, 335, 337, 336, 338, 339, 341, 340, -413, 342, 343, 344, 347, 345, 102, 132, 346, 103, 132, 348, -413, 350, 351, -413, 49, 352, 353, 265, 354, 355, 164, 356, -413, 104, 357, 358, 359, 360, 105, -413, 140, 361, -413, 362, 363, 365, 132, 366, 367, 132, 368, 369, 282, 370, 371, 132, 372, 373, 374, 375, 377, -413, 112, 378, 380, 399, 381, -413, 113, 382, 383, 407, 384, -40, -413, -413, 15, -413, 385, -413, 114, 386, -413, 387, 388, -413, 389, 390, 391, 408, 392, -413, 393, 394, -413, 115, 395, 396, 421, 397, 398, 132, 400, -413, 116, 401, -413, 19, 402, 403, 122, -413, 9, 404, 124, -413, 427, 405, 409, 265, 435, 410, 411, 450, -413, 478, -413, 486, 251, -413, 487, -413, -413, 491, -413, -413, -413, 413, -413, -413, 488, -413, 412, -413, -413, 494, -413, -413, 495, -413, -413, -413, 487, -413, -413, -413, -413, -413, -413, -413, 414, -413, -413, 492, -413, 415, -413, -413, -413, 497, 251, -413, -413, -413, 417, -413, 251, -413, -413, -413, 491, -413, -413, -413, -413, -413, -413, -413, -413, 251, -413, -413, -413, -413, -413, -413, 422, -413, 501, -413, 420, -413, 251, -413, -413, -413, -413, -413, -413, -413, 423, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 132, -413, -413, -413, 132, -413, -413, -413, -413, -413, 508, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 509, -413, -413, 512, -413, -413, -413, 425, -413, 251, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 513, -413, -413, -413, 514, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 515, -413, 349, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 251, -413, -413, -413, 516, -413, -413, 196, -413, 518, -413, -413, -413, -413, -413, 519, -413, -413, -413, -413, 520, -413, 521, 439, -413, -413, 565, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 487, -413, -413, 167, 245, -413, -413, -413, -413, 39, -413, 487, 487, 510, -413, -413, -413, -413, -413, -413, -413, -413, 167, -413, 649, 651, -413, -413, -413, -413, -413, 251, 282, -413, -413, -413, -413, -413, -413, -413, 487, 487, -413, -413, -413, 647, 251, 251, -413, 251, 573, -413, 563, -413, -413, 563, -413, -413, -413, -413, 655, 564, -413, 251, -413, 575, -413, -413, 639, 251, -413, -413, 9, 579, -413, 251, -413, -413, -413, 571, -413, -413, -413, -413, 576, -413, 577, -413, 574, 659, -413, -413, 654, 578, 661, -413, -413, 583, 577, 668, -413, 251, -413, -413, 580, -413, 670, 672, 671, -413, 674, 673, -413, -413, -413, 487, 487, -413, -413, 676, -413, -413, -413, 487, -413, 588, 251, -413, -413, -413, -413, 584, -413, -413, 251, -413, -413, 251, 589, 680, 251, 592, -413, -413, -413, -413, -413, -413, 598, -413, 251, 683, 600, 685, 299, -413, -413 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -413, -413, -413, -413, -413, -413, -413, -413, 176, -413, -413, -413, -413, -413, -413, 677, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -91, -250, -412, -413, -413, -413, -413, -90, -314, -413, -413, -413, -260, -413, -413, -80, -413, -413, -413, -413, -413, -413, -286, -413, -96, -413, -413, -413, -413, -413, -413, -99, -413, -413, -413, -413, -413, -413, -212, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -123, -413, -413, -413, -413, -413, -413, -413, -293, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 566, -413, -126, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -353, -413, -413, -413, -413, -130, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -253, -413, -16, -413, -413, -413, -413, -413, -413, -413, -413, 71, -413, -413, -413, -413, -413, 293, -413, -413, 21, 376, -413, -413, -413, -413, -413, 296, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -427 static const yytype_int16 yytable[] = { 459, 473, 356, 504, 465, 368, 257, 635, 266, 579, 395, 519, 361, 617, 523, 362, 478, 394, 245, 362, 362, 220, -252, 362, 284, -249, -242, -252, -284, 491, 302, -284, 326, -284, -307, 241, -320, -307, 274, -307, 463, -320, 552, 305, 714, 555, 578, -310, 13, 333, -310, 561, -310, -424, 363, 558, -424, 336, -424, 209, 715, -426, 210, 342, -426, 271, -426, -328, 235, 388, -328, 355, -328, -360, 314, -320, -360, -273, -360, 367, -320, 548, 238, -320, 382, -400, -400, 383, -320, 299, 3, -408, -408, -232, -335, -304, 287, 606, 581, -335, 4, 317, 611, 5, 19, 363, 618, -291, -252, 363, 363, 221, 339, 363, -284, 5, 6, 546, -410, -410, -307, 217, -320, -325, 259, 242, 406, 20, 275, 376, 594, -218, 527, -310, -262, -346, 144, 461, 528, -424, 498, -201, 462, -412, -412, 461, -201, -426, 213, 415, 462, 214, 421, -328, 416, 424, 146, 422, 430, -360, 425, -320, 433, 431, 148, 436, -349, 434, 440, -320, 437, -349, 453, 441, 468, 471, 488, 454, 426, 469, 472, 489, 444, 445, 502, 517, 521, 538, 544, 503, 518, 522, 539, 545, 149, 566, 572, 584, 597, 608, 567, 573, 585, 598, 609, 615, 224, 622, 227, 225, 616, 228, 623, 230, 253, 256, 231, 254, 214, 413, 265, 278, 710, 210, 279, 671, 150, 296, 308, 672, 297, 309, 151, 717, 719, 582, 311, 320, 330, 312, 321, 331, 345, 349, 370, 346, 350, 371, 373, 379, 665, 374, 380, 391, 397, 152, 392, 398, 262, 268, -266, -270, 730, 719, 153, 281, 612, -281, 290, 293, -297, -300, 323, 352, -417, -332, 358, 385, -414, -352, 402, 154, -383, 531, 532, 155, 156, 157, 158, 159, 160, 161, 694, 162, 449, 163, 164, 165, 166, 457, 460, 414, 680, 167, 168, 681, 458, 418, 169, 170, 171, 683, 172, 485, 789, 173, 174, 175, 176, 177, 178, 179, 476, 410, 712, 633, 180, 181, 439, 423, 482, 182, 636, 736, 419, 495, 737, 769, 770, 507, 634, 183, 184, 185, 510, 776, 186, 187, 188, 189, 190, 640, 428, 191, 515, 690, 697, 192, 650, 652, 193, 194, 542, 700, 195, 196, 661, 197, 198, 703, 199, 200, 201, 202, 203, 204, 205, 711, 206, 655, 729, 207, 208, 709, 432, 435, 438, 442, 443, 447, 448, 451, 455, 456, 464, 466, 724, 467, 470, 474, 475, 477, 570, 479, 480, 481, 483, 484, 486, 490, 576, 492, 493, 494, 496, 592, 497, 501, 505, 678, 506, 508, 509, 511, 601, 512, 513, 514, 516, 520, 624, 524, 735, 525, 526, 529, 530, 534, 535, 537, 540, 541, 628, 543, 547, 549, 550, 687, 551, 553, 554, 556, 557, 559, 560, 562, -330, 631, 564, 691, 565, 568, 563, 569, 571, 574, 575, 577, 583, 586, 587, 588, 589, 590, 591, 593, 595, 596, 599, 600, 604, 605, 632, 607, 610, 613, 760, 621, 625, 614, 210, 231, 626, 629, 630, 214, 639, 768, 641, 642, 649, 771, -223, 221, 774, -249, 242, 647, 654, 660, 659, 275, 673, 676, 664, 677, 679, 684, 685, 689, 693, 695, 721, 698, 699, 398, 701, 784, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 145, 704, 725, 726, 734, -331, 363, 739, 743, 740, 741, 746, 747, 749, 750, 751, 752, 753, 755, 754, 757, 758, 762, 764, 761, 763, 766, 767, 773, 777, 781, 779, 782, 783, 785, 786, 787, 788, 18, 745, 347, 0, 0, 705, 536, 732, 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 644 }; static const yytype_int16 yycheck[] = { 250, 261, 128, 289, 254, 131, 96, 419, 99, 362, 140, 304, 1, 4, 307, 4, 266, 1, 1, 4, 4, 1, 5, 4, 1, 8, 9, 10, 5, 279, 1, 8, 1, 10, 5, 1, 5, 8, 1, 10, 252, 10, 335, 1, 5, 338, 86, 5, 85, 1, 8, 344, 10, 5, 94, 341, 8, 1, 10, 1, 21, 5, 4, 1, 8, 1, 10, 5, 1, 1, 8, 1, 10, 5, 1, 5, 8, 13, 10, 1, 10, 331, 1, 5, 1, 18, 19, 4, 10, 1, 0, 18, 19, 12, 83, 7, 1, 390, 83, 83, 1, 1, 83, 16, 86, 94, 97, 12, 91, 94, 94, 91, 1, 94, 91, 16, 17, 329, 18, 19, 91, 1, 91, 12, 1, 91, 1, 8, 91, 1, 380, 11, 83, 91, 11, 7, 3, 5, 89, 91, 8, 83, 10, 18, 19, 5, 88, 91, 1, 83, 10, 4, 83, 91, 88, 83, 4, 88, 83, 91, 88, 91, 83, 88, 87, 83, 83, 88, 83, 91, 88, 88, 83, 88, 83, 83, 83, 88, 11, 88, 88, 88, 18, 19, 83, 83, 83, 83, 83, 88, 88, 88, 88, 88, 87, 83, 83, 83, 83, 83, 88, 88, 88, 88, 88, 83, 1, 83, 1, 4, 88, 4, 88, 1, 1, 1, 4, 4, 4, 83, 1, 1, 634, 4, 4, 518, 87, 1, 1, 522, 4, 4, 87, 645, 646, 365, 1, 1, 1, 4, 4, 4, 1, 1, 1, 4, 4, 4, 1, 1, 500, 4, 4, 1, 1, 87, 4, 4, 1, 1, 3, 3, 674, 675, 87, 1, 396, 3, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 3, 3, 1, 87, 3, 18, 19, 87, 87, 87, 87, 87, 87, 87, 96, 87, 12, 87, 87, 87, 87, 9, 8, 86, 552, 87, 87, 555, 88, 83, 87, 87, 87, 561, 87, 13, 15, 87, 87, 87, 87, 87, 87, 87, 3, 147, 638, 416, 87, 87, 90, 83, 3, 87, 422, 686, 89, 3, 689, 749, 750, 3, 89, 87, 87, 87, 3, 757, 87, 87, 87, 87, 87, 431, 83, 87, 7, 6, 606, 87, 454, 458, 87, 87, 3, 616, 87, 87, 489, 87, 87, 619, 87, 87, 87, 87, 87, 87, 87, 637, 87, 469, 666, 87, 87, 633, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 656, 83, 83, 83, 83, 83, 3, 83, 83, 83, 83, 83, 83, 83, 3, 83, 83, 83, 83, 7, 83, 83, 83, 545, 83, 83, 83, 83, 3, 83, 83, 83, 83, 83, 3, 83, 682, 83, 83, 83, 83, 83, 83, 83, 83, 83, 7, 83, 83, 83, 83, 573, 83, 83, 83, 83, 83, 83, 83, 83, 83, 7, 83, 585, 83, 83, 88, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 4, 83, 83, 83, 736, 83, 83, 86, 4, 4, 83, 83, 83, 4, 8, 747, 4, 4, 8, 751, 89, 91, 754, 8, 91, 93, 91, 8, 88, 91, 4, 4, 91, 3, 91, 4, 4, 4, 4, 3, 12, 4, 4, 4, 87, 777, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 87, 4, 3, 8, 83, 94, 3, 20, 96, 86, 83, 92, 88, 88, 92, 8, 14, 8, 92, 88, 4, 3, 3, 95, 4, 3, 5, 3, 92, 92, 98, 3, 92, 87, 3, 87, 3, 12, 706, 125, -1, -1, 623, 319, 675, -1, -1, -1, -1, -1, -1, -1, 408, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 441 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { 0, 100, 101, 0, 1, 16, 17, 102, 103, 104, 107, 109, 110, 85, 108, 105, 114, 111, 114, 86, 8, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 3, 83, 4, 106, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 1, 4, 176, 177, 1, 4, 183, 184, 1, 186, 187, 1, 91, 191, 192, 1, 4, 195, 1, 4, 343, 1, 4, 179, 317, 318, 1, 324, 325, 1, 196, 197, 1, 91, 200, 201, 1, 204, 205, 207, 208, 209, 210, 212, 1, 4, 216, 1, 184, 217, 1, 218, 219, 1, 221, 222, 1, 177, 224, 1, 225, 226, 1, 228, 229, 1, 91, 231, 232, 1, 4, 342, 1, 235, 236, 1, 238, 239, 1, 244, 245, 1, 249, 250, 1, 252, 253, 1, 4, 255, 1, 256, 257, 1, 259, 260, 1, 261, 262, 1, 4, 263, 1, 4, 264, 1, 330, 331, 1, 332, 333, 1, 4, 265, 1, 339, 340, 1, 266, 267, 268, 1, 4, 349, 1, 345, 346, 1, 347, 348, 1, 271, 272, 1, 274, 275, 1, 4, 265, 276, 1, 4, 352, 1, 277, 278, 1, 267, 283, 1, 336, 337, 1, 4, 94, 280, 284, 285, 1, 267, 270, 1, 4, 350, 1, 4, 351, 1, 286, 287, 1, 4, 344, 1, 4, 289, 1, 290, 291, 1, 295, 296, 1, 4, 297, 1, 285, 298, 1, 4, 299, 300, 301, 1, 310, 311, 312, 1, 334, 335, 112, 107, 314, 315, 83, 86, 83, 88, 178, 83, 89, 185, 83, 88, 83, 83, 88, 11, 189, 83, 193, 83, 88, 83, 83, 88, 83, 83, 88, 83, 90, 83, 88, 83, 83, 18, 19, 321, 83, 83, 12, 199, 83, 202, 83, 88, 83, 83, 9, 88, 178, 8, 5, 10, 215, 83, 178, 83, 83, 83, 88, 83, 83, 88, 189, 83, 83, 3, 83, 178, 83, 83, 83, 3, 83, 83, 13, 83, 233, 83, 88, 83, 178, 83, 83, 83, 3, 83, 83, 8, 215, 240, 83, 83, 88, 199, 83, 83, 3, 83, 83, 3, 83, 83, 83, 83, 7, 83, 83, 88, 240, 83, 83, 88, 240, 83, 83, 83, 83, 89, 83, 83, 18, 19, 327, 83, 83, 321, 83, 83, 88, 83, 83, 3, 83, 83, 88, 215, 83, 178, 83, 83, 83, 240, 83, 83, 240, 83, 83, 199, 83, 83, 240, 83, 88, 83, 83, 83, 88, 83, 83, 3, 83, 83, 88, 83, 83, 3, 83, 86, 280, 281, 83, 285, 83, 83, 88, 83, 83, 83, 83, 83, 83, 7, 83, 178, 83, 83, 83, 88, 83, 83, 3, 292, 293, 83, 83, 240, 83, 83, 88, 83, 83, 285, 83, 86, 83, 88, 4, 97, 302, 307, 83, 83, 88, 3, 83, 83, 327, 7, 83, 83, 7, 4, 177, 89, 179, 184, 188, 190, 8, 192, 4, 4, 180, 317, 322, 323, 93, 198, 8, 201, 206, 208, 211, 91, 184, 220, 223, 227, 88, 8, 232, 237, 241, 91, 178, 247, 246, 251, 254, 258, 240, 240, 4, 328, 329, 4, 3, 267, 91, 178, 178, 273, 178, 4, 4, 279, 267, 338, 4, 6, 267, 288, 4, 96, 3, 294, 178, 4, 4, 300, 87, 308, 178, 87, 311, 313, 113, 316, 178, 179, 189, 185, 194, 5, 21, 182, 179, 319, 179, 320, 12, 203, 213, 189, 4, 3, 234, 242, 199, 179, 326, 320, 341, 8, 178, 280, 280, 282, 3, 96, 86, 303, 20, 305, 302, 83, 92, 181, 88, 88, 92, 8, 14, 92, 8, 248, 88, 4, 269, 178, 95, 3, 4, 3, 309, 3, 5, 178, 179, 179, 178, 214, 3, 178, 243, 179, 92, 304, 98, 306, 92, 3, 92, 178, 87, 3, 87, 3, 15, 230 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex () #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule) #else static void yy_reduce_print (yyvsp, yyrule) YYSTYPE *yyvsp; int yyrule; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void yydestruct (yymsg, yytype, yyvaluep) const char *yymsg; int yytype; YYSTYPE *yyvaluep; #endif { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { case 4: /* "T_TOKEN" */ #line 164 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2025 "parser.cxx" break; case 5: /* "T_QSTRING" */ #line 165 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2030 "parser.cxx" break; case 6: /* "T_COMMENT" */ #line 166 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2035 "parser.cxx" break; case 7: /* "T_LINE" */ #line 167 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2040 "parser.cxx" break; case 8: /* "T_URI" */ #line 168 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2045 "parser.cxx" break; case 10: /* "T_DISPLAY" */ #line 169 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2050 "parser.cxx" break; case 11: /* "T_LANG" */ #line 170 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2055 "parser.cxx" break; case 12: /* "T_WORD" */ #line 171 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2060 "parser.cxx" break; case 17: /* "T_METHOD" */ #line 172 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2065 "parser.cxx" break; case 19: /* "T_AUTH_OTHER" */ #line 173 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2070 "parser.cxx" break; case 20: /* "T_IPV6ADDR" */ #line 174 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2075 "parser.cxx" break; case 21: /* "T_PARAMVAL" */ #line 175 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2080 "parser.cxx" break; case 82: /* "T_HDR_UNKNOWN" */ #line 176 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2085 "parser.cxx" break; case 107: /* "sip_version" */ #line 239 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2090 "parser.cxx" break; case 177: /* "media_range" */ #line 232 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_media)); delete (yyvaluep->yyt_media); }; #line 2095 "parser.cxx" break; case 178: /* "parameters" */ #line 235 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_params)); delete (yyvaluep->yyt_params); }; #line 2100 "parser.cxx" break; case 179: /* "parameter" */ #line 233 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_param)); delete (yyvaluep->yyt_param); }; #line 2105 "parser.cxx" break; case 182: /* "parameter_val" */ #line 234 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2110 "parser.cxx" break; case 184: /* "content_coding" */ #line 220 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_coding)); delete (yyvaluep->yyt_coding); }; #line 2115 "parser.cxx" break; case 189: /* "language" */ #line 231 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_language)); delete (yyvaluep->yyt_language); }; #line 2120 "parser.cxx" break; case 192: /* "alert_param" */ #line 212 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_alert_param)); delete (yyvaluep->yyt_alert_param); }; #line 2125 "parser.cxx" break; case 199: /* "call_id" */ #line 214 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2130 "parser.cxx" break; case 201: /* "info_param" */ #line 230 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_info_param)); delete (yyvaluep->yyt_info_param); }; #line 2135 "parser.cxx" break; case 207: /* "contacts" */ #line 219 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_contacts)); delete (yyvaluep->yyt_contacts); }; #line 2140 "parser.cxx" break; case 208: /* "contact_param" */ #line 218 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_contact)); delete (yyvaluep->yyt_contact); }; #line 2145 "parser.cxx" break; case 209: /* "contact_addr" */ #line 217 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_contact)); delete (yyvaluep->yyt_contact); }; #line 2150 "parser.cxx" break; case 215: /* "display_name" */ #line 224 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2155 "parser.cxx" break; case 232: /* "error_param" */ #line 225 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_error_param)); delete (yyvaluep->yyt_error_param); }; #line 2160 "parser.cxx" break; case 240: /* "from_addr" */ #line 226 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_from_addr)); delete (yyvaluep->yyt_from_addr); }; #line 2165 "parser.cxx" break; case 267: /* "rec_route" */ #line 236 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_route)); delete (yyvaluep->yyt_route); }; #line 2170 "parser.cxx" break; case 280: /* "comment" */ #line 216 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2175 "parser.cxx" break; case 285: /* "server" */ #line 238 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_server)); delete (yyvaluep->yyt_server); }; #line 2180 "parser.cxx" break; case 300: /* "via_parm" */ #line 240 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_via)); delete (yyvaluep->yyt_via); }; #line 2185 "parser.cxx" break; case 301: /* "sent_protocol" */ #line 237 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_via)); delete (yyvaluep->yyt_via); }; #line 2190 "parser.cxx" break; case 302: /* "host" */ #line 228 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_via)); delete (yyvaluep->yyt_via); }; #line 2195 "parser.cxx" break; case 307: /* "ipv6reference" */ #line 229 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2200 "parser.cxx" break; case 311: /* "warning" */ #line 241 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_warning)); delete (yyvaluep->yyt_warning); }; #line 2205 "parser.cxx" break; case 314: /* "hdr_unknown" */ #line 227 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_str)); delete (yyvaluep->yyt_str); }; #line 2210 "parser.cxx" break; case 319: /* "digest_response" */ #line 223 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_dig_resp)); delete (yyvaluep->yyt_dig_resp); }; #line 2215 "parser.cxx" break; case 320: /* "auth_params" */ #line 213 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_params)); delete (yyvaluep->yyt_params); }; #line 2220 "parser.cxx" break; case 321: /* "credentials" */ #line 221 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_credentials)); delete (yyvaluep->yyt_credentials); }; #line 2225 "parser.cxx" break; case 326: /* "digest_challenge" */ #line 222 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_dig_chlg)); delete (yyvaluep->yyt_dig_chlg); }; #line 2230 "parser.cxx" break; case 327: /* "challenge" */ #line 215 "parser.yxx" { MEMMAN_DELETE((yyvaluep->yyt_challenge)); delete (yyvaluep->yyt_challenge); }; #line 2235 "parser.cxx" break; default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (void); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void) #else int yyparse () #endif #endif { int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 244 "parser.yxx" { CTXT_NEW; } break; case 6: #line 249 "parser.yxx" { /* KLUDGE to work around a memory leak in bison. * T_NULL does never match, so the parser never * gets here. The error keyword causes bison * to eat all input and destroy all tokens returned * by the parser. * Without this workaround the following input causes * the parser to leak: * * INVITE INVITE .... * * In request_line a T_METHOD is returned as look ahead * token when bison tries to match sip_version. * This does not match, but the look ahead token is * never destructed by Bison. */ YYABORT; } break; case 7: #line 269 "parser.yxx" { /* Parsing stops here. Remaining text is * not parsed. */ YYACCEPT; } break; case 8: #line 278 "parser.yxx" { CTXT_URI; } break; case 9: #line 278 "parser.yxx" { CTXT_NEW; } break; case 10: #line 279 "parser.yxx" { MSG = new t_request(); MEMMAN_NEW(MSG); ((t_request *)MSG)->set_method(*(yyvsp[(1) - (6)].yyt_str)); ((t_request *)MSG)->uri.set_url(*(yyvsp[(3) - (6)].yyt_str)); MSG->version = *(yyvsp[(5) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(1) - (6)].yyt_str)); delete (yyvsp[(1) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (6)].yyt_str)); delete (yyvsp[(3) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(5) - (6)].yyt_str)); delete (yyvsp[(5) - (6)].yyt_str); if (!((t_request *)MSG)->uri.is_valid()) { MEMMAN_DELETE(MSG); delete MSG; MSG = NULL; YYABORT; } } break; case 11: #line 296 "parser.yxx" { CTXT_INITIAL; } break; case 12: #line 296 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(4) - (4)].yyt_str); } break; case 13: #line 300 "parser.yxx" { /* Parsing stops here. Remaining text is * not parsed. */ YYACCEPT; } break; case 14: #line 307 "parser.yxx" { CTXT_NUM; } break; case 15: #line 307 "parser.yxx" { CTXT_LINE; } break; case 16: #line 308 "parser.yxx" { CTXT_INITIAL; } break; case 17: #line 308 "parser.yxx" { MSG = new t_response(); MEMMAN_NEW(MSG); MSG->version = *(yyvsp[(1) - (7)].yyt_str); ((t_response *)MSG)->code = (yyvsp[(3) - (7)].yyt_ulong); ((t_response *)MSG)->reason = trim(*(yyvsp[(5) - (7)].yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (7)].yyt_str)); delete (yyvsp[(1) - (7)].yyt_str); MEMMAN_DELETE((yyvsp[(5) - (7)].yyt_str)); delete (yyvsp[(5) - (7)].yyt_str); } break; case 80: #line 382 "parser.yxx" { MSG->add_unknown_header(*(yyvsp[(1) - (4)].yyt_str), trim(*(yyvsp[(3) - (4)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (4)].yyt_str)); delete (yyvsp[(1) - (4)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (4)].yyt_str)); delete (yyvsp[(3) - (4)].yyt_str); } break; case 81: #line 387 "parser.yxx" { PARSE_ERROR("Accept"); } break; case 82: #line 389 "parser.yxx" { PARSE_ERROR("Accept-Encoding"); } break; case 83: #line 391 "parser.yxx" { PARSE_ERROR("Accept-Language"); } break; case 84: #line 393 "parser.yxx" { PARSE_ERROR("Alert-Info"); } break; case 85: #line 395 "parser.yxx" { PARSE_ERROR("Allow"); } break; case 86: #line 397 "parser.yxx" { PARSE_ERROR("Allow-Events"); } break; case 87: #line 399 "parser.yxx" { PARSE_ERROR("Authentication-Info"); } break; case 88: #line 401 "parser.yxx" { PARSE_ERROR("Authorization"); } break; case 89: #line 403 "parser.yxx" { PARSE_ERROR("Call-ID"); } break; case 90: #line 405 "parser.yxx" { PARSE_ERROR("Call-Info"); } break; case 91: #line 407 "parser.yxx" { PARSE_ERROR("Contact"); } break; case 92: #line 409 "parser.yxx" { PARSE_ERROR("Content-Disposition"); } break; case 93: #line 411 "parser.yxx" { PARSE_ERROR("Content-Encoding"); } break; case 94: #line 413 "parser.yxx" { PARSE_ERROR("Content-Language"); } break; case 95: #line 415 "parser.yxx" { PARSE_ERROR("Content-Length"); } break; case 96: #line 417 "parser.yxx" { PARSE_ERROR("Content-Type"); } break; case 97: #line 419 "parser.yxx" { PARSE_ERROR("CSeq"); } break; case 98: #line 421 "parser.yxx" { PARSE_ERROR("Date"); } break; case 99: #line 423 "parser.yxx" { PARSE_ERROR("Error-Info"); } break; case 100: #line 425 "parser.yxx" { PARSE_ERROR("Event"); } break; case 101: #line 427 "parser.yxx" { PARSE_ERROR("Expires"); } break; case 102: #line 429 "parser.yxx" { PARSE_ERROR("From"); } break; case 103: #line 431 "parser.yxx" { PARSE_ERROR("In-Reply-To"); } break; case 104: #line 433 "parser.yxx" { PARSE_ERROR("Max-Forwards"); } break; case 105: #line 435 "parser.yxx" { PARSE_ERROR("Min-Expires"); } break; case 106: #line 437 "parser.yxx" { PARSE_ERROR("MIME-Version"); } break; case 107: #line 439 "parser.yxx" { PARSE_ERROR("Organization"); } break; case 108: #line 441 "parser.yxx" { PARSE_ERROR("P-Asserted-Identity"); } break; case 109: #line 443 "parser.yxx" { PARSE_ERROR("P-Preferred-Identity"); } break; case 110: #line 445 "parser.yxx" { PARSE_ERROR("Priority"); } break; case 111: #line 447 "parser.yxx" { PARSE_ERROR("Privacy"); } break; case 112: #line 449 "parser.yxx" { PARSE_ERROR("Proxy-Authenticate"); } break; case 113: #line 451 "parser.yxx" { PARSE_ERROR("Proxy-Authorization"); } break; case 114: #line 453 "parser.yxx" { PARSE_ERROR("Proxy-Require"); } break; case 115: #line 455 "parser.yxx" { PARSE_ERROR("RAck"); } break; case 116: #line 457 "parser.yxx" { PARSE_ERROR("Record-Route"); } break; case 117: #line 459 "parser.yxx" { PARSE_ERROR("Refer-Sub"); } break; case 118: #line 461 "parser.yxx" { PARSE_ERROR("Refer-To"); } break; case 119: #line 463 "parser.yxx" { PARSE_ERROR("Referred-By"); } break; case 120: #line 465 "parser.yxx" { PARSE_ERROR("Replaces"); } break; case 121: #line 467 "parser.yxx" { PARSE_ERROR("Reply-To"); } break; case 122: #line 469 "parser.yxx" { PARSE_ERROR("Require"); } break; case 123: #line 471 "parser.yxx" { PARSE_ERROR("Request-Disposition"); } break; case 124: #line 473 "parser.yxx" { PARSE_ERROR("Retry-After"); } break; case 125: #line 475 "parser.yxx" { PARSE_ERROR("Route"); } break; case 126: #line 477 "parser.yxx" { PARSE_ERROR("RSeq"); } break; case 127: #line 479 "parser.yxx" { PARSE_ERROR("Server"); } break; case 128: #line 481 "parser.yxx" { PARSE_ERROR("Service-Route"); } break; case 129: #line 483 "parser.yxx" { PARSE_ERROR("SIP-ETag"); } break; case 130: #line 485 "parser.yxx" { PARSE_ERROR("SIP-If-Match"); } break; case 131: #line 487 "parser.yxx" { PARSE_ERROR("Subject"); } break; case 132: #line 489 "parser.yxx" { PARSE_ERROR("Subscription-State"); } break; case 133: #line 491 "parser.yxx" { PARSE_ERROR("Supported"); } break; case 134: #line 493 "parser.yxx" { PARSE_ERROR("Timestamp"); } break; case 135: #line 495 "parser.yxx" { PARSE_ERROR("To"); } break; case 136: #line 497 "parser.yxx" { PARSE_ERROR("Unsupported"); } break; case 137: #line 499 "parser.yxx" { PARSE_ERROR("User-Agent"); } break; case 138: #line 501 "parser.yxx" { PARSE_ERROR("Via"); } break; case 139: #line 503 "parser.yxx" { PARSE_ERROR("Warning"); } break; case 140: #line 505 "parser.yxx" { PARSE_ERROR("WWW-Authenticate"); } break; case 143: #line 521 "parser.yxx" { CTXT_LANG; } break; case 148: #line 531 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 149: #line 533 "parser.yxx" { CTXT_WORD; } break; case 151: #line 537 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 154: #line 543 "parser.yxx" { CTXT_LANG; } break; case 155: #line 545 "parser.yxx" { CTXT_NUM; } break; case 157: #line 549 "parser.yxx" { CTXT_NUM; } break; case 158: #line 551 "parser.yxx" { CTXT_DATE;} break; case 161: #line 557 "parser.yxx" { CTXT_NUM; } break; case 162: #line 559 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 163: #line 561 "parser.yxx" { CTXT_WORD; } break; case 164: #line 563 "parser.yxx" { CTXT_NUM; } break; case 165: #line 565 "parser.yxx" { CTXT_NUM; } break; case 167: #line 569 "parser.yxx" { CTXT_LINE; } break; case 168: #line 571 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 169: #line 573 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 172: #line 579 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 173: #line 581 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 175: #line 585 "parser.yxx" { CTXT_NUM; } break; case 176: #line 587 "parser.yxx" { CTXT_URI; } break; case 178: #line 591 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 179: #line 593 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 180: #line 595 "parser.yxx" { CTXT_WORD; } break; case 181: #line 597 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 184: #line 603 "parser.yxx" { CTXT_NUM; } break; case 185: #line 605 "parser.yxx" { CTXT_URI; } break; case 186: #line 607 "parser.yxx" { CTXT_NUM; } break; case 188: #line 611 "parser.yxx" { CTXT_URI; } break; case 191: #line 617 "parser.yxx" { CTXT_LINE; } break; case 194: #line 623 "parser.yxx" { CTXT_NUM; } break; case 195: #line 625 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 199: #line 633 "parser.yxx" { CTXT_NUM; } break; case 200: #line 635 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 202: #line 639 "parser.yxx" { (yyvsp[(1) - (2)].yyt_media)->add_params(*(yyvsp[(2) - (2)].yyt_params)); MSG->hdr_accept.add_media(*(yyvsp[(1) - (2)].yyt_media)); MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_media)); delete (yyvsp[(1) - (2)].yyt_media); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 203: #line 644 "parser.yxx" { (yyvsp[(3) - (4)].yyt_media)->add_params(*(yyvsp[(4) - (4)].yyt_params)); MSG->hdr_accept.add_media(*(yyvsp[(3) - (4)].yyt_media)); MEMMAN_DELETE((yyvsp[(3) - (4)].yyt_media)); delete (yyvsp[(3) - (4)].yyt_media); MEMMAN_DELETE((yyvsp[(4) - (4)].yyt_params)); delete (yyvsp[(4) - (4)].yyt_params); } break; case 204: #line 651 "parser.yxx" { (yyval.yyt_media) = new t_media(tolower(*(yyvsp[(1) - (3)].yyt_str)), tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_NEW((yyval.yyt_media)); MEMMAN_DELETE((yyvsp[(1) - (3)].yyt_str)); delete (yyvsp[(1) - (3)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 205: #line 657 "parser.yxx" { (yyval.yyt_params) = new list; MEMMAN_NEW((yyval.yyt_params)); } break; case 206: #line 658 "parser.yxx" { (yyvsp[(1) - (3)].yyt_params)->push_back(*(yyvsp[(3) - (3)].yyt_param)); (yyval.yyt_params) = (yyvsp[(1) - (3)].yyt_params); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_param)); delete (yyvsp[(3) - (3)].yyt_param); } break; case 207: #line 664 "parser.yxx" { (yyval.yyt_param) = new t_parameter(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_NEW((yyval.yyt_param)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 208: #line 668 "parser.yxx" { CTXT_PARAMVAL; } break; case 209: #line 668 "parser.yxx" { CTXT_INITIAL; } break; case 210: #line 668 "parser.yxx" { (yyval.yyt_param) = new t_parameter(tolower(*(yyvsp[(1) - (5)].yyt_str)), *(yyvsp[(4) - (5)].yyt_str)); MEMMAN_NEW((yyval.yyt_param)); MEMMAN_DELETE((yyvsp[(1) - (5)].yyt_str)); delete (yyvsp[(1) - (5)].yyt_str); MEMMAN_DELETE((yyvsp[(4) - (5)].yyt_str)); delete (yyvsp[(4) - (5)].yyt_str); } break; case 211: #line 675 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(1) - (1)].yyt_str); } break; case 212: #line 677 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(1) - (1)].yyt_str); } break; case 213: #line 681 "parser.yxx" { MSG->hdr_accept_encoding.add_coding(*(yyvsp[(1) - (1)].yyt_coding)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_coding)); delete (yyvsp[(1) - (1)].yyt_coding); } break; case 214: #line 684 "parser.yxx" { MSG->hdr_accept_encoding.add_coding(*(yyvsp[(3) - (3)].yyt_coding)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_coding)); delete (yyvsp[(3) - (3)].yyt_coding); } break; case 215: #line 689 "parser.yxx" { (yyval.yyt_coding) = new t_coding(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_NEW((yyval.yyt_coding)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 216: #line 693 "parser.yxx" { (yyval.yyt_coding) = new t_coding(tolower(*(yyvsp[(1) - (2)].yyt_str))); MEMMAN_NEW((yyval.yyt_coding)); (yyval.yyt_coding)->q = (yyvsp[(2) - (2)].yyt_float); MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); } break; case 217: #line 700 "parser.yxx" { if ((yyvsp[(2) - (2)].yyt_param)->name != "q") YYERROR; (yyval.yyt_float) = atof((yyvsp[(2) - (2)].yyt_param)->value.c_str()); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_param)); delete (yyvsp[(2) - (2)].yyt_param); } break; case 218: #line 707 "parser.yxx" { CTXT_LANG; } break; case 219: #line 707 "parser.yxx" { MSG->hdr_accept_language.add_language(*(yyvsp[(2) - (2)].yyt_language)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_language)); delete (yyvsp[(2) - (2)].yyt_language); } break; case 220: #line 710 "parser.yxx" { CTXT_LANG; } break; case 221: #line 710 "parser.yxx" { MSG->hdr_accept_language.add_language(*(yyvsp[(4) - (4)].yyt_language)); MEMMAN_DELETE((yyvsp[(4) - (4)].yyt_language)); delete (yyvsp[(4) - (4)].yyt_language); } break; case 222: #line 715 "parser.yxx" { CTXT_INITIAL; (yyval.yyt_language) = new t_language(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_NEW((yyval.yyt_language)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 223: #line 720 "parser.yxx" { CTXT_INITIAL; } break; case 224: #line 720 "parser.yxx" { (yyval.yyt_language) = new t_language(tolower(*(yyvsp[(1) - (3)].yyt_str))); MEMMAN_NEW((yyval.yyt_language)); (yyval.yyt_language)->q = (yyvsp[(3) - (3)].yyt_float); MEMMAN_DELETE((yyvsp[(1) - (3)].yyt_str)); delete (yyvsp[(1) - (3)].yyt_str); } break; case 225: #line 727 "parser.yxx" { MSG->hdr_alert_info.add_param(*(yyvsp[(1) - (1)].yyt_alert_param)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_alert_param)); delete (yyvsp[(1) - (1)].yyt_alert_param); } break; case 226: #line 730 "parser.yxx" { MSG->hdr_alert_info.add_param(*(yyvsp[(3) - (3)].yyt_alert_param)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_alert_param)); delete (yyvsp[(3) - (3)].yyt_alert_param); } break; case 227: #line 735 "parser.yxx" { CTXT_URI; } break; case 228: #line 735 "parser.yxx" { CTXT_INITIAL; } break; case 229: #line 735 "parser.yxx" { (yyval.yyt_alert_param) = new t_alert_param(); MEMMAN_NEW((yyval.yyt_alert_param)); (yyval.yyt_alert_param)->uri.set_url(*(yyvsp[(3) - (6)].yyt_str)); (yyval.yyt_alert_param)->parameter_list = *(yyvsp[(6) - (6)].yyt_params); if (!(yyval.yyt_alert_param)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_alert_param)); delete (yyval.yyt_alert_param); YYERROR; } MEMMAN_DELETE((yyvsp[(3) - (6)].yyt_str)); delete (yyvsp[(3) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(6) - (6)].yyt_params)); delete (yyvsp[(6) - (6)].yyt_params); } break; case 230: #line 750 "parser.yxx" { MSG->hdr_allow.add_method(*(yyvsp[(1) - (1)].yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 231: #line 753 "parser.yxx" { MSG->hdr_allow.add_method(*(yyvsp[(3) - (3)].yyt_str)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 232: #line 758 "parser.yxx" { CTXT_WORD; } break; case 233: #line 758 "parser.yxx" { CTXT_INITIAL; } break; case 234: #line 758 "parser.yxx" { MSG->hdr_call_id.set_call_id(*(yyvsp[(2) - (3)].yyt_str)); MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_str)); delete (yyvsp[(2) - (3)].yyt_str); } break; case 235: #line 763 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(1) - (1)].yyt_str); } break; case 236: #line 764 "parser.yxx" { (yyval.yyt_str) = new string(*(yyvsp[(1) - (3)].yyt_str) + '@' + *(yyvsp[(3) - (3)].yyt_str)); MEMMAN_NEW((yyval.yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (3)].yyt_str)); delete (yyvsp[(1) - (3)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 237: #line 771 "parser.yxx" { MSG->hdr_call_info.add_param(*(yyvsp[(1) - (1)].yyt_info_param)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_info_param)); delete (yyvsp[(1) - (1)].yyt_info_param); } break; case 238: #line 774 "parser.yxx" { MSG->hdr_call_info.add_param(*(yyvsp[(3) - (3)].yyt_info_param)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_info_param)); delete (yyvsp[(3) - (3)].yyt_info_param); } break; case 239: #line 779 "parser.yxx" { CTXT_URI; } break; case 240: #line 779 "parser.yxx" { CTXT_INITIAL; } break; case 241: #line 779 "parser.yxx" { (yyval.yyt_info_param) = new t_info_param(); MEMMAN_NEW((yyval.yyt_info_param)); (yyval.yyt_info_param)->uri.set_url(*(yyvsp[(3) - (6)].yyt_str)); (yyval.yyt_info_param)->parameter_list = *(yyvsp[(6) - (6)].yyt_params); if (!(yyval.yyt_info_param)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_info_param)); delete (yyval.yyt_info_param); YYERROR; } MEMMAN_DELETE((yyvsp[(3) - (6)].yyt_str)); delete (yyvsp[(3) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(6) - (6)].yyt_params)); delete (yyvsp[(6) - (6)].yyt_params); } break; case 242: #line 794 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 243: #line 794 "parser.yxx" { CTXT_INITIAL; } break; case 244: #line 794 "parser.yxx" { MSG->hdr_contact.set_any(); } break; case 245: #line 796 "parser.yxx" { MSG->hdr_contact.add_contacts(*(yyvsp[(1) - (1)].yyt_contacts)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_contacts)); delete (yyvsp[(1) - (1)].yyt_contacts); } break; case 246: #line 801 "parser.yxx" { (yyval.yyt_contacts) = new list; MEMMAN_NEW((yyval.yyt_contacts)); (yyval.yyt_contacts)->push_back(*(yyvsp[(1) - (1)].yyt_contact)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_contact)); delete (yyvsp[(1) - (1)].yyt_contact); } break; case 247: #line 806 "parser.yxx" { (yyvsp[(1) - (3)].yyt_contacts)->push_back(*(yyvsp[(3) - (3)].yyt_contact)); (yyval.yyt_contacts) = (yyvsp[(1) - (3)].yyt_contacts); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_contact)); delete (yyvsp[(3) - (3)].yyt_contact); } break; case 248: #line 812 "parser.yxx" { (yyval.yyt_contact) = (yyvsp[(1) - (2)].yyt_contact); list::const_iterator i; for (i = (yyvsp[(2) - (2)].yyt_params)->begin(); i != (yyvsp[(2) - (2)].yyt_params)->end(); i++) { if (i->name == "q") { (yyval.yyt_contact)->set_qvalue(atof(i->value.c_str())); } else if (i->name == "expires") { (yyval.yyt_contact)->set_expires(strtoul( i->value.c_str(), NULL, 10)); } else { (yyval.yyt_contact)->add_extension(*i); } } MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 249: #line 828 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 250: #line 828 "parser.yxx" { CTXT_INITIAL; } break; case 251: #line 828 "parser.yxx" { (yyval.yyt_contact) = new t_contact_param(); MEMMAN_NEW((yyval.yyt_contact)); (yyval.yyt_contact)->uri.set_url(*(yyvsp[(2) - (3)].yyt_str)); if (!(yyval.yyt_contact)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_contact)); delete (yyval.yyt_contact); YYERROR; } MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_str)); delete (yyvsp[(2) - (3)].yyt_str); } break; case 252: #line 839 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 253: #line 839 "parser.yxx" { CTXT_URI; } break; case 254: #line 839 "parser.yxx" { CTXT_INITIAL; } break; case 255: #line 839 "parser.yxx" { (yyval.yyt_contact) = new t_contact_param(); MEMMAN_NEW((yyval.yyt_contact)); (yyval.yyt_contact)->display = *(yyvsp[(2) - (7)].yyt_str); (yyval.yyt_contact)->uri.set_url(*(yyvsp[(5) - (7)].yyt_str)); if (!(yyval.yyt_contact)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_contact)); delete (yyval.yyt_contact); YYERROR; } MEMMAN_DELETE((yyvsp[(2) - (7)].yyt_str)); delete (yyvsp[(2) - (7)].yyt_str); MEMMAN_DELETE((yyvsp[(5) - (7)].yyt_str)); delete (yyvsp[(5) - (7)].yyt_str); } break; case 256: #line 854 "parser.yxx" { (yyval.yyt_str) = new string(); MEMMAN_NEW((yyval.yyt_str)); } break; case 257: #line 855 "parser.yxx" { (yyval.yyt_str) = new string(rtrim(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_NEW((yyval.yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 258: #line 859 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(1) - (1)].yyt_str); } break; case 259: #line 862 "parser.yxx" { MSG->hdr_content_disp.set_type(tolower(*(yyvsp[(1) - (2)].yyt_str))); list::const_iterator i; for (i = (yyvsp[(2) - (2)].yyt_params)->begin(); i != (yyvsp[(2) - (2)].yyt_params)->end(); i++) { if (i->name == "filename") { MSG->hdr_content_disp.set_filename(i->value); } else { MSG->hdr_content_disp.add_param(*i); } } MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 260: #line 878 "parser.yxx" { MSG->hdr_content_encoding.add_coding(*(yyvsp[(1) - (1)].yyt_coding)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_coding)); delete (yyvsp[(1) - (1)].yyt_coding); } break; case 261: #line 881 "parser.yxx" { MSG->hdr_content_encoding.add_coding(*(yyvsp[(3) - (3)].yyt_coding)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_coding)); delete (yyvsp[(3) - (3)].yyt_coding); } break; case 262: #line 886 "parser.yxx" { CTXT_LANG; } break; case 263: #line 886 "parser.yxx" { MSG->hdr_content_language.add_language(*(yyvsp[(2) - (2)].yyt_language)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_language)); delete (yyvsp[(2) - (2)].yyt_language); } break; case 264: #line 889 "parser.yxx" { CTXT_LANG; } break; case 265: #line 889 "parser.yxx" { MSG->hdr_content_language.add_language(*(yyvsp[(4) - (4)].yyt_language)); MEMMAN_DELETE((yyvsp[(4) - (4)].yyt_language)); delete (yyvsp[(4) - (4)].yyt_language); } break; case 266: #line 894 "parser.yxx" { CTXT_NUM; } break; case 267: #line 894 "parser.yxx" { CTXT_INITIAL; } break; case 268: #line 894 "parser.yxx" { MSG->hdr_content_length.set_length((yyvsp[(2) - (3)].yyt_ulong)); } break; case 269: #line 898 "parser.yxx" { (yyvsp[(1) - (2)].yyt_media)->add_params(*(yyvsp[(2) - (2)].yyt_params)); MSG->hdr_content_type.set_media(*(yyvsp[(1) - (2)].yyt_media)); MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_media)); delete (yyvsp[(1) - (2)].yyt_media); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 270: #line 905 "parser.yxx" { CTXT_NUM; } break; case 271: #line 905 "parser.yxx" { CTXT_INITIAL; } break; case 272: #line 905 "parser.yxx" { MSG->hdr_cseq.set_seqnr((yyvsp[(2) - (4)].yyt_ulong)); MSG->hdr_cseq.set_method(*(yyvsp[(4) - (4)].yyt_str)); MEMMAN_DELETE((yyvsp[(4) - (4)].yyt_str)); delete (yyvsp[(4) - (4)].yyt_str); } break; case 273: #line 911 "parser.yxx" { CTXT_DATE;} break; case 274: #line 914 "parser.yxx" { CTXT_INITIAL; } break; case 275: #line 914 "parser.yxx" { struct tm t; t.tm_mday = (yyvsp[(4) - (13)].yyt_ulong); t.tm_mon = (yyvsp[(5) - (13)].yyt_int); t.tm_year = (yyvsp[(6) - (13)].yyt_ulong) - 1900; t.tm_hour = (yyvsp[(7) - (13)].yyt_ulong); t.tm_min = (yyvsp[(9) - (13)].yyt_ulong); t.tm_sec = (yyvsp[(11) - (13)].yyt_ulong); MSG->hdr_date.set_date_gm(&t); } break; case 276: #line 925 "parser.yxx" { MSG->hdr_error_info.add_param(*(yyvsp[(1) - (1)].yyt_error_param)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_error_param)); delete (yyvsp[(1) - (1)].yyt_error_param); } break; case 277: #line 928 "parser.yxx" { MSG->hdr_error_info.add_param(*(yyvsp[(3) - (3)].yyt_error_param)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_error_param)); delete (yyvsp[(3) - (3)].yyt_error_param); } break; case 278: #line 933 "parser.yxx" { CTXT_URI; } break; case 279: #line 933 "parser.yxx" { CTXT_INITIAL; } break; case 280: #line 933 "parser.yxx" { (yyval.yyt_error_param) = new t_error_param(); MEMMAN_NEW((yyval.yyt_error_param)); (yyval.yyt_error_param)->uri.set_url(*(yyvsp[(3) - (6)].yyt_str)); (yyval.yyt_error_param)->parameter_list = *(yyvsp[(6) - (6)].yyt_params); if (!(yyval.yyt_error_param)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_error_param)); delete (yyval.yyt_error_param); YYERROR; } MEMMAN_DELETE((yyvsp[(3) - (6)].yyt_str)); delete (yyvsp[(3) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(6) - (6)].yyt_params)); delete (yyvsp[(6) - (6)].yyt_params); } break; case 281: #line 948 "parser.yxx" { CTXT_NUM; } break; case 282: #line 948 "parser.yxx" { CTXT_INITIAL; } break; case 283: #line 948 "parser.yxx" { MSG->hdr_expires.set_time((yyvsp[(2) - (3)].yyt_ulong)); } break; case 284: #line 952 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 285: #line 952 "parser.yxx" { MSG->hdr_from.set_display((yyvsp[(2) - (3)].yyt_from_addr)->display); MSG->hdr_from.set_uri((yyvsp[(2) - (3)].yyt_from_addr)->uri); list::const_iterator i; for (i = (yyvsp[(3) - (3)].yyt_params)->begin(); i != (yyvsp[(3) - (3)].yyt_params)->end(); i++) { if (i->name == "tag") { MSG->hdr_from.set_tag(i->value); } else { MSG->hdr_from.add_param(*i); } } MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_from_addr)); delete (yyvsp[(2) - (3)].yyt_from_addr); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 286: #line 967 "parser.yxx" { CTXT_INITIAL; } break; case 287: #line 967 "parser.yxx" { (yyval.yyt_from_addr) = new t_identity(); MEMMAN_NEW((yyval.yyt_from_addr)); (yyval.yyt_from_addr)->set_uri(*(yyvsp[(1) - (2)].yyt_str)); if (!(yyval.yyt_from_addr)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_from_addr)); delete (yyval.yyt_from_addr); YYERROR; } MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); } break; case 288: #line 978 "parser.yxx" { CTXT_URI; } break; case 289: #line 978 "parser.yxx" { CTXT_INITIAL; } break; case 290: #line 978 "parser.yxx" { (yyval.yyt_from_addr) = new t_identity(); MEMMAN_NEW((yyval.yyt_from_addr)); (yyval.yyt_from_addr)->set_display(*(yyvsp[(1) - (6)].yyt_str)); (yyval.yyt_from_addr)->set_uri(*(yyvsp[(4) - (6)].yyt_str)); if (!(yyval.yyt_from_addr)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_from_addr)); delete (yyval.yyt_from_addr); YYERROR; } MEMMAN_DELETE((yyvsp[(1) - (6)].yyt_str)); delete (yyvsp[(1) - (6)].yyt_str); MEMMAN_DELETE((yyvsp[(4) - (6)].yyt_str)); delete (yyvsp[(4) - (6)].yyt_str); } break; case 291: #line 993 "parser.yxx" { CTXT_WORD; } break; case 292: #line 993 "parser.yxx" { CTXT_INITIAL; } break; case 293: #line 993 "parser.yxx" { MSG->hdr_in_reply_to.add_call_id(*(yyvsp[(2) - (3)].yyt_str)); MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_str)); delete (yyvsp[(2) - (3)].yyt_str); } break; case 294: #line 996 "parser.yxx" { CTXT_WORD; } break; case 295: #line 996 "parser.yxx" { CTXT_INITIAL; } break; case 296: #line 996 "parser.yxx" { MSG->hdr_in_reply_to.add_call_id(*(yyvsp[(4) - (5)].yyt_str)); MEMMAN_DELETE((yyvsp[(4) - (5)].yyt_str)); delete (yyvsp[(4) - (5)].yyt_str); } break; case 297: #line 1001 "parser.yxx" { CTXT_NUM; } break; case 298: #line 1001 "parser.yxx" { CTXT_INITIAL; } break; case 299: #line 1001 "parser.yxx" { MSG->hdr_max_forwards.set_max_forwards((yyvsp[(2) - (3)].yyt_ulong)); } break; case 300: #line 1005 "parser.yxx" { CTXT_NUM; } break; case 301: #line 1005 "parser.yxx" { CTXT_INITIAL; } break; case 302: #line 1005 "parser.yxx" { MSG->hdr_min_expires.set_time((yyvsp[(2) - (3)].yyt_ulong)); } break; case 303: #line 1009 "parser.yxx" { MSG->hdr_mime_version.set_version(*(yyvsp[(1) - (1)].yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 304: #line 1014 "parser.yxx" { CTXT_LINE; } break; case 305: #line 1014 "parser.yxx" { CTXT_INITIAL; } break; case 306: #line 1014 "parser.yxx" { MSG->hdr_organization.set_name(trim(*(yyvsp[(2) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_str)); delete (yyvsp[(2) - (3)].yyt_str); } break; case 307: #line 1019 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 308: #line 1019 "parser.yxx" { MSG->hdr_p_asserted_identity.add_identity(*(yyvsp[(2) - (2)].yyt_from_addr)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_from_addr)); delete (yyvsp[(2) - (2)].yyt_from_addr); } break; case 309: #line 1022 "parser.yxx" { MSG->hdr_p_asserted_identity.add_identity(*(yyvsp[(3) - (3)].yyt_from_addr)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_from_addr)); delete (yyvsp[(3) - (3)].yyt_from_addr); } break; case 310: #line 1027 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 311: #line 1027 "parser.yxx" { MSG->hdr_p_preferred_identity.add_identity(*(yyvsp[(2) - (2)].yyt_from_addr)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_from_addr)); delete (yyvsp[(2) - (2)].yyt_from_addr); } break; case 312: #line 1030 "parser.yxx" { MSG->hdr_p_preferred_identity.add_identity(*(yyvsp[(3) - (3)].yyt_from_addr)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_from_addr)); delete (yyvsp[(3) - (3)].yyt_from_addr); } break; case 313: #line 1035 "parser.yxx" { MSG->hdr_priority.set_priority(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 314: #line 1040 "parser.yxx" { MSG->hdr_privacy.add_privacy(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 315: #line 1043 "parser.yxx" { MSG->hdr_privacy.add_privacy(tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 316: #line 1048 "parser.yxx" { MSG->hdr_proxy_require.add_feature(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 317: #line 1051 "parser.yxx" { MSG->hdr_proxy_require.add_feature(tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 318: #line 1056 "parser.yxx" { MSG->hdr_record_route.add_route(*(yyvsp[(1) - (1)].yyt_route)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_route)); delete (yyvsp[(1) - (1)].yyt_route); } break; case 319: #line 1059 "parser.yxx" { MSG->hdr_record_route.add_route(*(yyvsp[(3) - (3)].yyt_route)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_route)); delete (yyvsp[(3) - (3)].yyt_route); } break; case 320: #line 1064 "parser.yxx" { CTXT_URI; } break; case 321: #line 1064 "parser.yxx" { CTXT_INITIAL; } break; case 322: #line 1065 "parser.yxx" { (yyval.yyt_route) = new t_route; MEMMAN_NEW((yyval.yyt_route)); (yyval.yyt_route)->display = *(yyvsp[(2) - (7)].yyt_str); (yyval.yyt_route)->uri.set_url(*(yyvsp[(4) - (7)].yyt_str)); (yyval.yyt_route)->set_params(*(yyvsp[(7) - (7)].yyt_params)); if (!(yyval.yyt_route)->uri.is_valid()) { MEMMAN_DELETE((yyval.yyt_route)); delete (yyval.yyt_route); YYERROR; } MEMMAN_DELETE((yyvsp[(2) - (7)].yyt_str)); delete (yyvsp[(2) - (7)].yyt_str); MEMMAN_DELETE((yyvsp[(4) - (7)].yyt_str)); delete (yyvsp[(4) - (7)].yyt_str); MEMMAN_DELETE((yyvsp[(7) - (7)].yyt_params)); delete (yyvsp[(7) - (7)].yyt_params); } break; case 323: #line 1082 "parser.yxx" { MSG->hdr_service_route.add_route(*(yyvsp[(1) - (1)].yyt_route)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_route)); delete (yyvsp[(1) - (1)].yyt_route); } break; case 324: #line 1085 "parser.yxx" { MSG->hdr_service_route.add_route(*(yyvsp[(3) - (3)].yyt_route)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_route)); delete (yyvsp[(3) - (3)].yyt_route); } break; case 325: #line 1090 "parser.yxx" { CTXT_WORD; } break; case 326: #line 1090 "parser.yxx" { CTXT_INITIAL; } break; case 327: #line 1090 "parser.yxx" { MSG->hdr_replaces.set_call_id(*(yyvsp[(2) - (4)].yyt_str)); list::const_iterator i; for (i = (yyvsp[(4) - (4)].yyt_params)->begin(); i != (yyvsp[(4) - (4)].yyt_params)->end(); i++) { if (i->name == "to-tag") { MSG->hdr_replaces.set_to_tag(i->value); } else if (i->name == "from-tag") { MSG->hdr_replaces.set_from_tag(i->value); } else if (i->name == "early-only") { MSG->hdr_replaces.set_early_only(true); } else { MSG->hdr_replaces.add_param(*i); } } if (!MSG->hdr_replaces.is_valid()) YYERROR; MEMMAN_DELETE((yyvsp[(2) - (4)].yyt_str)); delete (yyvsp[(2) - (4)].yyt_str); MEMMAN_DELETE((yyvsp[(4) - (4)].yyt_params)); delete (yyvsp[(4) - (4)].yyt_params); } break; case 328: #line 1112 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 329: #line 1112 "parser.yxx" { MSG->hdr_reply_to.set_display((yyvsp[(2) - (3)].yyt_from_addr)->display); MSG->hdr_reply_to.set_uri((yyvsp[(2) - (3)].yyt_from_addr)->uri); MSG->hdr_reply_to.set_params(*(yyvsp[(3) - (3)].yyt_params)); MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_from_addr)); delete (yyvsp[(2) - (3)].yyt_from_addr); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 330: #line 1120 "parser.yxx" { MSG->hdr_require.add_feature(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 331: #line 1123 "parser.yxx" { MSG->hdr_require.add_feature(tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 332: #line 1128 "parser.yxx" { CTXT_NUM; } break; case 333: #line 1128 "parser.yxx" { CTXT_INITIAL; } break; case 334: #line 1128 "parser.yxx" { MSG->hdr_retry_after.set_time((yyvsp[(2) - (5)].yyt_ulong)); MSG->hdr_retry_after.set_comment(*(yyvsp[(4) - (5)].yyt_str)); list::const_iterator i; for (i = (yyvsp[(5) - (5)].yyt_params)->begin(); i != (yyvsp[(5) - (5)].yyt_params)->end(); i++) { if (i->name == "duration") { int d = strtoul(i->value.c_str(), NULL, 10); MSG->hdr_retry_after.set_duration(d); } else { MSG->hdr_retry_after.add_param(*i); } } MEMMAN_DELETE((yyvsp[(4) - (5)].yyt_str)); delete (yyvsp[(4) - (5)].yyt_str); MEMMAN_DELETE((yyvsp[(5) - (5)].yyt_params)); delete (yyvsp[(5) - (5)].yyt_params); } break; case 335: #line 1144 "parser.yxx" { (yyval.yyt_str) = new string(); MEMMAN_NEW((yyval.yyt_str)); } break; case 336: #line 1145 "parser.yxx" { CTXT_COMMENT; } break; case 337: #line 1145 "parser.yxx" { CTXT_INITIAL; } break; case 338: #line 1145 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(3) - (5)].yyt_str); } break; case 339: #line 1149 "parser.yxx" { MSG->hdr_route.add_route(*(yyvsp[(1) - (1)].yyt_route)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_route)); delete (yyvsp[(1) - (1)].yyt_route); } break; case 340: #line 1152 "parser.yxx" { MSG->hdr_route.add_route(*(yyvsp[(3) - (3)].yyt_route)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_route)); delete (yyvsp[(3) - (3)].yyt_route); } break; case 341: #line 1157 "parser.yxx" { MSG->hdr_server.add_server(*(yyvsp[(1) - (1)].yyt_server)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_server)); delete (yyvsp[(1) - (1)].yyt_server); } break; case 342: #line 1160 "parser.yxx" { MSG->hdr_server.add_server(*(yyvsp[(2) - (2)].yyt_server)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_server)); delete (yyvsp[(2) - (2)].yyt_server); } break; case 343: #line 1165 "parser.yxx" { (yyval.yyt_server) = new t_server(); MEMMAN_NEW((yyval.yyt_server)); (yyval.yyt_server)->comment = *(yyvsp[(1) - (1)].yyt_str); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 344: #line 1170 "parser.yxx" { (yyval.yyt_server) = new t_server(); MEMMAN_NEW((yyval.yyt_server)); (yyval.yyt_server)->product = *(yyvsp[(1) - (2)].yyt_str); (yyval.yyt_server)->comment = *(yyvsp[(2) - (2)].yyt_str); MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_str)); delete (yyvsp[(2) - (2)].yyt_str); } break; case 345: #line 1177 "parser.yxx" { (yyval.yyt_server) = new t_server(); MEMMAN_NEW((yyval.yyt_server)); (yyval.yyt_server)->product = *(yyvsp[(1) - (4)].yyt_str); (yyval.yyt_server)->version = *(yyvsp[(3) - (4)].yyt_str); (yyval.yyt_server)->comment = *(yyvsp[(4) - (4)].yyt_str); MEMMAN_DELETE((yyvsp[(1) - (4)].yyt_str)); delete (yyvsp[(1) - (4)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (4)].yyt_str)); delete (yyvsp[(3) - (4)].yyt_str); MEMMAN_DELETE((yyvsp[(4) - (4)].yyt_str)); delete (yyvsp[(4) - (4)].yyt_str); } break; case 346: #line 1188 "parser.yxx" { CTXT_LINE; } break; case 347: #line 1188 "parser.yxx" { CTXT_INITIAL; } break; case 348: #line 1188 "parser.yxx" { MSG->hdr_subject.set_subject(trim(*(yyvsp[(2) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_str)); delete (yyvsp[(2) - (3)].yyt_str); } break; case 349: #line 1193 "parser.yxx" { MSG->hdr_supported.set_empty(); } break; case 350: #line 1195 "parser.yxx" { MSG->hdr_supported.add_feature(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 351: #line 1198 "parser.yxx" { MSG->hdr_supported.add_feature(tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 352: #line 1203 "parser.yxx" { CTXT_NUM; } break; case 353: #line 1203 "parser.yxx" { CTXT_INITIAL; } break; case 354: #line 1206 "parser.yxx" { MSG->hdr_timestamp.set_timestamp((yyvsp[(1) - (1)].yyt_float)); } break; case 355: #line 1208 "parser.yxx" { MSG->hdr_timestamp.set_timestamp((yyvsp[(1) - (2)].yyt_float)); MSG->hdr_timestamp.set_delay((yyvsp[(2) - (2)].yyt_float)); } break; case 356: #line 1213 "parser.yxx" { (yyval.yyt_float) = (yyvsp[(1) - (1)].yyt_ulong); } break; case 357: #line 1214 "parser.yxx" { string s = int2str((yyvsp[(1) - (3)].yyt_ulong)) + '.' + int2str((yyvsp[(3) - (3)].yyt_ulong)); (yyval.yyt_float) = atof(s.c_str()); } break; case 358: #line 1219 "parser.yxx" { (yyval.yyt_float) = (yyvsp[(1) - (1)].yyt_ulong); } break; case 359: #line 1220 "parser.yxx" { string s = int2str((yyvsp[(1) - (3)].yyt_ulong)) + '.' + int2str((yyvsp[(3) - (3)].yyt_ulong)); (yyval.yyt_float) = atof(s.c_str()); } break; case 360: #line 1225 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 361: #line 1225 "parser.yxx" { MSG->hdr_to.set_display((yyvsp[(2) - (3)].yyt_from_addr)->display); MSG->hdr_to.set_uri((yyvsp[(2) - (3)].yyt_from_addr)->uri); list::const_iterator i; for (i = (yyvsp[(3) - (3)].yyt_params)->begin(); i != (yyvsp[(3) - (3)].yyt_params)->end(); i++) { if (i->name == "tag") { MSG->hdr_to.set_tag(i->value); } else { MSG->hdr_to.add_param(*i); } } MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_from_addr)); delete (yyvsp[(2) - (3)].yyt_from_addr); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 362: #line 1240 "parser.yxx" { MSG->hdr_unsupported.add_feature(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 363: #line 1243 "parser.yxx" { MSG->hdr_unsupported.add_feature(tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 364: #line 1248 "parser.yxx" { MSG->hdr_user_agent.add_server(*(yyvsp[(1) - (1)].yyt_server)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_server)); delete (yyvsp[(1) - (1)].yyt_server); } break; case 365: #line 1251 "parser.yxx" { MSG->hdr_user_agent.add_server(*(yyvsp[(2) - (2)].yyt_server)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_server)); delete (yyvsp[(2) - (2)].yyt_server); } break; case 366: #line 1256 "parser.yxx" { MSG->hdr_via.add_via(*(yyvsp[(1) - (1)].yyt_via)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_via)); delete (yyvsp[(1) - (1)].yyt_via); } break; case 367: #line 1259 "parser.yxx" { MSG->hdr_via.add_via(*(yyvsp[(3) - (3)].yyt_via)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_via)); delete (yyvsp[(3) - (3)].yyt_via); } break; case 368: #line 1264 "parser.yxx" { (yyval.yyt_via) = (yyvsp[(1) - (3)].yyt_via); (yyval.yyt_via)->host = (yyvsp[(2) - (3)].yyt_via)->host; (yyval.yyt_via)->port = (yyvsp[(2) - (3)].yyt_via)->port; list::const_iterator i; for (i = (yyvsp[(3) - (3)].yyt_params)->begin(); i != (yyvsp[(3) - (3)].yyt_params)->end(); i++) { if (i->name == "ttl") { (yyval.yyt_via)->ttl = atoi(i->value.c_str()); } else if (i->name == "maddr") { (yyval.yyt_via)->maddr = i->value; } else if (i->name == "received") { (yyval.yyt_via)->received = i->value; } else if (i->name == "branch") { (yyval.yyt_via)->branch = i->value; } else if (i->name == "rport") { (yyval.yyt_via)->rport_present = true; if (i->type == t_parameter::VALUE) { (yyval.yyt_via)->rport = atoi(i->value.c_str()); } } else { (yyval.yyt_via)->add_extension(*i); } } MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_via)); delete (yyvsp[(2) - (3)].yyt_via); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 369: #line 1292 "parser.yxx" { (yyval.yyt_via) = new t_via(); MEMMAN_NEW((yyval.yyt_via)); (yyval.yyt_via)->protocol_name = toupper(*(yyvsp[(1) - (5)].yyt_str)); (yyval.yyt_via)->protocol_version = *(yyvsp[(3) - (5)].yyt_str); (yyval.yyt_via)->transport = toupper(*(yyvsp[(5) - (5)].yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (5)].yyt_str)); delete (yyvsp[(1) - (5)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (5)].yyt_str)); delete (yyvsp[(3) - (5)].yyt_str); MEMMAN_DELETE((yyvsp[(5) - (5)].yyt_str)); delete (yyvsp[(5) - (5)].yyt_str); } break; case 370: #line 1303 "parser.yxx" { (yyval.yyt_via) = new t_via(); MEMMAN_NEW((yyval.yyt_via)); (yyval.yyt_via)->host = *(yyvsp[(1) - (1)].yyt_str); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 371: #line 1308 "parser.yxx" { CTXT_NUM; } break; case 372: #line 1308 "parser.yxx" { CTXT_INITIAL; } break; case 373: #line 1308 "parser.yxx" { if ((yyvsp[(4) - (5)].yyt_ulong) > 65535) YYERROR; (yyval.yyt_via) = new t_via(); MEMMAN_NEW((yyval.yyt_via)); (yyval.yyt_via)->host = *(yyvsp[(1) - (5)].yyt_str); (yyval.yyt_via)->port = (yyvsp[(4) - (5)].yyt_ulong); MEMMAN_DELETE((yyvsp[(1) - (5)].yyt_str)); delete (yyvsp[(1) - (5)].yyt_str); } break; case 374: #line 1316 "parser.yxx" { (yyval.yyt_via) = new t_via(); MEMMAN_NEW((yyval.yyt_via)); (yyval.yyt_via)->host = *(yyvsp[(1) - (1)].yyt_str); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 375: #line 1321 "parser.yxx" { CTXT_NUM; } break; case 376: #line 1321 "parser.yxx" { CTXT_INITIAL; } break; case 377: #line 1321 "parser.yxx" { (yyval.yyt_via) = new t_via(); MEMMAN_NEW((yyval.yyt_via)); (yyval.yyt_via)->host = *(yyvsp[(1) - (5)].yyt_str); (yyval.yyt_via)->port = (yyvsp[(4) - (5)].yyt_ulong); MEMMAN_DELETE((yyvsp[(1) - (5)].yyt_str)); delete (yyvsp[(1) - (5)].yyt_str); } break; case 378: #line 1329 "parser.yxx" { CTXT_IPV6ADDR; } break; case 379: #line 1329 "parser.yxx" { CTXT_INITIAL; } break; case 380: #line 1329 "parser.yxx" { // TODO: check correct format of IPv6 address (yyval.yyt_str) = new string('[' + *(yyvsp[(3) - (5)].yyt_str) + ']'); MEMMAN_NEW((yyval.yyt_str)); MEMMAN_DELETE((yyvsp[(3) - (5)].yyt_str)); } break; case 381: #line 1336 "parser.yxx" { MSG->hdr_warning.add_warning(*(yyvsp[(1) - (1)].yyt_warning)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_warning)); delete (yyvsp[(1) - (1)].yyt_warning); } break; case 382: #line 1339 "parser.yxx" { MSG->hdr_warning.add_warning(*(yyvsp[(3) - (3)].yyt_warning)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_warning)); delete (yyvsp[(3) - (3)].yyt_warning); } break; case 383: #line 1344 "parser.yxx" { CTXT_NUM; } break; case 384: #line 1344 "parser.yxx" { CTXT_INITIAL; } break; case 385: #line 1344 "parser.yxx" { (yyval.yyt_warning) = new t_warning(); MEMMAN_NEW((yyval.yyt_warning)); (yyval.yyt_warning)->code = (yyvsp[(2) - (5)].yyt_ulong); (yyval.yyt_warning)->host = (yyvsp[(4) - (5)].yyt_via)->host; (yyval.yyt_warning)->port = (yyvsp[(4) - (5)].yyt_via)->port; (yyval.yyt_warning)->text = *(yyvsp[(5) - (5)].yyt_str); MEMMAN_DELETE((yyvsp[(4) - (5)].yyt_via)); delete (yyvsp[(4) - (5)].yyt_via); MEMMAN_DELETE((yyvsp[(5) - (5)].yyt_str)); delete (yyvsp[(5) - (5)].yyt_str); } break; case 386: #line 1355 "parser.yxx" { CTXT_LINE; } break; case 387: #line 1355 "parser.yxx" { CTXT_INITIAL; } break; case 388: #line 1355 "parser.yxx" { (yyval.yyt_str) = (yyvsp[(2) - (3)].yyt_str); } break; case 389: #line 1358 "parser.yxx" { if ((yyvsp[(1) - (1)].yyt_param)->name == "nextnonce") MSG->hdr_auth_info.set_next_nonce((yyvsp[(1) - (1)].yyt_param)->value); else if ((yyvsp[(1) - (1)].yyt_param)->name == "qop") MSG->hdr_auth_info.set_message_qop((yyvsp[(1) - (1)].yyt_param)->value); else if ((yyvsp[(1) - (1)].yyt_param)->name == "rspauth") MSG->hdr_auth_info.set_response_auth((yyvsp[(1) - (1)].yyt_param)->value); else if ((yyvsp[(1) - (1)].yyt_param)->name == "cnonce") MSG->hdr_auth_info.set_cnonce((yyvsp[(1) - (1)].yyt_param)->value); else if ((yyvsp[(1) - (1)].yyt_param)->name == "nc") { MSG->hdr_auth_info.set_nonce_count( hex2int((yyvsp[(1) - (1)].yyt_param)->value)); } else { YYERROR; } MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_param)); delete (yyvsp[(1) - (1)].yyt_param); } break; case 392: #line 1382 "parser.yxx" { (yyval.yyt_dig_resp) = new t_digest_response(); MEMMAN_NEW((yyval.yyt_dig_resp)); if (!(yyval.yyt_dig_resp)->set_attr(*(yyvsp[(1) - (1)].yyt_param))) { MEMMAN_DELETE((yyval.yyt_dig_resp)); delete (yyval.yyt_dig_resp); YYERROR; } MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_param)); delete (yyvsp[(1) - (1)].yyt_param); } break; case 393: #line 1390 "parser.yxx" { (yyval.yyt_dig_resp) = (yyvsp[(1) - (3)].yyt_dig_resp); if (!(yyval.yyt_dig_resp)->set_attr(*(yyvsp[(3) - (3)].yyt_param))) { YYERROR; } MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_param)); delete (yyvsp[(3) - (3)].yyt_param); } break; case 394: #line 1398 "parser.yxx" { (yyval.yyt_params) = new list; MEMMAN_NEW((yyval.yyt_params)); (yyval.yyt_params)->push_back(*(yyvsp[(1) - (1)].yyt_param)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_param)); delete (yyvsp[(1) - (1)].yyt_param); } break; case 395: #line 1403 "parser.yxx" { (yyval.yyt_params) = (yyvsp[(1) - (3)].yyt_params); (yyval.yyt_params)->push_back(*(yyvsp[(3) - (3)].yyt_param)); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_param)); delete (yyvsp[(3) - (3)].yyt_param); } break; case 396: #line 1409 "parser.yxx" { CTXT_INITIAL; } break; case 397: #line 1409 "parser.yxx" { (yyval.yyt_credentials) = new t_credentials; MEMMAN_NEW((yyval.yyt_credentials)); (yyval.yyt_credentials)->auth_scheme = AUTH_DIGEST; (yyval.yyt_credentials)->digest_response = *(yyvsp[(3) - (3)].yyt_dig_resp); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_dig_resp)); delete (yyvsp[(3) - (3)].yyt_dig_resp); } break; case 398: #line 1415 "parser.yxx" { CTXT_INITIAL; } break; case 399: #line 1415 "parser.yxx" { (yyval.yyt_credentials) = new t_credentials; MEMMAN_NEW((yyval.yyt_credentials)); (yyval.yyt_credentials)->auth_scheme = *(yyvsp[(1) - (3)].yyt_str); (yyval.yyt_credentials)->auth_params = *(yyvsp[(3) - (3)].yyt_params); MEMMAN_DELETE((yyvsp[(1) - (3)].yyt_str)); delete (yyvsp[(1) - (3)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 400: #line 1424 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 401: #line 1424 "parser.yxx" { MSG->hdr_authorization.add_credentials(*(yyvsp[(2) - (2)].yyt_credentials)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_credentials)); delete (yyvsp[(2) - (2)].yyt_credentials); } break; case 402: #line 1429 "parser.yxx" { (yyval.yyt_dig_chlg) = new t_digest_challenge(); MEMMAN_NEW((yyval.yyt_dig_chlg)); if (!(yyval.yyt_dig_chlg)->set_attr(*(yyvsp[(1) - (1)].yyt_param))) { MEMMAN_DELETE((yyval.yyt_dig_chlg)); delete (yyval.yyt_dig_chlg); YYERROR; } MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_param)); delete (yyvsp[(1) - (1)].yyt_param); } break; case 403: #line 1437 "parser.yxx" { (yyval.yyt_dig_chlg) = (yyvsp[(1) - (3)].yyt_dig_chlg); if (!(yyval.yyt_dig_chlg)->set_attr(*(yyvsp[(3) - (3)].yyt_param))) { YYERROR; } MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_param)); delete (yyvsp[(3) - (3)].yyt_param); } break; case 404: #line 1445 "parser.yxx" { CTXT_INITIAL; } break; case 405: #line 1445 "parser.yxx" { (yyval.yyt_challenge) = new t_challenge; MEMMAN_NEW((yyval.yyt_challenge)); (yyval.yyt_challenge)->auth_scheme = AUTH_DIGEST; (yyval.yyt_challenge)->digest_challenge = *(yyvsp[(3) - (3)].yyt_dig_chlg); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_dig_chlg)); delete (yyvsp[(3) - (3)].yyt_dig_chlg); } break; case 406: #line 1451 "parser.yxx" { CTXT_INITIAL; } break; case 407: #line 1451 "parser.yxx" { (yyval.yyt_challenge) = new t_challenge; MEMMAN_NEW((yyval.yyt_challenge)); (yyval.yyt_challenge)->auth_scheme = *(yyvsp[(1) - (3)].yyt_str); (yyval.yyt_challenge)->auth_params = *(yyvsp[(3) - (3)].yyt_params); MEMMAN_DELETE((yyvsp[(1) - (3)].yyt_str)); delete (yyvsp[(1) - (3)].yyt_str); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 408: #line 1460 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 409: #line 1460 "parser.yxx" { MSG->hdr_proxy_authenticate.set_challenge(*(yyvsp[(2) - (2)].yyt_challenge)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_challenge)); delete (yyvsp[(2) - (2)].yyt_challenge); } break; case 410: #line 1465 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 411: #line 1465 "parser.yxx" { MSG->hdr_proxy_authorization. add_credentials(*(yyvsp[(2) - (2)].yyt_credentials)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_credentials)); delete (yyvsp[(2) - (2)].yyt_credentials); } break; case 412: #line 1471 "parser.yxx" { CTXT_AUTH_SCHEME; } break; case 413: #line 1471 "parser.yxx" { MSG->hdr_www_authenticate.set_challenge(*(yyvsp[(2) - (2)].yyt_challenge)); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_challenge)); delete (yyvsp[(2) - (2)].yyt_challenge); } break; case 414: #line 1476 "parser.yxx" { CTXT_NUM; } break; case 415: #line 1476 "parser.yxx" { CTXT_INITIAL; } break; case 416: #line 1476 "parser.yxx" { MSG->hdr_rseq.set_resp_nr((yyvsp[(2) - (3)].yyt_ulong)); } break; case 417: #line 1480 "parser.yxx" { CTXT_NUM; } break; case 418: #line 1480 "parser.yxx" { CTXT_INITIAL; } break; case 419: #line 1480 "parser.yxx" { MSG->hdr_rack.set_resp_nr((yyvsp[(2) - (5)].yyt_ulong)); MSG->hdr_rack.set_cseq_nr((yyvsp[(3) - (5)].yyt_ulong)); MSG->hdr_rack.set_method(*(yyvsp[(5) - (5)].yyt_str)); MEMMAN_DELETE((yyvsp[(5) - (5)].yyt_str)); delete (yyvsp[(5) - (5)].yyt_str); } break; case 420: #line 1487 "parser.yxx" { MSG->hdr_event.set_event_type(tolower(*(yyvsp[(1) - (2)].yyt_str))); list::const_iterator i; for (i = (yyvsp[(2) - (2)].yyt_params)->begin(); i != (yyvsp[(2) - (2)].yyt_params)->end(); i++) { if (i->name == "id") { MSG->hdr_event.set_id(i->value); } else { MSG->hdr_event.add_event_param(*i); } } MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 421: #line 1501 "parser.yxx" { MSG->hdr_allow_events.add_event_type(tolower(*(yyvsp[(1) - (1)].yyt_str))); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 422: #line 1504 "parser.yxx" { MSG->hdr_allow_events.add_event_type(tolower(*(yyvsp[(3) - (3)].yyt_str))); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; case 423: #line 1509 "parser.yxx" { MSG->hdr_subscription_state.set_substate(tolower(*(yyvsp[(1) - (2)].yyt_str))); list::const_iterator i; for (i = (yyvsp[(2) - (2)].yyt_params)->begin(); i != (yyvsp[(2) - (2)].yyt_params)->end(); i++) { if (i->name == "reason") { MSG->hdr_subscription_state. set_reason(tolower(i->value)); } else if (i->name == "expires") { MSG->hdr_subscription_state. set_expires(strtoul( i->value.c_str(), NULL, 10)); } else if (i->name == "retry-after") { MSG->hdr_subscription_state. set_retry_after(strtoul( i->value.c_str(), NULL, 10)); } else { MSG->hdr_subscription_state. add_extension(*i); } } MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 424: #line 1535 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 425: #line 1535 "parser.yxx" { MSG->hdr_refer_to.set_display((yyvsp[(2) - (3)].yyt_from_addr)->display); MSG->hdr_refer_to.set_uri((yyvsp[(2) - (3)].yyt_from_addr)->uri); MSG->hdr_refer_to.set_params(*(yyvsp[(3) - (3)].yyt_params)); MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_from_addr)); delete (yyvsp[(2) - (3)].yyt_from_addr); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 426: #line 1543 "parser.yxx" { CTXT_URI_SPECIAL; } break; case 427: #line 1543 "parser.yxx" { MSG->hdr_referred_by.set_display((yyvsp[(2) - (3)].yyt_from_addr)->display); MSG->hdr_referred_by.set_uri((yyvsp[(2) - (3)].yyt_from_addr)->uri); list::const_iterator i; for (i = (yyvsp[(3) - (3)].yyt_params)->begin(); i != (yyvsp[(3) - (3)].yyt_params)->end(); i++) { if (i->name == "cid") { MSG->hdr_referred_by.set_cid(i->value); } else { MSG->hdr_referred_by.add_param(*i); } } MEMMAN_DELETE((yyvsp[(2) - (3)].yyt_from_addr)); delete (yyvsp[(2) - (3)].yyt_from_addr); MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_params)); delete (yyvsp[(3) - (3)].yyt_params); } break; case 428: #line 1558 "parser.yxx" { string value(tolower(*(yyvsp[(1) - (2)].yyt_str))); if (value != "true" && value != "false") { YYERROR; } MSG->hdr_refer_sub.set_create_refer_sub(value == "true"); MSG->hdr_refer_sub.set_extensions(*(yyvsp[(2) - (2)].yyt_params)); MEMMAN_DELETE((yyvsp[(1) - (2)].yyt_str)); delete (yyvsp[(1) - (2)].yyt_str); MEMMAN_DELETE((yyvsp[(2) - (2)].yyt_params)); delete (yyvsp[(2) - (2)].yyt_params); } break; case 429: #line 1569 "parser.yxx" { MSG->hdr_sip_etag.set_etag(*(yyvsp[(1) - (1)].yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 430: #line 1574 "parser.yxx" { MSG->hdr_sip_if_match.set_etag(*(yyvsp[(1) - (1)].yyt_str)); MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 431: #line 1579 "parser.yxx" { bool ret = MSG->hdr_request_disposition.set_directive(*(yyvsp[(1) - (1)].yyt_str)); if (!ret) YYERROR; MEMMAN_DELETE((yyvsp[(1) - (1)].yyt_str)); delete (yyvsp[(1) - (1)].yyt_str); } break; case 432: #line 1583 "parser.yxx" { bool ret = MSG->hdr_request_disposition.set_directive(*(yyvsp[(3) - (3)].yyt_str)); if (!ret) YYERROR; MEMMAN_DELETE((yyvsp[(3) - (3)].yyt_str)); delete (yyvsp[(3) - (3)].yyt_str); } break; /* Line 1267 of yacc.c. */ #line 4885 "parser.cxx" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (yymsg); } else { yyerror (YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 1588 "parser.yxx" void yyerror (const char *s) /* Called by yyparse on error */ { // printf ("%s\n", s); } twinkle-1.4.2/src/parser/parser.yxx0000644000175000001440000012706511142400402014240 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %{ #include #include #include #include "media_type.h" #include "parameter.h" #include "parse_ctrl.h" #include "request.h" #include "response.h" #include "util.h" #include "audits/memman.h" using namespace std; extern int yylex(void); void yyerror(const char *s); %} // The %debug option causes a problem with the %destructor options later on. // The bison compilor generates undefined symbols: // // parser.y: In function `void yysymprint(FILE*, int, yystype)': // parser.y:0: error: `null' undeclared (first use this function) // // So if you need to debug, then outcomment the %destructor first. This will // do no harm to your debugging, it only will cause memory leaks during // error handling. // // %debug %union { int yyt_int; ulong yyt_ulong; float yyt_float; string *yyt_str; t_parameter *yyt_param; list *yyt_params; t_media *yyt_media; t_coding *yyt_coding; t_language *yyt_language; t_alert_param *yyt_alert_param; t_info_param *yyt_info_param; list *yyt_contacts; t_contact_param *yyt_contact; t_error_param *yyt_error_param; t_identity *yyt_from_addr; t_route *yyt_route; t_server *yyt_server; t_via *yyt_via; t_warning *yyt_warning; t_digest_response *yyt_dig_resp; t_credentials *yyt_credentials; t_digest_challenge *yyt_dig_chlg; t_challenge *yyt_challenge; } %token T_NUM %token T_TOKEN %token T_QSTRING %token T_COMMENT %token T_LINE %token T_URI %token T_URI_WILDCARD %token T_DISPLAY %token T_LANG %token T_WORD %token T_WKDAY %token T_MONTH %token T_GMT %token T_SIP %token T_METHOD %token T_AUTH_DIGEST %token T_AUTH_OTHER %token T_IPV6ADDR %token T_PARAMVAL %token T_HDR_ACCEPT %token T_HDR_ACCEPT_ENCODING %token T_HDR_ACCEPT_LANGUAGE %token T_HDR_ALERT_INFO %token T_HDR_ALLOW %token T_HDR_ALLOW_EVENTS %token T_HDR_AUTHENTICATION_INFO %token T_HDR_AUTHORIZATION %token T_HDR_CALL_ID %token T_HDR_CALL_INFO %token T_HDR_CONTACT %token T_HDR_CONTENT_DISP %token T_HDR_CONTENT_ENCODING %token T_HDR_CONTENT_LANGUAGE %token T_HDR_CONTENT_LENGTH %token T_HDR_CONTENT_TYPE %token T_HDR_CSEQ %token T_HDR_DATE %token T_HDR_ERROR_INFO %token T_HDR_EVENT %token T_HDR_EXPIRES %token T_HDR_FROM %token T_HDR_IN_REPLY_TO %token T_HDR_MAX_FORWARDS %token T_HDR_MIN_EXPIRES %token T_HDR_MIME_VERSION %token T_HDR_ORGANIZATION %token T_HDR_P_ASSERTED_IDENTITY %token T_HDR_P_PREFERRED_IDENTITY %token T_HDR_PRIORITY %token T_HDR_PRIVACY %token T_HDR_PROXY_AUTHENTICATE %token T_HDR_PROXY_AUTHORIZATION %token T_HDR_PROXY_REQUIRE %token T_HDR_RACK %token T_HDR_RECORD_ROUTE %token T_HDR_SERVICE_ROUTE %token T_HDR_REFER_SUB %token T_HDR_REFER_TO %token T_HDR_REFERRED_BY %token T_HDR_REPLACES %token T_HDR_REPLY_TO %token T_HDR_REQUIRE %token T_HDR_REQUEST_DISPOSITION %token T_HDR_RETRY_AFTER %token T_HDR_ROUTE %token T_HDR_RSEQ %token T_HDR_SERVER %token T_HDR_SIP_ETAG %token T_HDR_SIP_IF_MATCH %token T_HDR_SUBJECT %token T_HDR_SUBSCRIPTION_STATE %token T_HDR_SUPPORTED %token T_HDR_TIMESTAMP %token T_HDR_TO %token T_HDR_UNSUPPORTED %token T_HDR_USER_AGENT %token T_HDR_VIA %token T_HDR_WARNING %token T_HDR_WWW_AUTHENTICATE %token T_HDR_UNKNOWN %token T_CRLF %token T_ERROR // The token T_NULL is never returned by the scanner. %token T_NULL %destructor { MEMMAN_DELETE($$); delete $$; } T_TOKEN; %destructor { MEMMAN_DELETE($$); delete $$; } T_QSTRING %destructor { MEMMAN_DELETE($$); delete $$; } T_COMMENT %destructor { MEMMAN_DELETE($$); delete $$; } T_LINE %destructor { MEMMAN_DELETE($$); delete $$; } T_URI %destructor { MEMMAN_DELETE($$); delete $$; } T_DISPLAY %destructor { MEMMAN_DELETE($$); delete $$; } T_LANG %destructor { MEMMAN_DELETE($$); delete $$; } T_WORD %destructor { MEMMAN_DELETE($$); delete $$; } T_METHOD %destructor { MEMMAN_DELETE($$); delete $$; } T_AUTH_OTHER %destructor { MEMMAN_DELETE($$); delete $$; } T_IPV6ADDR %destructor { MEMMAN_DELETE($$); delete $$; } T_PARAMVAL %destructor { MEMMAN_DELETE($$); delete $$; } T_HDR_UNKNOWN %type alert_param %type auth_params %type call_id %type challenge %type comment %type contact_addr %type contact_param %type contacts %type content_coding %type credentials %type delay %type digest_challenge %type digest_response %type display_name %type error_param %type from_addr %type hdr_unknown %type host %type ipv6reference %type info_param %type language %type media_range %type parameter %type parameter_val %type parameters %type q_factor %type rec_route %type sent_protocol %type server %type sip_version %type timestamp %type via_parm %type warning %destructor { MEMMAN_DELETE($$); delete $$; } alert_param %destructor { MEMMAN_DELETE($$); delete $$; } auth_params %destructor { MEMMAN_DELETE($$); delete $$; } call_id %destructor { MEMMAN_DELETE($$); delete $$; } challenge %destructor { MEMMAN_DELETE($$); delete $$; } comment %destructor { MEMMAN_DELETE($$); delete $$; } contact_addr %destructor { MEMMAN_DELETE($$); delete $$; } contact_param %destructor { MEMMAN_DELETE($$); delete $$; } contacts %destructor { MEMMAN_DELETE($$); delete $$; } content_coding %destructor { MEMMAN_DELETE($$); delete $$; } credentials %destructor { MEMMAN_DELETE($$); delete $$; } digest_challenge %destructor { MEMMAN_DELETE($$); delete $$; } digest_response %destructor { MEMMAN_DELETE($$); delete $$; } display_name %destructor { MEMMAN_DELETE($$); delete $$; } error_param %destructor { MEMMAN_DELETE($$); delete $$; } from_addr %destructor { MEMMAN_DELETE($$); delete $$; } hdr_unknown %destructor { MEMMAN_DELETE($$); delete $$; } host %destructor { MEMMAN_DELETE($$); delete $$; } ipv6reference %destructor { MEMMAN_DELETE($$); delete $$; } info_param %destructor { MEMMAN_DELETE($$); delete $$; } language %destructor { MEMMAN_DELETE($$); delete $$; } media_range %destructor { MEMMAN_DELETE($$); delete $$; } parameter %destructor { MEMMAN_DELETE($$); delete $$; } parameter_val %destructor { MEMMAN_DELETE($$); delete $$; } parameters %destructor { MEMMAN_DELETE($$); delete $$; } rec_route %destructor { MEMMAN_DELETE($$); delete $$; } sent_protocol %destructor { MEMMAN_DELETE($$); delete $$; } server %destructor { MEMMAN_DELETE($$); delete $$; } sip_version %destructor { MEMMAN_DELETE($$); delete $$; } via_parm %destructor { MEMMAN_DELETE($$); delete $$; } warning %% sip_message: { CTXT_NEW; } sip_message2 ; sip_message2: request | response | error T_NULL { /* KLUDGE to work around a memory leak in bison. * T_NULL does never match, so the parser never * gets here. The error keyword causes bison * to eat all input and destroy all tokens returned * by the parser. * Without this workaround the following input causes * the parser to leak: * * INVITE INVITE .... * * In request_line a T_METHOD is returned as look ahead * token when bison tries to match sip_version. * This does not match, but the look ahead token is * never destructed by Bison. */ YYABORT; } ; request: request_line headers T_CRLF { /* Parsing stops here. Remaining text is * not parsed. */ YYACCEPT; } ; // KLUDGE: The use of CTXT_NEW is a kludge, to get the T_SIP symbol // for the SIP version request_line: T_METHOD { CTXT_URI; } T_URI { CTXT_NEW; } sip_version T_CRLF { MSG = new t_request(); MEMMAN_NEW(MSG); ((t_request *)MSG)->set_method(*$1); ((t_request *)MSG)->uri.set_url(*$3); MSG->version = *$5; MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($5); delete $5; if (!((t_request *)MSG)->uri.is_valid()) { MEMMAN_DELETE(MSG); delete MSG; MSG = NULL; YYABORT; } } ; sip_version: T_SIP { CTXT_INITIAL; } '/' T_TOKEN { $$ = $4; } ; response: status_line headers T_CRLF { /* Parsing stops here. Remaining text is * not parsed. */ YYACCEPT; } ; status_line: sip_version { CTXT_NUM; } T_NUM { CTXT_LINE; } T_LINE { CTXT_INITIAL; } T_CRLF { MSG = new t_response(); MEMMAN_NEW(MSG); MSG->version = *$1; ((t_response *)MSG)->code = $3; ((t_response *)MSG)->reason = trim(*$5); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($5); delete $5; } ; headers: /* empty */ | headers header ; header: hd_accept hdr_accept T_CRLF | hd_accept_encoding hdr_accept_encoding T_CRLF | hd_accept_language hdr_accept_language T_CRLF | hd_alert_info hdr_alert_info T_CRLF | hd_allow hdr_allow T_CRLF | hd_allow_events hdr_allow_events T_CRLF | hd_authentication_info hdr_authentication_info T_CRLF | hd_authorization hdr_authorization T_CRLF | hd_call_id hdr_call_id T_CRLF | hd_call_info hdr_call_info T_CRLF | hd_contact hdr_contact T_CRLF | hd_content_disp hdr_content_disp T_CRLF | hd_content_encoding hdr_content_encoding T_CRLF | hd_content_language hdr_content_language T_CRLF | hd_content_length hdr_content_length T_CRLF | hd_content_type hdr_content_type T_CRLF | hd_cseq hdr_cseq T_CRLF | hd_date hdr_date T_CRLF | hd_event hdr_event T_CRLF | hd_error_info hdr_error_info T_CRLF | hd_expires hdr_expires T_CRLF | hd_from hdr_from T_CRLF | hd_in_reply_to hdr_in_reply_to T_CRLF | hd_max_forwards hdr_max_forwards T_CRLF | hd_min_expires hdr_min_expires T_CRLF | hd_mime_version hdr_mime_version T_CRLF | hd_organization hdr_organization T_CRLF | hd_p_asserted_identity hdr_p_asserted_identity T_CRLF | hd_p_preferred_identity hdr_p_preferred_identity T_CRLF | hd_priority hdr_priority T_CRLF | hd_privacy hdr_privacy T_CRLF | hd_proxy_authenticate hdr_proxy_authenticate T_CRLF | hd_proxy_authorization hdr_proxy_authorization T_CRLF | hd_proxy_require hdr_proxy_require T_CRLF | hd_rack hdr_rack T_CRLF | hd_record_route hdr_record_route T_CRLF | hd_refer_sub hdr_refer_sub T_CRLF | hd_refer_to hdr_refer_to T_CRLF | hd_referred_by hdr_referred_by T_CRLF | hd_replaces hdr_replaces T_CRLF | hd_reply_to hdr_reply_to T_CRLF | hd_require hdr_require T_CRLF | hd_request_disposition hdr_request_disposition T_CRLF | hd_retry_after hdr_retry_after T_CRLF | hd_route hdr_route T_CRLF | hd_rseq hdr_rseq T_CRLF | hd_server hdr_server T_CRLF | hd_service_route hdr_service_route T_CRLF | hd_sip_etag hdr_sip_etag T_CRLF | hd_sip_if_match hdr_sip_if_match T_CRLF | hd_subject hdr_subject T_CRLF | hd_subscription_state hdr_subscription_state T_CRLF | hd_supported hdr_supported T_CRLF | hd_timestamp hdr_timestamp T_CRLF | hd_to hdr_to T_CRLF | hd_unsupported hdr_unsupported T_CRLF | hd_user_agent hdr_user_agent T_CRLF | hd_via hdr_via T_CRLF | hd_warning hdr_warning T_CRLF | hd_www_authenticate hdr_www_authenticate T_CRLF | T_HDR_UNKNOWN ':' hdr_unknown T_CRLF { MSG->add_unknown_header(*$1, trim(*$3)); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; } | hd_accept error T_CRLF { PARSE_ERROR("Accept"); } | hd_accept_encoding error T_CRLF { PARSE_ERROR("Accept-Encoding"); } | hd_accept_language error T_CRLF { PARSE_ERROR("Accept-Language"); } | hd_alert_info error T_CRLF { PARSE_ERROR("Alert-Info"); } | hd_allow error T_CRLF { PARSE_ERROR("Allow"); } | hd_allow_events error T_CRLF { PARSE_ERROR("Allow-Events"); } | hd_authentication_info error T_CRLF { PARSE_ERROR("Authentication-Info"); } | hd_authorization error T_CRLF { PARSE_ERROR("Authorization"); } | hd_call_id error T_CRLF { PARSE_ERROR("Call-ID"); } | hd_call_info error T_CRLF { PARSE_ERROR("Call-Info"); } | hd_contact error T_CRLF { PARSE_ERROR("Contact"); } | hd_content_disp error T_CRLF { PARSE_ERROR("Content-Disposition"); } | hd_content_encoding error T_CRLF { PARSE_ERROR("Content-Encoding"); } | hd_content_language error T_CRLF { PARSE_ERROR("Content-Language"); } | hd_content_length error T_CRLF { PARSE_ERROR("Content-Length"); } | hd_content_type error T_CRLF { PARSE_ERROR("Content-Type"); } | hd_cseq error T_CRLF { PARSE_ERROR("CSeq"); } | hd_date error T_CRLF { PARSE_ERROR("Date"); } | hd_error_info error T_CRLF { PARSE_ERROR("Error-Info"); } | hd_event error T_CRLF { PARSE_ERROR("Event"); } | hd_expires error T_CRLF { PARSE_ERROR("Expires"); } | hd_from error T_CRLF { PARSE_ERROR("From"); } | hd_in_reply_to error T_CRLF { PARSE_ERROR("In-Reply-To"); } | hd_max_forwards error T_CRLF { PARSE_ERROR("Max-Forwards"); } | hd_min_expires error T_CRLF { PARSE_ERROR("Min-Expires"); } | hd_mime_version error T_CRLF { PARSE_ERROR("MIME-Version"); } | hd_organization error T_CRLF { PARSE_ERROR("Organization"); } | hd_p_asserted_identity error T_CRLF { PARSE_ERROR("P-Asserted-Identity"); } | hd_p_preferred_identity error T_CRLF { PARSE_ERROR("P-Preferred-Identity"); } | hd_priority error T_CRLF { PARSE_ERROR("Priority"); } | hd_privacy error T_CRLF { PARSE_ERROR("Privacy"); } | hd_proxy_authenticate error T_CRLF { PARSE_ERROR("Proxy-Authenticate"); } | hd_proxy_authorization error T_CRLF { PARSE_ERROR("Proxy-Authorization"); } | hd_proxy_require error T_CRLF { PARSE_ERROR("Proxy-Require"); } | hd_rack error T_CRLF { PARSE_ERROR("RAck"); } | hd_record_route error T_CRLF { PARSE_ERROR("Record-Route"); } | hd_refer_sub error T_CRLF { PARSE_ERROR("Refer-Sub"); } | hd_refer_to error T_CRLF { PARSE_ERROR("Refer-To"); } | hd_referred_by error T_CRLF { PARSE_ERROR("Referred-By"); } | hd_replaces error T_CRLF { PARSE_ERROR("Replaces"); } | hd_reply_to error T_CRLF { PARSE_ERROR("Reply-To"); } | hd_require error T_CRLF { PARSE_ERROR("Require"); } | hd_request_disposition error T_CRLF { PARSE_ERROR("Request-Disposition"); } | hd_retry_after error T_CRLF { PARSE_ERROR("Retry-After"); } | hd_route error T_CRLF { PARSE_ERROR("Route"); } | hd_rseq error T_CRLF { PARSE_ERROR("RSeq"); } | hd_server error T_CRLF { PARSE_ERROR("Server"); } | hd_service_route error T_CRLF { PARSE_ERROR("Service-Route"); } | hd_sip_etag error T_CRLF { PARSE_ERROR("SIP-ETag"); } | hd_sip_if_match error T_CRLF { PARSE_ERROR("SIP-If-Match"); } | hd_subject error T_CRLF { PARSE_ERROR("Subject"); } | hd_subscription_state error T_CRLF { PARSE_ERROR("Subscription-State"); } | hd_supported error T_CRLF { PARSE_ERROR("Supported"); } | hd_timestamp error T_CRLF { PARSE_ERROR("Timestamp"); } | hd_to error T_CRLF { PARSE_ERROR("To"); } | hd_unsupported error T_CRLF { PARSE_ERROR("Unsupported"); } | hd_user_agent error T_CRLF { PARSE_ERROR("User-Agent"); } | hd_via error T_CRLF { PARSE_ERROR("Via"); } | hd_warning error T_CRLF { PARSE_ERROR("Warning"); } | hd_www_authenticate error T_CRLF { PARSE_ERROR("WWW-Authenticate"); } ; // KLUDGE // These rules are needed to get the error recovery working. // Many header rules start with a context change. As Bison uses // one token look ahead to determine a matching rule, the context // change must be done before Bison tries to match the error rule. // Changing the context header and once again at the header rule // does no harm as the context change operator is idem-potent. hd_accept: T_HDR_ACCEPT ':' ; hd_accept_encoding: T_HDR_ACCEPT_ENCODING ':' ; hd_accept_language: T_HDR_ACCEPT_LANGUAGE ':' { CTXT_LANG; } ; hd_alert_info: T_HDR_ALERT_INFO ':' ; hd_allow: T_HDR_ALLOW ':' ; hd_allow_events: T_HDR_ALLOW_EVENTS ':' ; hd_authentication_info: T_HDR_AUTHENTICATION_INFO ':' ; hd_authorization: T_HDR_AUTHORIZATION ':' { CTXT_AUTH_SCHEME; } ; hd_call_id: T_HDR_CALL_ID ':' { CTXT_WORD; } ; hd_call_info: T_HDR_CALL_INFO ':' ; hd_contact: T_HDR_CONTACT ':' { CTXT_URI_SPECIAL; } ; hd_content_disp: T_HDR_CONTENT_DISP ':' ; hd_content_encoding: T_HDR_CONTENT_ENCODING ':' ; hd_content_language: T_HDR_CONTENT_LANGUAGE ':' { CTXT_LANG; } ; hd_content_length: T_HDR_CONTENT_LENGTH ':' { CTXT_NUM; } ; hd_content_type: T_HDR_CONTENT_TYPE ':' ; hd_cseq: T_HDR_CSEQ ':' { CTXT_NUM; } ; hd_date: T_HDR_DATE ':' { CTXT_DATE;} ; hd_error_info: T_HDR_ERROR_INFO ':' ; hd_event: T_HDR_EVENT ':' ; hd_expires: T_HDR_EXPIRES ':' { CTXT_NUM; } ; hd_from: T_HDR_FROM ':' { CTXT_URI_SPECIAL; } ; hd_in_reply_to: T_HDR_IN_REPLY_TO ':' { CTXT_WORD; } ; hd_max_forwards: T_HDR_MAX_FORWARDS ':' { CTXT_NUM; } ; hd_min_expires: T_HDR_MIN_EXPIRES ':' { CTXT_NUM; } ; hd_mime_version: T_HDR_MIME_VERSION ':' ; hd_organization: T_HDR_ORGANIZATION ':' { CTXT_LINE; } ; hd_p_asserted_identity: T_HDR_P_ASSERTED_IDENTITY ':' { CTXT_URI_SPECIAL; } ; hd_p_preferred_identity: T_HDR_P_PREFERRED_IDENTITY ':' { CTXT_URI_SPECIAL; } ; hd_priority: T_HDR_PRIORITY ':' ; hd_privacy: T_HDR_PRIVACY ':' ; hd_proxy_authenticate: T_HDR_PROXY_AUTHENTICATE ':' { CTXT_AUTH_SCHEME; } ; hd_proxy_authorization: T_HDR_PROXY_AUTHORIZATION ':' { CTXT_AUTH_SCHEME; } ; hd_proxy_require: T_HDR_PROXY_REQUIRE ':' ; hd_rack: T_HDR_RACK ':' { CTXT_NUM; } ; hd_record_route: T_HDR_RECORD_ROUTE ':' { CTXT_URI; } ; hd_refer_sub: T_HDR_REFER_SUB ':' ; hd_refer_to: T_HDR_REFER_TO ':' { CTXT_URI_SPECIAL; } ; hd_referred_by: T_HDR_REFERRED_BY ':' { CTXT_URI_SPECIAL; } ; hd_replaces: T_HDR_REPLACES ':' { CTXT_WORD; } ; hd_reply_to: T_HDR_REPLY_TO ':' { CTXT_URI_SPECIAL; } ; hd_require: T_HDR_REQUIRE ':' ; hd_request_disposition: T_HDR_REQUEST_DISPOSITION ':' ; hd_retry_after: T_HDR_RETRY_AFTER ':' { CTXT_NUM; } ; hd_route: T_HDR_ROUTE ':' { CTXT_URI; } ; hd_rseq: T_HDR_RSEQ ':' { CTXT_NUM; } ; hd_server: T_HDR_SERVER ':' ; hd_service_route: T_HDR_SERVICE_ROUTE ':' { CTXT_URI; } ; hd_sip_etag: T_HDR_SIP_ETAG ':' ; hd_sip_if_match: T_HDR_SIP_IF_MATCH ':' ; hd_subject: T_HDR_SUBJECT ':' { CTXT_LINE; } ; hd_subscription_state: T_HDR_SUBSCRIPTION_STATE ':' ; hd_supported: T_HDR_SUPPORTED ':' ; hd_timestamp: T_HDR_TIMESTAMP ':' { CTXT_NUM; } ; hd_to: T_HDR_TO ':' { CTXT_URI_SPECIAL; } ; hd_unsupported: T_HDR_UNSUPPORTED ':' ; hd_user_agent: T_HDR_USER_AGENT ':' ; hd_via: T_HDR_VIA ':' ; hd_warning: T_HDR_WARNING ':' { CTXT_NUM; } ; hd_www_authenticate: T_HDR_WWW_AUTHENTICATE ':' { CTXT_AUTH_SCHEME; } ; hdr_accept: /* empty */ | media_range parameters { $1->add_params(*$2); MSG->hdr_accept.add_media(*$1); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } | hdr_accept ',' media_range parameters { $3->add_params(*$4); MSG->hdr_accept.add_media(*$3); MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($4); delete $4; } ; media_range: T_TOKEN '/' T_TOKEN { $$ = new t_media(tolower(*$1), tolower(*$3)); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; } ; parameters: /* empty */ { $$ = new list; MEMMAN_NEW($$); } | parameters ';' parameter { $1->push_back(*$3); $$ = $1; MEMMAN_DELETE($3); delete $3; } ; parameter: T_TOKEN { $$ = new t_parameter(tolower(*$1)); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; } | T_TOKEN '=' { CTXT_PARAMVAL; } parameter_val { CTXT_INITIAL; } { $$ = new t_parameter(tolower(*$1), *$4); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($4); delete $4; } ; parameter_val: T_PARAMVAL { $$ = $1; } | T_QSTRING { $$ = $1; } ; hdr_accept_encoding: content_coding { MSG->hdr_accept_encoding.add_coding(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_accept_encoding ',' content_coding { MSG->hdr_accept_encoding.add_coding(*$3); MEMMAN_DELETE($3); delete $3; } ; content_coding: T_TOKEN { $$ = new t_coding(tolower(*$1)); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; } | T_TOKEN q_factor { $$ = new t_coding(tolower(*$1)); MEMMAN_NEW($$); $$->q = $2; MEMMAN_DELETE($1); delete $1; } ; q_factor: ';' parameter { if ($2->name != "q") YYERROR; $$ = atof($2->value.c_str()); MEMMAN_DELETE($2); delete $2; } ; hdr_accept_language: { CTXT_LANG; } language { MSG->hdr_accept_language.add_language(*$2); MEMMAN_DELETE($2); delete $2; } | hdr_accept_language ',' { CTXT_LANG; } language { MSG->hdr_accept_language.add_language(*$4); MEMMAN_DELETE($4); delete $4; } ; language: T_LANG { CTXT_INITIAL; $$ = new t_language(tolower(*$1)); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; } | T_LANG { CTXT_INITIAL; } q_factor { $$ = new t_language(tolower(*$1)); MEMMAN_NEW($$); $$->q = $3; MEMMAN_DELETE($1); delete $1; } ; hdr_alert_info: alert_param { MSG->hdr_alert_info.add_param(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_alert_info ',' alert_param { MSG->hdr_alert_info.add_param(*$3); MEMMAN_DELETE($3); delete $3; } ; alert_param: '<' { CTXT_URI; } T_URI { CTXT_INITIAL; } '>' parameters { $$ = new t_alert_param(); MEMMAN_NEW($$); $$->uri.set_url(*$3); $$->parameter_list = *$6; if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($6); delete $6; } ; hdr_allow: T_TOKEN { MSG->hdr_allow.add_method(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_allow ',' T_TOKEN { MSG->hdr_allow.add_method(*$3); MEMMAN_DELETE($3); delete $3; } ; hdr_call_id: { CTXT_WORD; } call_id { CTXT_INITIAL; } { MSG->hdr_call_id.set_call_id(*$2); MEMMAN_DELETE($2); delete $2; } ; call_id: T_WORD { $$ = $1; } | T_WORD '@' T_WORD { $$ = new string(*$1 + '@' + *$3); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; } ; hdr_call_info: info_param { MSG->hdr_call_info.add_param(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_call_info ',' info_param { MSG->hdr_call_info.add_param(*$3); MEMMAN_DELETE($3); delete $3; } ; info_param: '<' { CTXT_URI; } T_URI { CTXT_INITIAL; } '>' parameters { $$ = new t_info_param(); MEMMAN_NEW($$); $$->uri.set_url(*$3); $$->parameter_list = *$6; if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($6); delete $6; } ; hdr_contact: { CTXT_URI_SPECIAL; } T_URI_WILDCARD { CTXT_INITIAL; } { MSG->hdr_contact.set_any(); } | contacts { MSG->hdr_contact.add_contacts(*$1); MEMMAN_DELETE($1); delete $1; } ; contacts: contact_param { $$ = new list; MEMMAN_NEW($$); $$->push_back(*$1); MEMMAN_DELETE($1); delete $1; } | contacts ',' contact_param { $1->push_back(*$3); $$ = $1; MEMMAN_DELETE($3); delete $3; } ; contact_param: contact_addr parameters { $$ = $1; list::const_iterator i; for (i = $2->begin(); i != $2->end(); i++) { if (i->name == "q") { $$->set_qvalue(atof(i->value.c_str())); } else if (i->name == "expires") { $$->set_expires(strtoul( i->value.c_str(), NULL, 10)); } else { $$->add_extension(*i); } } MEMMAN_DELETE($2); delete $2; } ; contact_addr: { CTXT_URI_SPECIAL; } T_URI { CTXT_INITIAL; } { $$ = new t_contact_param(); MEMMAN_NEW($$); $$->uri.set_url(*$2); if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($2); delete $2; } | { CTXT_URI_SPECIAL; } display_name '<' { CTXT_URI; } T_URI { CTXT_INITIAL; } '>' { $$ = new t_contact_param(); MEMMAN_NEW($$); $$->display = *$2; $$->uri.set_url(*$5); if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($5); delete $5; } ; display_name: /* empty */ { $$ = new string(); MEMMAN_NEW($$); } | T_DISPLAY { $$ = new string(rtrim(*$1)); MEMMAN_NEW($$); MEMMAN_DELETE($1); delete $1; } | T_QSTRING { $$ = $1; } ; hdr_content_disp: T_TOKEN parameters { MSG->hdr_content_disp.set_type(tolower(*$1)); list::const_iterator i; for (i = $2->begin(); i != $2->end(); i++) { if (i->name == "filename") { MSG->hdr_content_disp.set_filename(i->value); } else { MSG->hdr_content_disp.add_param(*i); } } MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } ; hdr_content_encoding: content_coding { MSG->hdr_content_encoding.add_coding(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_content_encoding ',' content_coding { MSG->hdr_content_encoding.add_coding(*$3); MEMMAN_DELETE($3); delete $3; } ; hdr_content_language: { CTXT_LANG; } language { MSG->hdr_content_language.add_language(*$2); MEMMAN_DELETE($2); delete $2; } | hdr_content_language ',' { CTXT_LANG; } language { MSG->hdr_content_language.add_language(*$4); MEMMAN_DELETE($4); delete $4; } ; hdr_content_length: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { MSG->hdr_content_length.set_length($2); } ; hdr_content_type: media_range parameters { $1->add_params(*$2); MSG->hdr_content_type.set_media(*$1); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } ; hdr_cseq: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } T_TOKEN { MSG->hdr_cseq.set_seqnr($2); MSG->hdr_cseq.set_method(*$4); MEMMAN_DELETE($4); delete $4; } ; hdr_date: { CTXT_DATE;} T_WKDAY ',' T_NUM T_MONTH T_NUM T_NUM ':' T_NUM ':' T_NUM T_GMT { CTXT_INITIAL; } { struct tm t; t.tm_mday = $4; t.tm_mon = $5; t.tm_year = $6 - 1900; t.tm_hour = $7; t.tm_min = $9; t.tm_sec = $11; MSG->hdr_date.set_date_gm(&t); } ; hdr_error_info: error_param { MSG->hdr_error_info.add_param(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_error_info ',' error_param { MSG->hdr_error_info.add_param(*$3); MEMMAN_DELETE($3); delete $3; } ; error_param: '<' { CTXT_URI; } T_URI { CTXT_INITIAL; } '>' parameters { $$ = new t_error_param(); MEMMAN_NEW($$); $$->uri.set_url(*$3); $$->parameter_list = *$6; if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($6); delete $6; } ; hdr_expires: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { MSG->hdr_expires.set_time($2); } ; hdr_from: { CTXT_URI_SPECIAL; } from_addr parameters { MSG->hdr_from.set_display($2->display); MSG->hdr_from.set_uri($2->uri); list::const_iterator i; for (i = $3->begin(); i != $3->end(); i++) { if (i->name == "tag") { MSG->hdr_from.set_tag(i->value); } else { MSG->hdr_from.add_param(*i); } } MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($3); delete $3; } ; from_addr: T_URI { CTXT_INITIAL; } { $$ = new t_identity(); MEMMAN_NEW($$); $$->set_uri(*$1); if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($1); delete $1; } | display_name '<' { CTXT_URI; } T_URI { CTXT_INITIAL; } '>' { $$ = new t_identity(); MEMMAN_NEW($$); $$->set_display(*$1); $$->set_uri(*$4); if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($4); delete $4; } ; hdr_in_reply_to: { CTXT_WORD; } call_id { CTXT_INITIAL; } { MSG->hdr_in_reply_to.add_call_id(*$2); MEMMAN_DELETE($2); delete $2; } | hdr_in_reply_to ',' { CTXT_WORD; } call_id { CTXT_INITIAL; } { MSG->hdr_in_reply_to.add_call_id(*$4); MEMMAN_DELETE($4); delete $4; } ; hdr_max_forwards: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { MSG->hdr_max_forwards.set_max_forwards($2); } ; hdr_min_expires: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { MSG->hdr_min_expires.set_time($2); } ; hdr_mime_version: T_TOKEN { MSG->hdr_mime_version.set_version(*$1); MEMMAN_DELETE($1); delete $1; } ; hdr_organization: { CTXT_LINE; } T_LINE { CTXT_INITIAL; } { MSG->hdr_organization.set_name(trim(*$2)); MEMMAN_DELETE($2); delete $2; } ; hdr_p_asserted_identity: { CTXT_URI_SPECIAL; } from_addr { MSG->hdr_p_asserted_identity.add_identity(*$2); MEMMAN_DELETE($2); delete $2; } | hdr_p_asserted_identity ',' from_addr { MSG->hdr_p_asserted_identity.add_identity(*$3); MEMMAN_DELETE($3); delete $3; } ; hdr_p_preferred_identity: { CTXT_URI_SPECIAL; } from_addr { MSG->hdr_p_preferred_identity.add_identity(*$2); MEMMAN_DELETE($2); delete $2; } | hdr_p_preferred_identity ',' from_addr { MSG->hdr_p_preferred_identity.add_identity(*$3); MEMMAN_DELETE($3); delete $3; } ; hdr_priority: T_TOKEN { MSG->hdr_priority.set_priority(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } ; hdr_privacy: T_TOKEN { MSG->hdr_privacy.add_privacy(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } | hdr_privacy ';' T_TOKEN { MSG->hdr_privacy.add_privacy(tolower(*$3)); MEMMAN_DELETE($3); delete $3; } ; hdr_proxy_require: T_TOKEN { MSG->hdr_proxy_require.add_feature(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } | hdr_proxy_require ',' T_TOKEN { MSG->hdr_proxy_require.add_feature(tolower(*$3)); MEMMAN_DELETE($3); delete $3; } ; hdr_record_route: rec_route { MSG->hdr_record_route.add_route(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_record_route ',' rec_route { MSG->hdr_record_route.add_route(*$3); MEMMAN_DELETE($3); delete $3; } ; rec_route: { CTXT_URI; } display_name '<' T_URI { CTXT_INITIAL; } '>' parameters { $$ = new t_route; MEMMAN_NEW($$); $$->display = *$2; $$->uri.set_url(*$4); $$->set_params(*$7); if (!$$->uri.is_valid()) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($4); delete $4; MEMMAN_DELETE($7); delete $7; } ; hdr_service_route: rec_route { MSG->hdr_service_route.add_route(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_service_route ',' rec_route { MSG->hdr_service_route.add_route(*$3); MEMMAN_DELETE($3); delete $3; } ; hdr_replaces: { CTXT_WORD; } call_id { CTXT_INITIAL; } parameters { MSG->hdr_replaces.set_call_id(*$2); list::const_iterator i; for (i = $4->begin(); i != $4->end(); i++) { if (i->name == "to-tag") { MSG->hdr_replaces.set_to_tag(i->value); } else if (i->name == "from-tag") { MSG->hdr_replaces.set_from_tag(i->value); } else if (i->name == "early-only") { MSG->hdr_replaces.set_early_only(true); } else { MSG->hdr_replaces.add_param(*i); } } if (!MSG->hdr_replaces.is_valid()) YYERROR; MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($4); delete $4; } ; hdr_reply_to: { CTXT_URI_SPECIAL; } from_addr parameters { MSG->hdr_reply_to.set_display($2->display); MSG->hdr_reply_to.set_uri($2->uri); MSG->hdr_reply_to.set_params(*$3); MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($3); delete $3; } ; hdr_require: T_TOKEN { MSG->hdr_require.add_feature(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } | hdr_proxy_require ',' T_TOKEN { MSG->hdr_require.add_feature(tolower(*$3)); MEMMAN_DELETE($3); delete $3; } ; hdr_retry_after: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } comment parameters { MSG->hdr_retry_after.set_time($2); MSG->hdr_retry_after.set_comment(*$4); list::const_iterator i; for (i = $5->begin(); i != $5->end(); i++) { if (i->name == "duration") { int d = strtoul(i->value.c_str(), NULL, 10); MSG->hdr_retry_after.set_duration(d); } else { MSG->hdr_retry_after.add_param(*i); } } MEMMAN_DELETE($4); delete $4; MEMMAN_DELETE($5); delete $5; } ; comment: /* empty */ { $$ = new string(); MEMMAN_NEW($$); } | '(' { CTXT_COMMENT; } T_COMMENT { CTXT_INITIAL; } ')' { $$ = $3; } ; hdr_route: rec_route { MSG->hdr_route.add_route(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_route ',' rec_route { MSG->hdr_route.add_route(*$3); MEMMAN_DELETE($3); delete $3; } ; hdr_server: server { MSG->hdr_server.add_server(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_server server { MSG->hdr_server.add_server(*$2); MEMMAN_DELETE($2); delete $2; } ; server: comment { $$ = new t_server(); MEMMAN_NEW($$); $$->comment = *$1; MEMMAN_DELETE($1); delete $1; } | T_TOKEN comment { $$ = new t_server(); MEMMAN_NEW($$); $$->product = *$1; $$->comment = *$2; MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } | T_TOKEN '/' T_TOKEN comment { $$ = new t_server(); MEMMAN_NEW($$); $$->product = *$1; $$->version = *$3; $$->comment = *$4; MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($4); delete $4; } ; hdr_subject: { CTXT_LINE; } T_LINE { CTXT_INITIAL; } { MSG->hdr_subject.set_subject(trim(*$2)); MEMMAN_DELETE($2); delete $2; } ; hdr_supported: /* empty */ { MSG->hdr_supported.set_empty(); } | T_TOKEN { MSG->hdr_supported.add_feature(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } | hdr_supported ',' T_TOKEN { MSG->hdr_supported.add_feature(tolower(*$3)); MEMMAN_DELETE($3); delete $3; } ; hdr_timestamp: { CTXT_NUM; } hdr_timestamp1 { CTXT_INITIAL; } ; hdr_timestamp1: timestamp { MSG->hdr_timestamp.set_timestamp($1); } | timestamp delay { MSG->hdr_timestamp.set_timestamp($1); MSG->hdr_timestamp.set_delay($2); } ; timestamp: T_NUM { $$ = $1; } | T_NUM '.' T_NUM { string s = int2str($1) + '.' + int2str($3); $$ = atof(s.c_str()); } ; delay: T_NUM { $$ = $1; } | T_NUM '.' T_NUM { string s = int2str($1) + '.' + int2str($3); $$ = atof(s.c_str()); } ; hdr_to: { CTXT_URI_SPECIAL; } from_addr parameters { MSG->hdr_to.set_display($2->display); MSG->hdr_to.set_uri($2->uri); list::const_iterator i; for (i = $3->begin(); i != $3->end(); i++) { if (i->name == "tag") { MSG->hdr_to.set_tag(i->value); } else { MSG->hdr_to.add_param(*i); } } MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($3); delete $3; } ; hdr_unsupported: T_TOKEN { MSG->hdr_unsupported.add_feature(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } | hdr_unsupported ',' T_TOKEN { MSG->hdr_unsupported.add_feature(tolower(*$3)); MEMMAN_DELETE($3); delete $3; } ; hdr_user_agent: server { MSG->hdr_user_agent.add_server(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_user_agent server { MSG->hdr_user_agent.add_server(*$2); MEMMAN_DELETE($2); delete $2; } ; hdr_via: via_parm { MSG->hdr_via.add_via(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_via ',' via_parm { MSG->hdr_via.add_via(*$3); MEMMAN_DELETE($3); delete $3; } ; via_parm: sent_protocol host parameters { $$ = $1; $$->host = $2->host; $$->port = $2->port; list::const_iterator i; for (i = $3->begin(); i != $3->end(); i++) { if (i->name == "ttl") { $$->ttl = atoi(i->value.c_str()); } else if (i->name == "maddr") { $$->maddr = i->value; } else if (i->name == "received") { $$->received = i->value; } else if (i->name == "branch") { $$->branch = i->value; } else if (i->name == "rport") { $$->rport_present = true; if (i->type == t_parameter::VALUE) { $$->rport = atoi(i->value.c_str()); } } else { $$->add_extension(*i); } } MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($3); delete $3; } ; sent_protocol: T_TOKEN '/' T_TOKEN '/' T_TOKEN { $$ = new t_via(); MEMMAN_NEW($$); $$->protocol_name = toupper(*$1); $$->protocol_version = *$3; $$->transport = toupper(*$5); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; MEMMAN_DELETE($5); delete $5; } ; host: T_TOKEN { $$ = new t_via(); MEMMAN_NEW($$); $$->host = *$1; MEMMAN_DELETE($1); delete $1; } | T_TOKEN ':' { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { if ($4 > 65535) YYERROR; $$ = new t_via(); MEMMAN_NEW($$); $$->host = *$1; $$->port = $4; MEMMAN_DELETE($1); delete $1; } | ipv6reference { $$ = new t_via(); MEMMAN_NEW($$); $$->host = *$1; MEMMAN_DELETE($1); delete $1; } | ipv6reference ':' { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { $$ = new t_via(); MEMMAN_NEW($$); $$->host = *$1; $$->port = $4; MEMMAN_DELETE($1); delete $1; } ; ipv6reference: '[' { CTXT_IPV6ADDR; } T_IPV6ADDR { CTXT_INITIAL; } ']' { // TODO: check correct format of IPv6 address $$ = new string('[' + *$3 + ']'); MEMMAN_NEW($$); MEMMAN_DELETE($3); } ; hdr_warning: warning { MSG->hdr_warning.add_warning(*$1); MEMMAN_DELETE($1); delete $1; } | hdr_warning ',' warning { MSG->hdr_warning.add_warning(*$3); MEMMAN_DELETE($3); delete $3; } ; warning: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } host T_QSTRING { $$ = new t_warning(); MEMMAN_NEW($$); $$->code = $2; $$->host = $4->host; $$->port = $4->port; $$->text = *$5; MEMMAN_DELETE($4); delete $4; MEMMAN_DELETE($5); delete $5; } ; hdr_unknown: { CTXT_LINE; } T_LINE { CTXT_INITIAL; } { $$ = $2; } ; ainfo: parameter { if ($1->name == "nextnonce") MSG->hdr_auth_info.set_next_nonce($1->value); else if ($1->name == "qop") MSG->hdr_auth_info.set_message_qop($1->value); else if ($1->name == "rspauth") MSG->hdr_auth_info.set_response_auth($1->value); else if ($1->name == "cnonce") MSG->hdr_auth_info.set_cnonce($1->value); else if ($1->name == "nc") { MSG->hdr_auth_info.set_nonce_count( hex2int($1->value)); } else { YYERROR; } MEMMAN_DELETE($1); delete $1; } ; hdr_authentication_info: ainfo | hdr_authentication_info ',' ainfo ; digest_response: parameter { $$ = new t_digest_response(); MEMMAN_NEW($$); if (!$$->set_attr(*$1)) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($1); delete $1; } | digest_response ',' parameter { $$ = $1; if (!$$->set_attr(*$3)) { YYERROR; } MEMMAN_DELETE($3); delete $3; } ; auth_params: parameter { $$ = new list; MEMMAN_NEW($$); $$->push_back(*$1); MEMMAN_DELETE($1); delete $1; } | auth_params ',' parameter { $$ = $1; $$->push_back(*$3); MEMMAN_DELETE($3); delete $3; } ; credentials: T_AUTH_DIGEST { CTXT_INITIAL; } digest_response { $$ = new t_credentials; MEMMAN_NEW($$); $$->auth_scheme = AUTH_DIGEST; $$->digest_response = *$3; MEMMAN_DELETE($3); delete $3; } | T_AUTH_OTHER { CTXT_INITIAL; } auth_params { $$ = new t_credentials; MEMMAN_NEW($$); $$->auth_scheme = *$1; $$->auth_params = *$3; MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; } ; hdr_authorization: { CTXT_AUTH_SCHEME; } credentials { MSG->hdr_authorization.add_credentials(*$2); MEMMAN_DELETE($2); delete $2; } ; digest_challenge: parameter { $$ = new t_digest_challenge(); MEMMAN_NEW($$); if (!$$->set_attr(*$1)) { MEMMAN_DELETE($$); delete $$; YYERROR; } MEMMAN_DELETE($1); delete $1; } | digest_challenge ',' parameter { $$ = $1; if (!$$->set_attr(*$3)) { YYERROR; } MEMMAN_DELETE($3); delete $3; } ; challenge: T_AUTH_DIGEST { CTXT_INITIAL; } digest_challenge { $$ = new t_challenge; MEMMAN_NEW($$); $$->auth_scheme = AUTH_DIGEST; $$->digest_challenge = *$3; MEMMAN_DELETE($3); delete $3; } | T_AUTH_OTHER { CTXT_INITIAL; } auth_params { $$ = new t_challenge; MEMMAN_NEW($$); $$->auth_scheme = *$1; $$->auth_params = *$3; MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($3); delete $3; } ; hdr_proxy_authenticate: { CTXT_AUTH_SCHEME; } challenge { MSG->hdr_proxy_authenticate.set_challenge(*$2); MEMMAN_DELETE($2); delete $2; } ; hdr_proxy_authorization: { CTXT_AUTH_SCHEME; } credentials { MSG->hdr_proxy_authorization. add_credentials(*$2); MEMMAN_DELETE($2); delete $2; } ; hdr_www_authenticate: { CTXT_AUTH_SCHEME; } challenge { MSG->hdr_www_authenticate.set_challenge(*$2); MEMMAN_DELETE($2); delete $2; } ; hdr_rseq: { CTXT_NUM; } T_NUM { CTXT_INITIAL; } { MSG->hdr_rseq.set_resp_nr($2); } ; hdr_rack: { CTXT_NUM; } T_NUM T_NUM { CTXT_INITIAL; } T_TOKEN { MSG->hdr_rack.set_resp_nr($2); MSG->hdr_rack.set_cseq_nr($3); MSG->hdr_rack.set_method(*$5); MEMMAN_DELETE($5); delete $5; } ; hdr_event: T_TOKEN parameters { MSG->hdr_event.set_event_type(tolower(*$1)); list::const_iterator i; for (i = $2->begin(); i != $2->end(); i++) { if (i->name == "id") { MSG->hdr_event.set_id(i->value); } else { MSG->hdr_event.add_event_param(*i); } } MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } ; hdr_allow_events: T_TOKEN { MSG->hdr_allow_events.add_event_type(tolower(*$1)); MEMMAN_DELETE($1); delete $1; } | hdr_allow_events ',' T_TOKEN { MSG->hdr_allow_events.add_event_type(tolower(*$3)); MEMMAN_DELETE($3); delete $3; } ; hdr_subscription_state: T_TOKEN parameters { MSG->hdr_subscription_state.set_substate(tolower(*$1)); list::const_iterator i; for (i = $2->begin(); i != $2->end(); i++) { if (i->name == "reason") { MSG->hdr_subscription_state. set_reason(tolower(i->value)); } else if (i->name == "expires") { MSG->hdr_subscription_state. set_expires(strtoul( i->value.c_str(), NULL, 10)); } else if (i->name == "retry-after") { MSG->hdr_subscription_state. set_retry_after(strtoul( i->value.c_str(), NULL, 10)); } else { MSG->hdr_subscription_state. add_extension(*i); } } MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } ; hdr_refer_to: { CTXT_URI_SPECIAL; } from_addr parameters { MSG->hdr_refer_to.set_display($2->display); MSG->hdr_refer_to.set_uri($2->uri); MSG->hdr_refer_to.set_params(*$3); MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($3); delete $3; } ; hdr_referred_by: { CTXT_URI_SPECIAL; } from_addr parameters { MSG->hdr_referred_by.set_display($2->display); MSG->hdr_referred_by.set_uri($2->uri); list::const_iterator i; for (i = $3->begin(); i != $3->end(); i++) { if (i->name == "cid") { MSG->hdr_referred_by.set_cid(i->value); } else { MSG->hdr_referred_by.add_param(*i); } } MEMMAN_DELETE($2); delete $2; MEMMAN_DELETE($3); delete $3; } ; hdr_refer_sub: T_TOKEN parameters { string value(tolower(*$1)); if (value != "true" && value != "false") { YYERROR; } MSG->hdr_refer_sub.set_create_refer_sub(value == "true"); MSG->hdr_refer_sub.set_extensions(*$2); MEMMAN_DELETE($1); delete $1; MEMMAN_DELETE($2); delete $2; } ; hdr_sip_etag: T_TOKEN { MSG->hdr_sip_etag.set_etag(*$1); MEMMAN_DELETE($1); delete $1; } ; hdr_sip_if_match: T_TOKEN { MSG->hdr_sip_if_match.set_etag(*$1); MEMMAN_DELETE($1); delete $1; } ; hdr_request_disposition: T_TOKEN { bool ret = MSG->hdr_request_disposition.set_directive(*$1); if (!ret) YYERROR; MEMMAN_DELETE($1); delete $1; } | hdr_request_disposition ',' T_TOKEN { bool ret = MSG->hdr_request_disposition.set_directive(*$3); if (!ret) YYERROR; MEMMAN_DELETE($3); delete $3; } %% void yyerror (const char *s) /* Called by yyparse on error */ { // printf ("%s\n", s); } twinkle-1.4.2/src/parser/credentials.cpp0000644000175000001440000000637411127714057015213 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "credentials.h" #include "definitions.h" #include "util.h" t_digest_response::t_digest_response() { nonce_count = 0; } string t_digest_response::encode(void) const { string s; if (username.size() > 0) { s += "username="; s += '"'; s += username; s += '"'; } if (realm.size() > 0) { if (s.size() > 0) s += ','; s += "realm="; s += '"'; s += realm; s += '"'; } if (nonce.size() > 0) { if (s.size() > 0) s += ','; s += "nonce="; s += '"'; s += nonce; s += '"'; } if (digest_uri.is_valid()) { if (s.size() > 0) s += ','; s += "uri="; s += '"'; s += digest_uri.encode(); s += '"'; } if (dresponse.size() > 0) { if (s.size() > 0) s += ','; s += "response="; s += '"'; s += dresponse; s += '"'; } if (algorithm.size() > 0) { if (s.size() > 0) s += ','; s += "algorithm="; s += algorithm; } if (cnonce.size() > 0) { if (s.size() > 0) s += ','; s += "cnonce="; s += '"'; s += cnonce; s += '"'; } if (opaque.size() > 0) { if (s.size() > 0) s += ','; s += "opaque="; s += '"'; s += opaque; s += '"'; } if (message_qop.size() > 0) { if (s.size() > 0) s += ','; s += "qop="; s += message_qop; } if (nonce_count > 0) { if (s.size() > 0) s += ','; s += "nc="; s += ulong2str(nonce_count, "%08x"); } for (list::const_iterator i = auth_params.begin(); i != auth_params.end(); i++) { if (s.size() > 0) s += ','; s += i->encode(); } return s; } bool t_digest_response::set_attr(const t_parameter &p) { if (p.name == "username") username = p.value; else if (p.name == "realm") realm = p.value; else if (p.name == "nonce") nonce = p.value; else if (p.name == "digest_uri") { digest_uri.set_url(p.value); if (!digest_uri.is_valid()) return false; } else if (p.name == "response") dresponse = p.value; else if (p.name == "cnonce") cnonce = p.value; else if (p.name == "opaque") opaque = p.value; else if (p.name == "algorithm") algorithm = p.value; else if (p.name == "qop") message_qop = p.value; else if (p.name == "nc") nonce_count = hex2int(p.value); else auth_params.push_back(p); return true; } string t_credentials::encode(void) const { string s = auth_scheme; s += ' '; if (auth_scheme == AUTH_DIGEST) { s += digest_response.encode(); } else { for (list::const_iterator i = auth_params.begin(); i != auth_params.end(); i++) { if (i != auth_params.begin()) s += ','; s += i->encode(); } } return s; } twinkle-1.4.2/src/parser/hdr_route.h0000644000175000001440000000254511127714050014343 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Route header #ifndef _H_HDR_ROUTE #define _H_HDR_ROUTE #include #include #include "route.h" #include "header.h" #include "parameter.h" using namespace std; class t_hdr_route : public t_header { public: list route_list; // If route_to_first_route == true, then the request must be routed // to the first route in the list. Otherwise to the request URI. bool route_to_first_route; t_hdr_route(); void add_route(const t_route &r); string encode(void) const; string encode_multi_header(void) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/identity.cpp0000644000175000001440000000237411127714057014543 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "identity.h" #include "util.h" t_identity::t_identity() : display(), uri() {} void t_identity::set_display(const string &d) { display = d; } void t_identity::set_uri(const string &u) { uri.set_url(u); } void t_identity::set_uri(const t_url &u) { uri = u; } string t_identity::encode(void) const { string s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; return s; } twinkle-1.4.2/src/parser/hdr_request_disposition.h0000644000175000001440000000543011142402274017314 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Request-Disposition header (RFC 3841) */ #ifndef _H_HDR_REQUEST_DISPOSITION #define _H_HDR_REQUEST_DISPOSITION #include #include "header.h" using namespace std; #define REQDIS_PROXY "proxy" #define REQDIS_REDIRECT "redirect" #define REQDIS_CANCEL "cancel" #define REQDIS_NO_CANCEL "no-cancel" #define REQDIS_FORK "fork" #define REQDIS_NO_FORK "no-fork" #define REQDIS_RECURSE "recurse" #define REQDIS_NO_RECURSE "no-recurse" #define REQDIS_PARALLEL "parallel" #define REQDIS_SEQUENTIAL "sequential" #define REQDIS_QUEUE "queue" #define REQDIS_NO_QUEUE "no-queue" /** Request-Disposition header (RFC 3841) */ class t_hdr_request_disposition : public t_header { public: enum t_proxy_directive { PROXY_NULL, PROXY, REDIRECT }; enum t_cancel_directive { CANCEL_NULL, CANCEL, NO_CANCEL }; enum t_fork_directive { FORK_NULL, FORK, NO_FORK }; enum t_recurse_directive { RECURSE_NULL, RECURSE, NO_RECURSE }; enum t_parallel_directive { PARALLEL_NULL, PARALLEL, SEQUENTIAL }; enum t_queue_directive { QUEUE_NULL, QUEUE, NO_QUEUE }; t_proxy_directive proxy_directive; t_cancel_directive cancel_directive; t_fork_directive fork_directive; t_recurse_directive recurse_directive; t_parallel_directive parallel_directive; t_queue_directive queue_directive; t_hdr_request_disposition(); void set_proxy_directive(t_proxy_directive directive); void set_cancel_directive(t_cancel_directive directive); void set_fork_directive(t_fork_directive directive); void set_recurse_directive(t_recurse_directive directive); void set_parallel_directive(t_parallel_directive directive); void set_queue_directive(t_queue_directive directive); /** * Set a directive using one of the tokens define in RFC 3841 * @param s [in] Directive token. * @return True if directive set. False if directive is invalid or * conflicts with exisiting directives. */ bool set_directive(const string &s); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_accept.h0000644000175000001440000000243111127714050014436 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Accept header #ifndef _HDR_ACCEPT_H #define _HDR_ACCEPT_H #include #include "header.h" #include "media_type.h" class t_hdr_accept : public t_header { public: list media_list; // list of accepted media t_hdr_accept(); // Add a media to the list of accepted media void add_media(const t_media &media); // Clear the list of features, but make the header 'populated'. // An empty header will be in the message. void set_empty(void); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_retry_after.h0000644000175000001440000000252311127714050015527 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Retry-After header #ifndef _H_HDR_RETRY_AFTER #define _H_HDR_RETRY_AFTER #include #include #include "header.h" #include "parameter.h" using namespace std; class t_hdr_retry_after : public t_header { public: unsigned long time; // in seconds string comment; unsigned long duration; // in seconds list params; t_hdr_retry_after(); void set_time(unsigned long t); void set_comment(const string &c); void set_duration(unsigned long d); void add_param(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_proxy_authenticate.cpp0000644000175000001440000000223011127714057017455 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_proxy_authenticate.h" #include "definitions.h" t_hdr_proxy_authenticate::t_hdr_proxy_authenticate() : t_header("Proxy-Authenticate") {} void t_hdr_proxy_authenticate::set_challenge(const t_challenge &c) { populated = true; challenge = c; } string t_hdr_proxy_authenticate::encode_value(void) const { if (!populated) return ""; return challenge.encode(); } twinkle-1.4.2/src/parser/response.h0000644000175000001440000001437111127714050014206 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Response #ifndef _H_RESPONSE #define _H_RESPONSE #include #include "sip_message.h" using namespace std; // Repsonse codes // Informational #define R_100_TRYING 100 #define R_180_RINGING 180 #define R_181_CALL_IS_BEING_FORWARDED 181 #define R_182_QUEUED 182 #define R_183_SESSION_PROGRESS 183 // Success #define R_200_OK 200 #define R_202_ACCEPTED 202 // Redirection #define R_300_MULTIPLE_CHOICES 300 #define R_301_MOVED_PERMANENTLY 301 #define R_302_MOVED_TEMPORARILY 302 #define R_305_USE_PROXY 305 #define R_380_ALTERNATIVE_SERVICE 380 // Client error #define R_400_BAD_REQUEST 400 #define R_401_UNAUTHORIZED 401 #define R_402_PAYMENT_REQUIRED 402 #define R_403_FORBIDDEN 403 #define R_404_NOT_FOUND 404 #define R_405_METHOD_NOT_ALLOWED 405 #define R_406_NOT_ACCEPTABLE 406 #define R_407_PROXY_AUTH_REQUIRED 407 #define R_408_REQUEST_TIMEOUT 408 #define R_410_GONE 410 #define R_412_CONDITIONAL_REQUEST_FAILED 412 #define R_413_REQ_ENTITY_TOO_LARGE 413 #define R_414_REQ_URI_TOO_LARGE 414 #define R_415_UNSUPPORTED_MEDIA_TYPE 415 #define R_416_UNSUPPORTED_URI_SCHEME 416 #define R_420_BAD_EXTENSION 420 #define R_421_EXTENSION_REQUIRED 421 #define R_423_INTERVAL_TOO_BRIEF 423 #define R_480_TEMP_NOT_AVAILABLE 480 #define R_481_TRANSACTION_NOT_EXIST 481 #define R_482_LOOP_DETECTED 482 #define R_483_TOO_MANY_HOPS 483 #define R_484_ADDRESS_INCOMPLETE 484 #define R_485_AMBIGUOUS 485 #define R_486_BUSY_HERE 486 #define R_487_REQUEST_TERMINATED 487 #define R_488_NOT_ACCEPTABLE_HERE 488 #define R_489_BAD_EVENT 489 #define R_491_REQUEST_PENDING 491 #define R_493_UNDECIPHERABLE 493 // Server error #define R_500_INTERNAL_SERVER_ERROR 500 #define R_501_NOT_IMPLEMENTED 501 #define R_502_BAD_GATEWAY 502 #define R_503_SERVICE_UNAVAILABLE 503 #define R_504_SERVER_TIMEOUT 504 #define R_505_SIP_VERSION_NOT_SUPPORTED 505 #define R_513_MESSAGE_TOO_LARGE 513 // Global failure #define R_600_BUSY_EVERYWHERE 600 #define R_603_DECLINE 603 #define R_604_NOT_EXIST_ANYWHERE 604 #define R_606_NOT_ACCEPTABLE 606 // Response classes #define R_1XX 1 // Informational #define R_2XX 2 // Success #define R_3XX 3 // Redirection #define R_4XX 4 // Client error #define R_5XX 5 // Server error #define R_6XX 6 // Global failure // Default reason strings #define REASON_100 "Trying" #define REASON_180 "Ringing" #define REASON_181 "Call Is Being Forwarded" #define REASON_182 "Queued" #define REASON_183 "Session Progress" #define REASON_200 "OK" #define REASON_202 "Accepted" #define REASON_300 "Multiple Choices" #define REASON_301 "Moved Permanently" #define REASON_302 "Moved Temporarily" #define REASON_305 "Use Proxy" #define REASON_380 "Alternative Service" #define REASON_400 "Bad Request" #define REASON_401 "Unauthorized" #define REASON_402 "Payment Required" #define REASON_403 "Forbidden" #define REASON_404 "Not Found" #define REASON_405 "Method Not Allowed" #define REASON_406 "Not Acceptable" #define REASON_407 "Proxy Authentication Required" #define REASON_408 "Request Timeout" #define REASON_410 "Gone" #define REASON_412 "Conditional Request Failed" #define REASON_413 "Request Entity Too Large" #define REASON_414 "Request-URI Too Large" #define REASON_415 "Unsupported Media Type" #define REASON_416 "Unsupported URI Scheme" #define REASON_420 "Bad Extension" #define REASON_421 "Extension Required" #define REASON_423 "Interval Too Brief" #define REASON_480 "Temporarily Not Available" #define REASON_481 "Call Leg/Transaction Does Not Exist" #define REASON_482 "Loop Detected" #define REASON_483 "Too Many Hops" #define REASON_484 "Address Incomplete" #define REASON_485 "Ambiguous" #define REASON_486 "Busy Here" #define REASON_487 "Request Terminated" #define REASON_488 "Not Acceptable Here" #define REASON_489 "Bad Event" #define REASON_491 "Request Pending" #define REASON_493 "Undecipherable" #define REASON_500 "Internal Server Error" #define REASON_501 "Not Implemented" #define REASON_502 "Bad Gateway" #define REASON_503 "Service Unavailable" #define REASON_504 "Server Time-out" #define REASON_505 "SIP Version Not Supported" #define REASON_513 "Message Too Large" #define REASON_600 "Busy Everywhere" #define REASON_603 "Decline" #define REASON_604 "Does Not Exist Anywhere" #define REASON_606 "Not Acceptable" // The protocol allows a SIP response to have a non-default reason // phrase that gives a more detailed reason. // RFC 3261 21.4.18 // Code 480 should have a specific reason phrase #define REASON_480_NO_ANSWER "User not responding" // RFC 3265 3.2.4 #define REASON_481_SUBSCRIPTION_NOT_EXIST "Subscription does not exist" class t_response : public t_sip_message { public: int code; string reason; /** The source address of the request generating this response. */ t_ip_port src_ip_port_request; t_response(); t_response(const t_response &r); t_response(int _code, string _reason = ""); t_msg_type get_type(void) const { return MSG_RESPONSE; } // Return the response class 1,2,3,4,5,6 int get_class(void) const; bool is_provisional(void) const; bool is_final(void) const; bool is_success(void) const; string encode(bool add_content_length = true); list encode_env(void); t_sip_message *copy(void) const; bool is_valid(bool &fatal, string &reason) const; // Returns true if the response is a 401/407 with // the proper authenticate header. bool must_authenticate(void) const; /** * Get the destination address for sending the response. * @param ip_port [out] The destination address. */ void get_destination(t_ip_port &ip_port) const; virtual void calc_local_ip(void); }; #endif twinkle-1.4.2/src/parser/hdr_server.cpp0000644000175000001440000000340711127714057015053 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_server.h" #include "util.h" t_server::t_server() {} t_server::t_server(const string &_product, const string &_version, const string &_comment) { product = _product; version = _version; comment = _comment; } string t_server::encode(void) const { string s; s = product; if (version.size() > 0) { s += '/'; s += version; } if (comment.size() > 0) { if (s.size() > 0) s += ' '; s += "("; s += comment; s += ')'; } return s; } t_hdr_server::t_hdr_server() : t_header("Server") {}; void t_hdr_server::add_server(const t_server &s) { populated = true; server_info.push_back(s); } string t_hdr_server::get_server_info(void) const { string s; for (list::const_iterator i = server_info.begin(); i != server_info.end(); i++ ) { if (i != server_info.begin()) s += ' '; s += i->encode(); } return s; } string t_hdr_server::encode_value(void) const { if (!populated) return ""; return get_server_info(); } twinkle-1.4.2/src/parser/hdr_content_encoding.cpp0000644000175000001440000000253211127714057017063 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_content_encoding.h" #include "definitions.h" #include "parse_ctrl.h" t_hdr_content_encoding::t_hdr_content_encoding() : t_header("Content-Encoding", "e") {}; void t_hdr_content_encoding::add_coding(const t_coding &coding) { populated = true; coding_list.push_back(coding); } string t_hdr_content_encoding::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = coding_list.begin(); i != coding_list.end(); i++) { if (i != coding_list.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_proxy_authenticate.h0000644000175000001440000000226011127714050017116 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Proxy-Authenticate header #ifndef _HDR_PROXY_AUTHENTICATE_H #define _HDR_PROXY_AUTHENTICATE_H #include #include #include "challenge.h" #include "header.h" using namespace std; class t_hdr_proxy_authenticate : public t_header { public: t_challenge challenge; t_hdr_proxy_authenticate(); void set_challenge(const t_challenge &c); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_timestamp.cpp0000644000175000001440000000245211127714057015547 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_timestamp.h" #include "util.h" t_hdr_timestamp::t_hdr_timestamp() : t_header("Timestamp") { timestamp = 0; delay = 0; } void t_hdr_timestamp::set_timestamp(float t) { populated = true; timestamp = t; } void t_hdr_timestamp::set_delay(float d) { populated = true; delay = d; } string t_hdr_timestamp::encode_value(void) const { string s; if (!populated) return s; s += float2str(timestamp, 3); if (delay != 0) { s += " "; s += float2str(delay, 3); } return s; } twinkle-1.4.2/src/parser/definitions.h0000644000175000001440000000357011127714050014662 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _DEFINITIONS_H #define _DEFINITIONS_H #include #include "protocol.h" #include "sockets/url.h" using namespace std; #define SIP_VERSION "2.0" // RFC 3261 #ifndef RFC3261_COOKIE #define RFC3261_COOKIE "z9hG4bK" #endif // Authentication schemes #define AUTH_DIGEST "Digest" // Authentication algorithms #define ALG_MD5 "MD5" #define ALG_AKAV1_MD5 "AKAV1-MD5" #define ALG_MD5_SESS "MD5-sess" // Authentication QOP #define QOP_AUTH "auth" #define QOP_AUTH_INT "auth-int" /** SIP request methods. */ enum t_method { INVITE, ACK, OPTIONS, BYE, CANCEL, REGISTER, PRACK, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE, PUBLISH, METHOD_UNKNOWN }; /** * Convert a method to a string. * @param m The method. * @param unknown Method name if m is @ref METHOD_UNKNOWN. * @return The name of the method. */ string method2str(const t_method &m, const string &unknown = ""); /** * Convert a string to a method. * @param s The string. * @return The method having s as name. If s is an unknown name, * then @ref METHOD_UNKNOWN is returned. */ t_method str2method(const string &s); #endif twinkle-1.4.2/src/parser/hdr_min_expires.h0000644000175000001440000000217011127714050015521 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Expires header #ifndef _HDR_MIN_EXPIRES_LENGTH #define _HDR_MIN_EXPIRES_LENGTH #include #include "header.h" using namespace std; class t_hdr_min_expires : public t_header { public: unsigned long time; // expiry time in seconds t_hdr_min_expires(); void set_time(unsigned long t); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_service_route.h0000644000175000001440000000240111127714050016052 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Service-Route header #ifndef _H_HDR_SERVICE_ROUTE #define _H_HDR_SERVICE_ROUTE #include #include #include "route.h" #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_service_route : public t_header { public: list route_list; t_hdr_service_route(); void add_route(const t_route &r); string encode(void) const; string encode_multi_header(void) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_accept_language.cpp0000644000175000001440000000315111127714057016643 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_accept_language.h" #include "util.h" t_language::t_language() { language = "en"; q = 1.0; } t_language::t_language(const string &l) { language = l; q = 1.0; } string t_language::encode(void) const { string s; s = language; if (q != 1.0) { s += ";q="; s += float2str(q, 1); } return s; } t_hdr_accept_language::t_hdr_accept_language() : t_header("Accept-Language") {}; void t_hdr_accept_language::add_language(const t_language &language) { populated = true; language_list.push_back(language); } string t_hdr_accept_language::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = language_list.begin(); i != language_list.end(); i++) { if (i != language_list.begin()) s += ","; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/milenage.h0000644000175000001440000000233611127714050014127 00000000000000/*------------------------------------------------------------------- * Example algorithms f1, f1*, f2, f3, f4, f5, f5* *------------------------------------------------------------------- * * A sample implementation of the example 3GPP authentication and * key agreement functions f1, f1*, f2, f3, f4, f5 and f5*. This is * a byte-oriented implementation of the functions, and of the block * cipher kernel function Rijndael. * * This has been coded for clarity, not necessarily for efficiency. * * The functions f2, f3, f4 and f5 share the same inputs and have * been coded together as a single function. f1, f1* and f5* are * all coded separately. * *-----------------------------------------------------------------*/ #ifndef MILENAGE_H #define MILENAGE_H typedef unsigned char u8; void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], u8 mac_a[8], u8 op[16] ); void f2345 ( u8 k[16], u8 rand[16], u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] ); void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], u8 mac_s[8], u8 op[16] ); void f5star( u8 k[16], u8 rand[16], u8 ak[6], u8 op[16] ); void ComputeOPc( u8 op_c[16], u8 op[16] ); #endif twinkle-1.4.2/src/parser/hdr_replaces.h0000644000175000001440000000266511127714050015006 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Replaces header // RFC 3891 #ifndef _H_HDR_REPLACES #define _H_HDR_REPLACES #include #include #include "header.h" #include "parameter.h" using namespace std; class t_hdr_replaces : public t_header { public: string call_id; string to_tag; string from_tag; bool early_only; list params; t_hdr_replaces(); void set_call_id(const string &id); void set_to_tag(const string &tag); void set_from_tag(const string &tag); void set_early_only(const bool on); void set_params(const list &l); void add_param(const t_parameter &p); string encode_value(void) const; bool is_valid(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_content_length.cpp0000644000175000001440000000230411134635712016551 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_content_length.h" #include "parse_ctrl.h" #include "util.h" t_hdr_content_length::t_hdr_content_length() : t_header("Content-Length", "l") { length = 0; } void t_hdr_content_length::set_length(unsigned long l) { populated = true; length = l; } string t_hdr_content_length::encode_value(void) const { string s; if (!populated) return s; s = ulong2str(length); return s; } twinkle-1.4.2/src/parser/hdr_referred_by.cpp0000644000175000001440000000347011127714057016035 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_referred_by.h" #include "definitions.h" #include "parse_ctrl.h" #include "util.h" t_hdr_referred_by::t_hdr_referred_by() : t_header("Referred-By", "b") {} void t_hdr_referred_by::set_display(const string &d) { populated = true; display = d; } void t_hdr_referred_by::set_uri(const string &u) { populated = true; uri.set_url(u); } void t_hdr_referred_by::set_uri(const t_url &u) { populated = true; uri = u; } void t_hdr_referred_by::set_cid(const string &c) { populated = true; cid = c; } void t_hdr_referred_by::set_params(const list &l) { populated = true; params = l; } void t_hdr_referred_by::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_referred_by::encode_value(void) const { string s; if (!populated) return s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; if (cid.size() > 0) { s += ";cid="; s += cid; } s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/route.h0000644000175000001440000000216111127714050013500 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Route item #ifndef _H_ROUTE #define _H_ROUTE #include #include #include "parameter.h" using namespace std; class t_route { public: string display; t_url uri; list params; void add_param(const t_parameter &p); void set_params(const list &l); string encode(void) const; }; #endif twinkle-1.4.2/src/parser/sip_body.h0000644000175000001440000001521111127714050014152 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // SIP bodies #ifndef _H_SIP_BODY #define _H_SIP_BODY #include #include #include #include "media_type.h" //@{ /** @name Utilies for XML body parsing */ /** * Check the tag name of an XML node. * @param node [in] (xmlNode *) The XML node to check. * @param tag [in] (const char *) The tag name. * @param namespace [in] (const char *) The namespace of the tag. * @return true if the node has the tag name within the name space. */ #define IS_XML_TAG(node, tag, namespace)\ ((node)->type == XML_ELEMENT_NODE &&\ (node)->ns &&\ xmlStrEqual((node)->ns->href, BAD_CAST (namespace)) &&\ xmlStrEqual((node)->name, BAD_CAST (tag))) /** * Check the attribute name of an XML attribute. */ #define IS_XML_ATTR(attr, attr_name, namespace)\ ((attr)->type == XML_ATTRIBUTE_NODE &&\ (attr)->ns &&\ xmlStrEqual((attr)->ns->href, BAD_CAST (namespace)) &&\ xmlStrEqual((attr)->name, BAD_CAST (attr_name))) //@} class t_sip_message; using namespace std; /** Body type. */ enum t_body_type { BODY_OPAQUE, /**< Opaque body. */ BODY_SDP, /**< SDP */ BODY_SIPFRAG, /**< message/sipfrag RFC 3420 */ BODY_DTMF_RELAY, /**< DTMF relay as defined by Cisco */ BODY_SIMPLE_MSG_SUM, /**< Simple message summary RFC 3842 */ BODY_PLAIN_TEXT, /**< Plain text for messaging */ BODY_HTML_TEXT, /**< HTML text for messaging */ BODY_PIDF_XML, /**< pidf+xml RFC 3863 */ BODY_IM_ISCOMPOSING_XML /**< im-iscomposing+xml RFC 3994 */ }; /** Abstract base class for SIP bodies. */ class t_sip_body { public: /** * Indicates if the body content is invalid. * This will be set by the body parser. */ bool invalid; /** Constructor. */ t_sip_body(); virtual ~t_sip_body() {} /** * Encode the body. * @return Text encoded body. */ virtual string encode(void) const = 0; /** * Create a copy of the body. * @return Copy of the body. */ virtual t_sip_body *copy(void) const = 0; /** * Get type of body. * @return body type. */ virtual t_body_type get_type(void) const = 0; /** * Get content type for this type of body. * @return Content type. */ virtual t_media get_media(void) const = 0; /** * Check if all local IP address are correctly filled in. This * check is an integrity check to help debugging the auto IP * discover feature. */ virtual bool local_ip_check(void) const; /** * Return the size of the encoded body. This method encodes the body * to calculate the size. When a more efficient algorithm is available * a sub class may override this method. * @return The size of the encoded body in bytes. */ virtual size_t get_encoded_size(void) const; }; /** Abstract base class for XML formatted bodies. */ class t_sip_body_xml : public t_sip_body { protected: xmlDoc *xml_doc; /**< XML document */ /** * Create an empty XML document. * Override this method to create the specific XML document. * @param xml_version [in] The XML version of the document. * @param charset [in] The character set of the document. */ virtual void create_xml_doc(const string &xml_version = "1.0", const string &charset = "UTF-8"); /** Remove the XML document */ virtual void clear_xml_doc(void); /** * Copy the XML document from this body to another body. * @param to_body [in] The body to copy the XML body to. */ virtual void copy_xml_doc(t_sip_body_xml *to_body) const; public: /** Constructor */ t_sip_body_xml(); /** Destructor */ virtual ~t_sip_body_xml(); virtual string encode(void) const; /** * Parse a text representation of the body. * The result is stored in @ref xml_doc * @param s [in] Text to parse. * @return True if parsing and state extracting succeeded, false otherwise. * @pre xml_doc == NULL * @post If parsing succeeds then xml_doc != NULL */ virtual bool parse(const string &s); }; /** * This body can contain any type of body. The contents are * unparsed and thus opaque. */ class t_sip_body_opaque : public t_sip_body { public: string opaque; /**< The body contents. */ /** Construct body with empty content. */ t_sip_body_opaque(); /** * Construct a body with opaque content. * @param s [in] The content. */ t_sip_body_opaque(string s); string encode(void) const; t_sip_body *copy(void) const; t_body_type get_type(void) const; t_media get_media(void) const; virtual size_t get_encoded_size(void) const; }; // RFC 3420 // sipfrag body class t_sip_body_sipfrag : public t_sip_body { public: t_sip_message *sipfrag; t_sip_body_sipfrag(t_sip_message *m); ~t_sip_body_sipfrag(); string encode(void) const; t_sip_body *copy(void) const; t_body_type get_type(void) const; t_media get_media(void) const; }; // application/dtmf-relay body class t_sip_body_dtmf_relay : public t_sip_body { public: char signal; uint16 duration; // ms t_sip_body_dtmf_relay(); t_sip_body_dtmf_relay(char _signal, uint16 _duration); string encode(void) const; t_sip_body *copy(void) const; t_body_type get_type(void) const; t_media get_media(void) const; bool parse(const string &s); }; /** Plain text body. */ class t_sip_body_plain_text : public t_sip_body { public: string text; /**< The text */ /** Construct a body with empty text. */ t_sip_body_plain_text(); /** * Constructor. * @param _text [in] The body text. */ t_sip_body_plain_text(const string &_text); string encode(void) const; t_sip_body *copy(void) const; t_body_type get_type(void) const; t_media get_media(void) const; virtual size_t get_encoded_size(void) const; }; /** Html text body. */ class t_sip_body_html_text : public t_sip_body { public: string text; /**< The text */ /** * Constructor. * @param _text [in] The body text. */ t_sip_body_html_text(const string &_text); string encode(void) const; t_sip_body *copy(void) const; t_body_type get_type(void) const; t_media get_media(void) const; virtual size_t get_encoded_size(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_content_type.cpp0000644000175000001440000000222511127714057016255 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_content_type.h" #include "definitions.h" #include "parse_ctrl.h" t_hdr_content_type::t_hdr_content_type() : t_header("Content-Type", "c") {}; void t_hdr_content_type::set_media(const t_media &m) { populated = true; media = m; } string t_hdr_content_type::encode_value(void) const { string s; if (!populated) return s; s = media.encode(); return s; } twinkle-1.4.2/src/parser/hdr_subscription_state.cpp0000644000175000001440000000355411127714057017474 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_subscription_state.h" #include "util.h" t_hdr_subscription_state::t_hdr_subscription_state() : t_header("Subscription-State") { expires = 0; retry_after = 0; } void t_hdr_subscription_state::set_substate(const string &s) { populated = true; substate = s; } void t_hdr_subscription_state::set_reason(const string &s) { populated = true; reason = s; } void t_hdr_subscription_state::set_expires(unsigned long e) { populated = true; expires = e; } void t_hdr_subscription_state::set_retry_after(unsigned long r) { populated = true; retry_after = r; } void t_hdr_subscription_state::add_extension(const t_parameter &p) { populated = true; extensions.push_back(p); } string t_hdr_subscription_state::encode_value(void) const { string s; if (!populated) return s; s = substate; if (reason.size() > 0) { s += ";reason="; s += reason; } if (expires > 0) { s += ";expires="; s += ulong2str(expires); } if (retry_after > 0) { s += ";retry-after="; s += ulong2str(retry_after); } s += param_list2str(extensions); return s; } twinkle-1.4.2/src/parser/hdr_error_info.cpp0000644000175000001440000000301711127714057015706 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_error_info.h" void t_error_param::add_param(const t_parameter &p) { parameter_list.push_back(p); } string t_error_param::encode(void) const { string s; s = '<' + uri.encode() + '>'; s += param_list2str(parameter_list); return s; } t_hdr_error_info::t_hdr_error_info() : t_header("Error-Info") {}; void t_hdr_error_info::add_param(const t_error_param &p) { populated = true; error_param_list.push_back(p); } string t_hdr_error_info::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = error_param_list.begin(); i != error_param_list.end(); i++) { if (i != error_param_list.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_event.h0000644000175000001440000000275711127714050014333 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Event header // RFC 3265 #ifndef _HDR_EVENT #define _HDR_EVENT #include #include #include "header.h" #include "parameter.h" #define SIP_EVENT_REFER "refer" // RFC 3515 #define SIP_EVENT_MSG_SUMMARY "message-summary" // RFC 3842 #define SIP_EVENT_PRESENCE "presence" // RFC 3856 using namespace std; class t_hdr_event : public t_header { public: // The event_type attribute contains the event-template as well // if present, e.g. event.template string event_type; string id; list event_params; t_hdr_event(); void set_event_type(const string &t); void set_id(const string &s); void add_event_param(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_privacy.cpp0000644000175000001440000000272011127714057015217 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "definitions.h" #include "hdr_privacy.h" using namespace std; t_hdr_privacy::t_hdr_privacy() : t_header("Privacy") {}; void t_hdr_privacy::add_privacy(const string &privacy) { populated = true; privacy_list.push_back(privacy); } bool t_hdr_privacy::contains_privacy(const string &privacy) const { return (find(privacy_list.begin(), privacy_list.end(), privacy) != privacy_list.end()); } string t_hdr_privacy::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = privacy_list.begin(); i != privacy_list.end(); i++) { if (i != privacy_list.begin()) s += ";"; s += *i; } return s; } twinkle-1.4.2/src/parser/hdr_refer_to.cpp0000644000175000001440000000322011127714057015343 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_refer_to.h" #include "definitions.h" #include "parse_ctrl.h" #include "util.h" t_hdr_refer_to::t_hdr_refer_to() : t_header("Refer-To", "r") {} void t_hdr_refer_to::set_display(const string &d) { populated = true; display = d; } void t_hdr_refer_to::set_uri(const string &u) { populated = true; uri.set_url(u); } void t_hdr_refer_to::set_uri(const t_url &u) { populated = true; uri = u; } void t_hdr_refer_to::set_params(const list &l) { populated = true; params = l; } void t_hdr_refer_to::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_refer_to::encode_value(void) const { string s; if (!populated) return s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/hdr_user_agent.cpp0000644000175000001440000000254211127714057015700 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_user_agent.h" #include "util.h" t_hdr_user_agent::t_hdr_user_agent() : t_header("User-Agent") {}; void t_hdr_user_agent::add_server(const t_server &s) { populated = true; ua_info.push_back(s); } string t_hdr_user_agent::get_ua_info(void) const { string s; for (list::const_iterator i = ua_info.begin(); i != ua_info.end(); i++ ) { if (i != ua_info.begin()) s += ' '; s += i->encode(); } return s; } string t_hdr_user_agent::encode_value(void) const { if (!populated) return ""; return get_ua_info(); } twinkle-1.4.2/src/parser/hdr_p_asserted_identity.h0000644000175000001440000000230211127714050017236 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3325 9.1 // P-Asserted-Identity header #ifndef _H_HDR_P_ASSERTED_IDENTITY #define _H_HDR_P_ASSERTED_IDENTITY #include #include "header.h" #include "identity.h" using namespace std; class t_hdr_p_asserted_identity : public t_header { public: list identity_list; t_hdr_p_asserted_identity(); void add_identity(const t_identity &identity); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_content_disp.cpp0000644000175000001440000000302711127714057016234 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_content_disp.h" t_hdr_content_disp::t_hdr_content_disp() : t_header("Content-Disposition") {}; void t_hdr_content_disp::set_type(const string &t) { populated = true; type = t; } void t_hdr_content_disp::set_filename(const string &name) { populated = true; filename = name; } void t_hdr_content_disp::add_param(const t_parameter &p) { populated = true; params.push_back(p); } void t_hdr_content_disp::set_params(const list &l) { populated = true; params = l; } string t_hdr_content_disp::encode_value(void) const { string s; if (!populated) return s; s = type; if (!filename.empty()) { s += ";filename=\""; s += filename; s += "\""; } s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/media_type.h0000644000175000001440000000433711127714050014471 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Media MIME type definition. */ #ifndef _MEDIA_TYPE_H #define _MEDIA_TYPE_H #include #include #include "parameter.h" using namespace std; /** Media MIME type definition. */ class t_media { public: string type; /**< main type */ string subtype; /**< subtype */ string charset; /**< Character set */ float q; /**< quality factor */ list media_param_list; /**< media paramters */ list accept_extension_list; /**< accept parameters */ /** Constructor */ t_media(); /** * Constructor. * Construct object with a specic type and subtype. * @param t [in] type * @param s [in] subtype */ t_media(const string &t, const string &s); /** * Constructor. * Construct a media object from a mime type name * @param mime_type [in] The mime type name, e.g. "text/plain" */ t_media(const string &mime_type); /** * Add a parameter list. * Method for parser to add the parsed parameter list l. * l should start with optional media parameters followed * by the q-paramter followed by accept parameters. * @param l [in] The parameter list. */ void add_params(const list &l); /** * Encode as string. * @return The encoded media type. */ string encode(void) const; /** * Get the glob for a file name containing this MIME type. * E.g. .txt for text/plain * @return The file name extension. */ string get_file_glob(void) const; }; #endif twinkle-1.4.2/src/parser/parameter.cpp0000644000175000001440000000376711127714057014701 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "parameter.h" #include "util.h" t_parameter::t_parameter() { type = VALUE; } t_parameter::t_parameter(const string &n) { type = NOVALUE; name = n; } t_parameter::t_parameter(const string &n, const string &v) { type = VALUE; name = n; value = v; } string t_parameter::encode(void) const { string s; s += name; if (type == VALUE) { s += '='; if (must_quote(value)) { s += '\"' + value + '\"'; } else { s += value; } } return s; } bool t_parameter::operator==(const t_parameter &rhs) { return (type == rhs.type && name == rhs.name); } t_parameter str2param(const string &s) { vector l = split_on_first(s, '='); if (l.size() == 1) { return t_parameter(s); } else { return t_parameter(trim(l[0]), trim(l[1])); } } string param_list2str(const list &l) { string s; for (list::const_iterator i = l.begin(); i != l.end(); i++) { s += ';'; s += i->encode(); } return s; } list str2param_list(const string &s) { list result; vector l = split(s, ';'); for (vector::const_iterator i = l.begin(); i != l.end(); i++) { t_parameter p = str2param(trim(*i)); result.push_back(p); } return result; } twinkle-1.4.2/src/parser/coding.h0000644000175000001440000000204411127714050013605 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Content coding type #ifndef _CODING_H #define _CODING_H #include using namespace std; class t_coding { public: string content_coding; float q; // quality factor; t_coding(); t_coding(const string &s); string encode(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_refer_to.h0000644000175000001440000000252211127714050015005 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3515 // Refer-To header #ifndef _H_HDR_REFER_TO #define _H_HDR_REFER_TO #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_refer_to : public t_header { public: string display; // display name t_url uri; list params; t_hdr_refer_to(); void set_display(const string &d); void set_uri(const string &u); void set_uri(const t_url &u); void set_params(const list &l); void add_param(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_max_forwards.cpp0000644000175000001440000000222411127714057016235 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_max_forwards.h" #include "util.h" t_hdr_max_forwards::t_hdr_max_forwards() : t_header("Max-Forwards") { max_forwards = 0; } void t_hdr_max_forwards::set_max_forwards(int m) { populated = true; max_forwards = m; } string t_hdr_max_forwards::encode_value(void) const { if (!populated) return ""; return int2str(max_forwards); } twinkle-1.4.2/src/parser/parser.h0000644000175000001440000001614611142401140013634 00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_NUM = 258, T_TOKEN = 259, T_QSTRING = 260, T_COMMENT = 261, T_LINE = 262, T_URI = 263, T_URI_WILDCARD = 264, T_DISPLAY = 265, T_LANG = 266, T_WORD = 267, T_WKDAY = 268, T_MONTH = 269, T_GMT = 270, T_SIP = 271, T_METHOD = 272, T_AUTH_DIGEST = 273, T_AUTH_OTHER = 274, T_IPV6ADDR = 275, T_PARAMVAL = 276, T_HDR_ACCEPT = 277, T_HDR_ACCEPT_ENCODING = 278, T_HDR_ACCEPT_LANGUAGE = 279, T_HDR_ALERT_INFO = 280, T_HDR_ALLOW = 281, T_HDR_ALLOW_EVENTS = 282, T_HDR_AUTHENTICATION_INFO = 283, T_HDR_AUTHORIZATION = 284, T_HDR_CALL_ID = 285, T_HDR_CALL_INFO = 286, T_HDR_CONTACT = 287, T_HDR_CONTENT_DISP = 288, T_HDR_CONTENT_ENCODING = 289, T_HDR_CONTENT_LANGUAGE = 290, T_HDR_CONTENT_LENGTH = 291, T_HDR_CONTENT_TYPE = 292, T_HDR_CSEQ = 293, T_HDR_DATE = 294, T_HDR_ERROR_INFO = 295, T_HDR_EVENT = 296, T_HDR_EXPIRES = 297, T_HDR_FROM = 298, T_HDR_IN_REPLY_TO = 299, T_HDR_MAX_FORWARDS = 300, T_HDR_MIN_EXPIRES = 301, T_HDR_MIME_VERSION = 302, T_HDR_ORGANIZATION = 303, T_HDR_P_ASSERTED_IDENTITY = 304, T_HDR_P_PREFERRED_IDENTITY = 305, T_HDR_PRIORITY = 306, T_HDR_PRIVACY = 307, T_HDR_PROXY_AUTHENTICATE = 308, T_HDR_PROXY_AUTHORIZATION = 309, T_HDR_PROXY_REQUIRE = 310, T_HDR_RACK = 311, T_HDR_RECORD_ROUTE = 312, T_HDR_SERVICE_ROUTE = 313, T_HDR_REFER_SUB = 314, T_HDR_REFER_TO = 315, T_HDR_REFERRED_BY = 316, T_HDR_REPLACES = 317, T_HDR_REPLY_TO = 318, T_HDR_REQUIRE = 319, T_HDR_REQUEST_DISPOSITION = 320, T_HDR_RETRY_AFTER = 321, T_HDR_ROUTE = 322, T_HDR_RSEQ = 323, T_HDR_SERVER = 324, T_HDR_SIP_ETAG = 325, T_HDR_SIP_IF_MATCH = 326, T_HDR_SUBJECT = 327, T_HDR_SUBSCRIPTION_STATE = 328, T_HDR_SUPPORTED = 329, T_HDR_TIMESTAMP = 330, T_HDR_TO = 331, T_HDR_UNSUPPORTED = 332, T_HDR_USER_AGENT = 333, T_HDR_VIA = 334, T_HDR_WARNING = 335, T_HDR_WWW_AUTHENTICATE = 336, T_HDR_UNKNOWN = 337, T_CRLF = 338, T_ERROR = 339, T_NULL = 340 }; #endif /* Tokens. */ #define T_NUM 258 #define T_TOKEN 259 #define T_QSTRING 260 #define T_COMMENT 261 #define T_LINE 262 #define T_URI 263 #define T_URI_WILDCARD 264 #define T_DISPLAY 265 #define T_LANG 266 #define T_WORD 267 #define T_WKDAY 268 #define T_MONTH 269 #define T_GMT 270 #define T_SIP 271 #define T_METHOD 272 #define T_AUTH_DIGEST 273 #define T_AUTH_OTHER 274 #define T_IPV6ADDR 275 #define T_PARAMVAL 276 #define T_HDR_ACCEPT 277 #define T_HDR_ACCEPT_ENCODING 278 #define T_HDR_ACCEPT_LANGUAGE 279 #define T_HDR_ALERT_INFO 280 #define T_HDR_ALLOW 281 #define T_HDR_ALLOW_EVENTS 282 #define T_HDR_AUTHENTICATION_INFO 283 #define T_HDR_AUTHORIZATION 284 #define T_HDR_CALL_ID 285 #define T_HDR_CALL_INFO 286 #define T_HDR_CONTACT 287 #define T_HDR_CONTENT_DISP 288 #define T_HDR_CONTENT_ENCODING 289 #define T_HDR_CONTENT_LANGUAGE 290 #define T_HDR_CONTENT_LENGTH 291 #define T_HDR_CONTENT_TYPE 292 #define T_HDR_CSEQ 293 #define T_HDR_DATE 294 #define T_HDR_ERROR_INFO 295 #define T_HDR_EVENT 296 #define T_HDR_EXPIRES 297 #define T_HDR_FROM 298 #define T_HDR_IN_REPLY_TO 299 #define T_HDR_MAX_FORWARDS 300 #define T_HDR_MIN_EXPIRES 301 #define T_HDR_MIME_VERSION 302 #define T_HDR_ORGANIZATION 303 #define T_HDR_P_ASSERTED_IDENTITY 304 #define T_HDR_P_PREFERRED_IDENTITY 305 #define T_HDR_PRIORITY 306 #define T_HDR_PRIVACY 307 #define T_HDR_PROXY_AUTHENTICATE 308 #define T_HDR_PROXY_AUTHORIZATION 309 #define T_HDR_PROXY_REQUIRE 310 #define T_HDR_RACK 311 #define T_HDR_RECORD_ROUTE 312 #define T_HDR_SERVICE_ROUTE 313 #define T_HDR_REFER_SUB 314 #define T_HDR_REFER_TO 315 #define T_HDR_REFERRED_BY 316 #define T_HDR_REPLACES 317 #define T_HDR_REPLY_TO 318 #define T_HDR_REQUIRE 319 #define T_HDR_REQUEST_DISPOSITION 320 #define T_HDR_RETRY_AFTER 321 #define T_HDR_ROUTE 322 #define T_HDR_RSEQ 323 #define T_HDR_SERVER 324 #define T_HDR_SIP_ETAG 325 #define T_HDR_SIP_IF_MATCH 326 #define T_HDR_SUBJECT 327 #define T_HDR_SUBSCRIPTION_STATE 328 #define T_HDR_SUPPORTED 329 #define T_HDR_TIMESTAMP 330 #define T_HDR_TO 331 #define T_HDR_UNSUPPORTED 332 #define T_HDR_USER_AGENT 333 #define T_HDR_VIA 334 #define T_HDR_WARNING 335 #define T_HDR_WWW_AUTHENTICATE 336 #define T_HDR_UNKNOWN 337 #define T_CRLF 338 #define T_ERROR 339 #define T_NULL 340 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 49 "parser.yxx" { int yyt_int; ulong yyt_ulong; float yyt_float; string *yyt_str; t_parameter *yyt_param; list *yyt_params; t_media *yyt_media; t_coding *yyt_coding; t_language *yyt_language; t_alert_param *yyt_alert_param; t_info_param *yyt_info_param; list *yyt_contacts; t_contact_param *yyt_contact; t_error_param *yyt_error_param; t_identity *yyt_from_addr; t_route *yyt_route; t_server *yyt_server; t_via *yyt_via; t_warning *yyt_warning; t_digest_response *yyt_dig_resp; t_credentials *yyt_credentials; t_digest_challenge *yyt_dig_chlg; t_challenge *yyt_challenge; } /* Line 1529 of yacc.c. */ #line 245 "parser.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; twinkle-1.4.2/src/parser/hdr_mime_version.cpp0000644000175000001440000000214111127714057016233 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_mime_version.h" t_hdr_mime_version::t_hdr_mime_version() : t_header("MIME-Version") {}; void t_hdr_mime_version::set_version(const string &v) { populated = true; version = v; } string t_hdr_mime_version::encode_value(void) const { if (!populated) return ""; return version; } twinkle-1.4.2/src/parser/hdr_unsupported.h0000644000175000001440000000226111127714050015570 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Unsupported header #ifndef _H_HDR_UNSUPPORTED #define _H_HDR_UNSUPPORTED #include #include #include "header.h" class t_hdr_unsupported : public t_header { public: list features; t_hdr_unsupported(); void add_feature(const string &f); void set_features(const list &_features); bool contains(const string &f) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_sip_etag.cpp0000644000175000001440000000205611127714057015337 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_sip_etag.h" t_hdr_sip_etag::t_hdr_sip_etag() : t_header("SIP-ETag") {}; void t_hdr_sip_etag::set_etag(const string &_etag) { populated = true; etag = _etag; } string t_hdr_sip_etag::encode_value(void) const { if (!populated) return ""; return etag; } twinkle-1.4.2/src/parser/hdr_alert_info.h0000644000175000001440000000256611127714050015332 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Alert-Info header #ifndef _HDR_ALERT_INFO_H #define _HDR_ALERT_INFO_H #include #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_alert_param { public: t_url uri; list parameter_list; void add_param(const t_parameter &p); string encode(void) const; }; class t_hdr_alert_info : public t_header { public: list alert_param_list; t_hdr_alert_info(); // Add a paramter to the list of alert parameters void add_param(const t_alert_param &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/parse_ctrl.cpp0000644000175000001440000000636311134633416015047 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "parse_ctrl.h" #include "protocol.h" #include "util.h" #include "audits/memman.h" // Interface to Bison extern int yyparse(void); // Interface to Flex struct yy_buffer_state; extern struct yy_buffer_state *yy_scan_string(const char *); extern void yy_delete_buffer(struct yy_buffer_state *); t_mutex t_parser::mtx_parser; bool t_parser::check_max_forwards = true; bool t_parser::compact_headers = false; bool t_parser::multi_values_as_list = true; int t_parser::comment_level = 0; list t_parser::parse_errors; string t_parser::unfold(const string &h) { string::size_type i; string s = h; while ((i = s.find("\r\n ")) != string::npos) { s.replace(i, 3, " "); } while ((i = s.find("\r\n\t")) != string::npos) { s.replace(i, 3, " "); } // This is only for easy testing of hand edited messages // in Linux where the end of line character is \n only. while ((i = s.find("\n ")) != string::npos) { s.replace(i, 2, " "); } while ((i = s.find("\n\t")) != string::npos) { s.replace(i, 2, " "); } return s; } t_parser::t_context t_parser::context = t_parser::X_INITIAL; t_sip_message *t_parser::msg = NULL; t_sip_message *t_parser::parse(const string &s, list &parse_errors_) { t_mutex_guard guard(mtx_parser); int ret; struct yy_buffer_state *b; msg = NULL; parse_errors.clear(); string x = unfold(s); b = yy_scan_string(x.c_str()); ret = yyparse(); yy_delete_buffer(b); if (ret != 0) { if (msg) { MEMMAN_DELETE(msg); delete msg; msg = NULL; } throw ret; } parse_errors_ = parse_errors; return msg; } t_sip_message *t_parser::parse_headers(const string &s, list &parse_errors_) { string msg("INVITE sip:fake@fake.invalid SIP/2.0"); msg += CRLF; list hdr_list = str2param_list(s); for (list::iterator i = hdr_list.begin(); i != hdr_list.end(); i++) { msg += unescape_hex(i->name); msg += ": "; msg += unescape_hex(i->value); msg += CRLF; } msg += CRLF; return parse(msg, parse_errors_); } void t_parser::enter_ctx_comment(void) { comment_level = 0; context = t_parser::X_COMMENT; } void t_parser::inc_comment_level(void) { comment_level++; } bool t_parser::dec_comment_level(void) { if (comment_level == 0) return false; comment_level--; return true; } void t_parser::add_header_error(const string &header_name) { string s = "Parse error in header: " + header_name; parse_errors.push_back(s); } t_syntax_error::t_syntax_error(const string &e) { error = e; } twinkle-1.4.2/src/parser/sip_body.cpp0000644000175000001440000001634611127714057014526 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sip_body.h" #include #include #include #include "log.h" #include "protocol.h" #include "sip_message.h" #include "util.h" #include "audits/memman.h" #include "audio/rtp_telephone_event.h" //////////////////////////////////// // class t_sip_body //////////////////////////////////// t_sip_body::t_sip_body() { invalid = false; } bool t_sip_body::local_ip_check(void) const { return true; } size_t t_sip_body::get_encoded_size(void) const { return encode().size(); } //////////////////////////////////// // class t_sip_xml_body //////////////////////////////////// void t_sip_body_xml::create_xml_doc(const string &xml_version, const string &charset) { clear_xml_doc(); // XML doc xml_doc = xmlNewDoc(BAD_CAST xml_version.c_str()); MEMMAN_NEW(xml_doc); xml_doc->encoding = xmlCharStrdup(charset.c_str()); } void t_sip_body_xml::clear_xml_doc(void) { if (xml_doc) { MEMMAN_DELETE(xml_doc); xmlFreeDoc(xml_doc); xml_doc = NULL; } } void t_sip_body_xml::copy_xml_doc(t_sip_body_xml *to_body) const { if (to_body->xml_doc) { to_body->clear_xml_doc(); } if (xml_doc) { to_body->xml_doc = xmlCopyDoc(xml_doc, 1); if (!to_body->xml_doc) { log_file->write_report("Failed to copy xml document.", "t_sip_body_xml::copy", LOG_NORMAL, LOG_CRITICAL); } else { MEMMAN_NEW(to_body->xml_doc); } } } t_sip_body_xml::t_sip_body_xml() : t_sip_body(), xml_doc(NULL) {} t_sip_body_xml::~t_sip_body_xml() { clear_xml_doc(); } string t_sip_body_xml::encode(void) const { if (!xml_doc) { t_sip_body_xml *self = const_cast(this); self->create_xml_doc(); } assert(xml_doc); xmlChar *buf; int buf_size; xmlDocDumpMemory(xml_doc, &buf, &buf_size); string result((char*)buf); xmlFree(buf); return result; } bool t_sip_body_xml::parse(const string &s) { assert(xml_doc == NULL); xml_doc = xmlReadMemory(s.c_str(), s.size(), "noname.xml", NULL, XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING); if (!xml_doc) { log_file->write_report("Failed to parse xml document.", "t_sip_body_xml::parse", LOG_NORMAL, LOG_WARNING); } else { MEMMAN_NEW(xml_doc); } return (xml_doc != NULL); } //////////////////////////////////// // class t_sip_body_opaque //////////////////////////////////// t_sip_body_opaque::t_sip_body_opaque() : t_sip_body() {} t_sip_body_opaque::t_sip_body_opaque(string s) : t_sip_body(), opaque(s) {} string t_sip_body_opaque::encode(void) const { return opaque; } t_sip_body *t_sip_body_opaque::copy(void) const { t_sip_body_opaque *sb = new t_sip_body_opaque(*this); MEMMAN_NEW(sb); return sb; } t_body_type t_sip_body_opaque::get_type(void) const { return BODY_OPAQUE; } t_media t_sip_body_opaque::get_media(void) const { return t_media("application", "octet-stream"); } size_t t_sip_body_opaque::get_encoded_size(void) const { return opaque.size(); } //////////////////////////////////// // class t_sip_body_sipfrag //////////////////////////////////// t_sip_body_sipfrag::t_sip_body_sipfrag(t_sip_message *m) : t_sip_body() { sipfrag = m->copy(); } t_sip_body_sipfrag::~t_sip_body_sipfrag() { MEMMAN_DELETE(sipfrag); delete sipfrag; } string t_sip_body_sipfrag::encode(void) const { return sipfrag->encode(false); } t_sip_body *t_sip_body_sipfrag::copy(void) const { t_sip_body_sipfrag *sb = new t_sip_body_sipfrag(sipfrag); MEMMAN_NEW(sb); return sb; } t_body_type t_sip_body_sipfrag::get_type(void) const { return BODY_SIPFRAG; } t_media t_sip_body_sipfrag::get_media(void) const { return t_media("message", "sipfrag"); } //////////////////////////////////// // class t_sip_body_dtmf_relay //////////////////////////////////// t_sip_body_dtmf_relay::t_sip_body_dtmf_relay() : t_sip_body() { signal = '0'; duration = 250; } t_sip_body_dtmf_relay::t_sip_body_dtmf_relay(char _signal, uint16 _duration) : signal(_signal), duration(_duration) {} string t_sip_body_dtmf_relay::encode(void) const { string s = "Signal="; s += signal; s += CRLF; s += "Duration="; s += int2str(duration); s += CRLF; return s; } t_sip_body *t_sip_body_dtmf_relay::copy(void) const { t_sip_body_dtmf_relay *sb = new t_sip_body_dtmf_relay(*this); MEMMAN_NEW(sb); return sb; } t_body_type t_sip_body_dtmf_relay::get_type(void) const { return BODY_DTMF_RELAY; } t_media t_sip_body_dtmf_relay::get_media(void) const { return t_media("application", "dtmf-relay"); } bool t_sip_body_dtmf_relay::parse(const string &s) { signal = 0; duration = 250; bool valid = false; vector lines = split_linebreak(s); for (vector::iterator i = lines.begin(); i != lines.end(); i++) { string line = trim(*i); if (line.empty()) continue; vector l = split_on_first(line, '='); if (l.size() != 2) continue; string parameter = tolower(trim(l[0])); string value = tolower(trim(l[1])); if (value.empty()) continue; if (parameter == "signal") { if (!VALID_DTMF_SYM(value[0])) return false; signal = value[0]; valid = true; } else if (parameter == "duration") { duration = atoi(value.c_str()); if (duration == 0) return false; } } return valid; } //////////////////////////////////// // class t_sip_body_plain_text //////////////////////////////////// t_sip_body_plain_text::t_sip_body_plain_text() : t_sip_body() {} t_sip_body_plain_text::t_sip_body_plain_text(const string &_text) : t_sip_body(), text(_text) {} string t_sip_body_plain_text::encode(void) const { return text; } t_sip_body *t_sip_body_plain_text::copy(void) const { t_sip_body *sb = new t_sip_body_plain_text(*this); MEMMAN_NEW(sb); return sb; } t_body_type t_sip_body_plain_text::get_type(void) const { return BODY_PLAIN_TEXT; } t_media t_sip_body_plain_text::get_media(void) const { return t_media("text", "plain"); } size_t t_sip_body_plain_text::get_encoded_size(void) const { return text.size(); } //////////////////////////////////// // class t_sip_body_html_text //////////////////////////////////// t_sip_body_html_text::t_sip_body_html_text(const string &_text) : t_sip_body(), text(_text) {} string t_sip_body_html_text::encode(void) const { return text; } t_sip_body *t_sip_body_html_text::copy(void) const { t_sip_body *sb = new t_sip_body_html_text(*this); MEMMAN_NEW(sb); return sb; } t_body_type t_sip_body_html_text::get_type(void) const { return BODY_HTML_TEXT; } t_media t_sip_body_html_text::get_media(void) const { return t_media("text", "html"); } size_t t_sip_body_html_text::get_encoded_size(void) const { return text.size(); } twinkle-1.4.2/src/parser/scanner.cxx0000644000175000001440000032215111142401202014337 00000000000000 #line 3 "scanner.cxx" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 33 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef unsigned int yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) #define yywrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ (yytext_ptr) -= (yy_more_len); \ yyleng = (size_t) (yy_cp - (yytext_ptr)); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 163 #define YY_END_OF_BUFFER 164 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_acclist[1388] = { 0, 164, 67, 163, 66, 67, 163, 65, 163, 67, 163, 62, 67, 163, 63, 67, 163, 61, 62, 67, 163, 61, 62, 67, 163, 40, 61, 62, 67, 163, 16, 61, 62, 67, 163, 44, 61, 62, 67, 163, 13, 61, 62, 67, 163, 22, 61, 62, 67, 163, 9, 61, 62, 67, 163, 53, 61, 62, 67, 163, 15, 61, 62, 67, 163, 11, 61, 62, 67, 163, 20, 61, 62, 67, 163, 61, 62, 67, 163, 39, 61, 62, 67, 163, 51, 61, 62, 67, 163, 55, 61, 62, 67, 163, 6, 61, 62, 67, 163, 58, 61, 62, 67, 163, 61, 62, 67, 163, 72, 74, 163, 16454, 73, 74, 163, 75, 163, 74, 163, 72, 74, 163,16454, 68, 74, 163,16454, 71, 72, 74, 163, 16454, 79, 81, 163, 80, 81, 163, 82, 163, 81, 163, 79, 81, 163, 76, 81, 163, 78, 79, 81, 163, 87, 163, 86, 163, 87, 163, 85, 87, 163, 83, 87, 163, 98, 163, 97, 98, 163, 100, 163, 98, 163, 96, 98, 163, 103, 163, 102, 103, 163, 105, 163, 103, 163, 101, 103, 163, 108, 163, 107, 108, 163, 110, 163, 108, 163, 106, 108, 163, 133, 163, 132, 133, 163, 135, 163, 133, 163, 131, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 133, 163, 136, 163, 138, 163, 139, 163, 94, 163, 93, 163, 94, 163, 91, 94, 163, 92, 94, 163, 88, 94, 163, 143, 163, 142, 143, 163, 145, 163, 143, 163, 141, 143, 163, 141, 143, 163, 149, 163, 148, 149, 163, 151, 163, 149, 163, 147, 149, 163, 147, 149, 163, 163, 95, 163, 154, 163, 153, 154, 163, 156, 163, 154, 163, 152, 154, 163, 160, 163, 159, 160, 163, 162, 163, 160, 163, 157, 160, 163, 158, 160, 163, 64, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 55, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 72,16454,16454, 8262, 72,16454, 69, 79, 79, 77, 86, 85, 84, 99, 96, 104, 101, 109, 106, 134, 131, 136, 137, 93, 91, 92, 90, 89, 144, 141, 141, 150, 147, 147, 155, 152, 161, 157, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 58, 61, 62, 61, 62, 61, 62, 96, 96, 121, 125, 129, 119, 115, 130, 118, 124, 123, 120, 122, 111, 128, 127, 116, 126, 117, 114, 112, 113, 140, 141, 147, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 17, 61, 62, 18, 61, 62, 61, 62, 61, 62, 61, 62, 22, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 35, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 47, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 96, 96, 147, 61, 62, 61, 62, 5, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 20, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 46, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 96, 96, 147, 1, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 48, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 96, 96, 146, 147, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 9, 61, 62, 61, 62, 11, 61, 62, 61, 62, 61, 62, 21, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 31, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 43, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 51, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 59, 61, 62, 61, 62, 96, 96, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 30, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 39, 61, 62, 61, 62, 41, 61, 62, 42, 61, 62, 61, 62, 61, 62, 61, 62, 49, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 96, 96, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 10, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 38, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 53, 61, 62, 54, 61, 62, 61, 62, 61, 62, 61, 62, 96, 61, 62, 61, 62, 4, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 19, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 57, 61, 62, 61, 62, 96, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 23, 61, 62, 61, 62, 61, 62, 25, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 40, 61, 62, 61, 62, 45, 61, 62, 61, 62, 61, 62, 61, 62, 56, 61, 62, 61, 62, 61, 62, 61, 62, 6, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 16, 61, 62, 24, 61, 62, 26, 61, 62, 27, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 36, 61, 62, 61, 62, 61, 62, 50, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 8, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 34, 61, 62, 61, 62, 37, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 15, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 2, 61, 62, 3, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 13, 61, 62, 14, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 60, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 32, 61, 62, 61, 62, 61, 62, 52, 61, 62, 7, 61, 62, 12, 61, 62, 28, 61, 62, 61, 62, 33, 61, 62, 44, 61, 62, 29, 61, 62 } ; static yyconst flex_int16_t yy_accept[715] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 7, 9, 11, 14, 17, 21, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 79, 84, 89, 94, 99, 104, 108, 112, 115, 117, 119, 123, 127, 132, 135, 138, 140, 142, 145, 148, 152, 154, 156, 158, 161, 164, 166, 169, 171, 173, 176, 178, 181, 183, 185, 188, 190, 193, 195, 197, 200, 202, 205, 207, 209, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 249, 252, 255, 257, 260, 262, 264, 267, 270, 272, 275, 277, 279, 282, 285, 286, 288, 290, 293, 295, 297, 300, 302, 305, 307, 309, 312, 315, 316, 317, 319, 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 372, 374, 376, 378, 380, 382, 384, 384, 385, 386, 386, 388, 389, 390, 390, 391, 392, 392, 393, 393, 394, 394, 395, 396, 396, 397, 398, 399, 400, 401, 402, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 404, 405, 405, 406, 406, 407, 408, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, 480, 482, 484, 486, 488, 490, 492, 495, 497, 499, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 523, 524, 526, 528, 530, 532, 534, 536, 539, 542, 544, 546, 548, 551, 553, 555, 557, 559, 561, 563, 565, 567, 569, 571, 574, 576, 578, 580, 582, 584, 586, 589, 591, 593, 595, 597, 599, 601, 603, 605, 607, 609, 610, 611, 612, 614, 616, 619, 621, 623, 625, 627, 629, 631, 634, 636, 638, 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, 660, 662, 664, 666, 668, 670, 673, 675, 677, 679, 681, 683, 685, 687, 689, 691, 693, 695, 697, 698, 699, 700, 703, 705, 707, 709, 711, 713, 715, 717, 719, 721, 723, 725, 727, 729, 731, 733, 735, 737, 739, 741, 743, 745, 747, 749, 751, 753, 755, 757, 760, 762, 764, 766, 768, 770, 772, 774, 776, 778, 780, 782, 783, 784, 786, 788, 790, 792, 794, 796, 799, 801, 804, 806, 808, 811, 813, 815, 817, 819, 821, 823, 825, 827, 830, 832, 834, 836, 838, 840, 842, 844, 846, 848, 851, 853, 855, 857, 859, 862, 864, 866, 868, 870, 872, 875, 877, 878, 879, 881, 883, 885, 887, 889, 891, 893, 895, 897, 899, 901, 903, 905, 907, 909, 911, 914, 916, 918, 920, 922, 925, 927, 930, 933, 935, 937, 939, 942, 944, 946, 948, 950, 952, 954, 956, 957, 958, 960, 962, 964, 966, 968, 970, 973, 975, 977, 979, 981, 983, 985, 987, 989, 991, 993, 995, 997, 999, 1001, 1003, 1006, 1008, 1010, 1012, 1014, 1016, 1018, 1021, 1024, 1026, 1028, 1030, 1031, 1033, 1035, 1038, 1040, 1042, 1044, 1046, 1048, 1050, 1052, 1054, 1057, 1059, 1061, 1063, 1065, 1067, 1069, 1071, 1073, 1075, 1077, 1079, 1081, 1083, 1085, 1087, 1089, 1091, 1094, 1096, 1097, 1099, 1101, 1103, 1105, 1107, 1109, 1111, 1113, 1115, 1117, 1120, 1122, 1124, 1127, 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1144, 1146, 1149, 1151, 1153, 1155, 1158, 1160, 1162, 1164, 1167, 1169, 1171, 1173, 1175, 1177, 1179, 1182, 1185, 1188, 1191, 1193, 1195, 1197, 1199, 1201, 1204, 1206, 1208, 1211, 1213, 1215, 1217, 1219, 1221, 1224, 1226, 1228, 1230, 1232, 1234, 1236, 1238, 1240, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1258, 1260, 1262, 1264, 1267, 1269, 1271, 1273, 1275, 1277, 1279, 1281, 1284, 1287, 1289, 1291, 1293, 1295, 1297, 1299, 1301, 1303, 1305, 1307, 1309, 1311, 1313, 1316, 1319, 1321, 1323, 1325, 1327, 1329, 1331, 1334, 1336, 1338, 1340, 1342, 1344, 1346, 1348, 1350, 1352, 1354, 1356, 1358, 1361, 1363, 1365, 1368, 1371, 1374, 1377, 1379, 1382, 1385, 1388, 1388 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 1, 1, 5, 1, 5, 7, 8, 9, 5, 1, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 15, 16, 1, 17, 12, 1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 18, 19, 18, 1, 5, 5, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 12, 1, 12, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[46] = { 0, 1, 2, 3, 3, 4, 5, 6, 6, 4, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17 } ; static yyconst flex_int16_t yy_base[761] = { 0, 0, 19, 64, 83, 102, 121, 128, 138, 157, 0, 202, 206, 209, 212, 224, 265, 6, 71, 216, 226, 307, 0, 352, 375, 1453, 1452, 397, 421, 446, 465, 1459, 1462, 1462, 1462, 1455, 0, 1462, 0, 220, 0, 198, 1437, 108, 1419, 1422, 0, 0, 49, 1417, 78, 241, 215, 79, 110, 1425, 228, 270, 1462, 1462, 1462, 484, 229, 503, 0, 1462, 1462, 1462, 522, 1462, 541, 277, 1462, 1449, 1462, 1445, 1462, 1462, 1462, 1447, 1439, 1462, 1462, 1462, 1445, 0, 1462, 1462, 1462, 1444, 1433, 1462, 1462, 1462, 1442, 1431, 115, 1419, 217, 1410, 106, 218, 1407, 1418, 253, 244, 1415, 0, 1462, 1435, 543, 1462, 1434, 1462, 1462, 86, 1462, 1462, 1462, 1433, 0, 1407, 1462, 1462, 1462, 1431, 0, 1405, 1462, 1462, 1462, 1462, 1462, 1429, 0, 1462, 1462, 1462, 1428, 0, 1462, 1462, 0, 0, 1408, 258, 1390, 1397, 1394, 1402, 1386, 1387, 1399, 1387, 1387, 1410, 1376, 120, 1392, 239, 258, 1395, 391, 1376, 1391, 1377, 1378, 351, 1380, 0, 1373, 1386, 1389, 1371, 1365, 378, 371, 395, 1462, 412, 0, 1462, 0, 1390, 0, 1462, 560, 1462, 1402, 1462, 1398, 1462, 1462, 0, 1393, 1462, 0, 1462, 1389, 1462, 1388, 1363, 1373, 1376, 1376, 1368, 1356, 1361, 123, 258, 1360, 1351, 1352, 1351, 1354, 1355, 1347, 1362, 1362, 0, 1462, 564, 1462, 1381, 1462, 1462, 293, 1462, 1462, 1462, 0, 1348, 1462, 0, 1356, 1462, 0, 1462, 0, 1357, 1343, 1345, 1351, 1346, 1337, 1339, 1350, 1339, 1339, 1343, 1338, 1332, 1358, 1343, 1356, 1345, 1326, 1326, 362, 1319, 1331, 1326, 1335, 1327, 1317, 1319, 1316, 1318, 1312, 1342, 336, 1316, 1326, 1309, 1311, 0, 1314, 1336, 289, 1335, 1334, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 0, 1319, 1307, 1302, 1298, 381, 1329, 337, 0, 0, 1301, 1298, 1299, 0, 1311, 1309, 1323, 1308, 1298, 1292, 1305, 1291, 1307, 1282, 0, 1288, 1287, 220, 378, 1279, 1298, 0, 409, 412, 1297, 1298, 1285, 1280, 1282, 1306, 1287, 1294, 1303, 1302, 1273, 1271, 1299, 1298, 1274, 1269, 1277, 1282, 1270, 1292, 0, 1277, 1265, 1265, 1257, 1254, 1268, 1271, 1269, 1265, 1270, 1281, 1267, 394, 1267, 1278, 1249, 1249, 1275, 0, 1247, 1261, 1243, 1256, 1258, 1242, 1241, 1238, 1241, 1255, 1241, 1233, 1262, 1261, 1231, 1259, 1240, 1243, 1227, 1237, 437, 1225, 1224, 1234, 1223, 1229, 1222, 1234, 1222, 1211, 1218, 1230, 1214, 1208, 418, 1241, 324, 1226, 1225, 1209, 1208, 1222, 1225, 0, 1220, 1223, 1232, 1200, 1210, 1198, 1216, 1201, 1208, 1207, 1193, 1218, 1217, 0, 433, 1193, 1184, 1196, 1178, 0, 1197, 0, 1211, 1184, 0, 1172, 1173, 1177, 1185, 1192, 1172, 1173, 1162, 0, 1165, 1180, 1166, 1162, 1167, 1177, 1161, 1161, 1184, 0, 1168, 1182, 1165, 1158, 0, 1154, 1164, 1152, 1146, 1158, 0, 1154, 1170, 1169, 1145, 1157, 1148, 1148, 1149, 1150, 1135, 546, 1143, 1157, 1146, 1124, 1124, 1121, 1135, 1121, 0, 1118, 1120, 1121, 1130, 0, 1140, 0, 0, 1126, 1109, 1110, 0, 1126, 1106, 1121, 1105, 1100, 1105, 1113, 1126, 1125, 1112, 1100, 1095, 1095, 1107, 1087, 0, 1097, 1091, 454, 1079, 1088, 1079, 1080, 1088, 1091, 1086, 1090, 1088, 1084, 1067, 1066, 0, 1084, 1076, 1079, 1068, 1062, 1072, 0, 0, 1072, 1056, 1061, 1082, 1057, 1064, 0, 1048, 1047, 1056, 1042, 1057, 1043, 1042, 1039, 0, 1037, 1047, 1034, 1026, 1028, 1051, 1037, 455, 1030, 1016, 1010, 1013, 1013, 1009, 1026, 1013, 1022, 0, 1002, 1030, 1016, 998, 999, 1008, 1001, 997, 997, 1001, 992, 957, 0, 934, 929, 0, 928, 932, 949, 925, 920, 919, 931, 0, 916, 0, 902, 888, 880, 0, 879, 877, 878, 0, 863, 863, 856, 865, 847, 841, 0, 0, 0, 0, 848, 826, 807, 809, 808, 0, 797, 806, 0, 819, 806, 794, 800, 790, 0, 784, 790, 797, 789, 791, 791, 785, 767, 0, 771, 0, 770, 564, 556, 557, 570, 550, 543, 549, 0, 541, 549, 543, 541, 530, 517, 515, 0, 0, 524, 506, 518, 515, 498, 502, 513, 493, 492, 508, 503, 493, 497, 0, 0, 488, 475, 474, 484, 480, 468, 0, 481, 463, 456, 466, 469, 449, 425, 432, 417, 406, 365, 368, 0, 352, 79, 0, 0, 0, 0, 52, 0, 0, 0, 1462, 585, 602, 619, 636, 653, 670, 687, 704, 721, 738, 755, 772, 789, 803, 817, 834, 851, 868, 885, 902, 919, 936, 947, 961, 978, 995, 1012, 459, 1026, 1036, 1049, 1065, 1081, 471, 1092, 1103, 1114, 1125, 1136, 1147, 1158, 1169, 1180, 1191, 1202, 1213, 1224 } ; static yyconst flex_int16_t yy_def[761] = { 0, 714, 713, 715, 715, 716, 716, 717, 717, 713, 9, 718, 718, 719, 719, 720, 720, 721, 721, 722, 722, 713, 21, 723, 723, 724, 724, 725, 725, 726, 726, 713, 713, 713, 713, 713, 727, 713, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 729, 713, 713, 713, 730, 731, 730, 732, 713, 713, 713, 733, 713, 733, 734, 713, 735, 713, 713, 713, 713, 713, 713, 736, 713, 713, 713, 713, 737, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 738, 713, 713, 739, 713, 740, 713, 713, 713, 713, 713, 713, 713, 741, 741, 713, 713, 713, 713, 742, 742, 713, 713, 713, 713, 713, 713, 743, 713, 713, 713, 713, 744, 713, 713, 727, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 729, 713, 731, 713, 745, 63, 713, 732, 746, 70, 713, 734, 713, 735, 713, 713, 713, 713, 747, 748, 713, 737, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 738, 713, 739, 713, 740, 713, 713, 713, 713, 713, 713, 741, 741, 713, 742, 742, 713, 743, 713, 744, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 745, 749, 750, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 741, 742, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 751, 752, 742, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 753, 754, 742, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 755, 756, 742, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 757, 758, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 759, 713, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 760, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 713, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 0, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713 } ; static yyconst flex_int16_t yy_nxt[1508] = { 0, 32, 33, 34, 35, 713, 37, 32, 32, 108, 109, 713, 32, 713, 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 38, 37, 32, 32, 38, 38, 38, 32, 38, 32, 32, 32, 32, 32, 32, 39, 40, 41, 42, 43, 44, 38, 38, 45, 38, 46, 47, 48, 38, 49, 50, 38, 51, 52, 53, 54, 55, 56, 38, 38, 38, 57, 58, 59, 60, 156, 62, 57, 57, 63, 108, 109, 57, 157, 57, 57, 60, 60, 57, 57, 57, 58, 59, 60, 159, 62, 57, 57, 63, 227, 228, 57, 712, 57, 57, 60, 60, 57, 57, 64, 65, 66, 67, 168, 69, 64, 64, 70, 711, 169, 64, 160, 64, 67, 67, 67, 64, 64, 64, 65, 66, 67, 207, 69, 64, 64, 70, 72, 73, 64, 74, 64, 67, 67, 67, 64, 64, 72, 73, 170, 74, 151, 208, 75, 171, 152, 201, 153, 253, 254, 288, 202, 289, 75, 76, 77, 78, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 82, 83, 84, 81, 82, 83, 84, 87, 88, 89, 87, 88, 89, 81, 147, 111, 112, 81, 90, 113, 114, 90, 92, 93, 94, 111, 112, 176, 148, 113, 114, 115, 149, 95, 209, 165, 369, 204, 144, 166, 96, 115, 178, 97, 173, 98, 99, 145, 210, 100, 205, 167, 101, 102, 103, 256, 146, 161, 104, 105, 370, 162, 106, 92, 93, 94, 174, 216, 176, 213, 257, 163, 177, 214, 95, 164, 187, 188, 240, 189, 217, 96, 258, 178, 97, 241, 98, 99, 259, 215, 100, 290, 190, 101, 102, 103, 227, 228, 291, 104, 105, 181, 713, 106, 116, 117, 118, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, 122, 123, 124, 125, 352, 122, 122, 122, 353, 456, 457, 122, 335, 122, 122, 122, 122, 122, 122, 270, 176, 336, 127, 122, 123, 124, 125, 176, 122, 122, 122, 177, 710, 271, 122, 178, 122, 122, 122, 122, 122, 122, 178, 322, 176, 127, 131, 132, 133, 371, 323, 411, 349, 372, 709, 134, 708, 134, 134, 178, 261, 179, 350, 262, 134, 134, 134, 134, 134, 134, 131, 132, 133, 263, 264, 181, 178, 265, 412, 134, 375, 134, 134, 377, 376, 453, 707, 378, 134, 134, 134, 134, 134, 134, 135, 136, 137, 138, 706, 140, 135, 135, 454, 705, 477, 135, 704, 438, 135, 135, 135, 478, 135, 135, 136, 137, 138, 439, 140, 135, 135, 558, 230, 230, 135, 559, 599, 135, 135, 135, 703, 135, 175, 179, 279, 279, 600, 177, 175, 175, 702, 701, 700, 175, 699, 175, 175, 181, 178, 175, 175, 175, 179, 698, 697, 696, 177, 175, 175, 695, 694, 693, 175, 692, 175, 175, 181, 178, 175, 175, 182, 183, 691, 690, 689, 688, 182, 182, 687, 686, 685, 182, 684, 182, 683, 185, 682, 182, 182, 182, 183, 681, 680, 222, 223, 182, 182, 224, 225, 679, 182, 678, 182, 677, 185, 676, 182, 182, 675, 226, 187, 188, 674, 189, 222, 223, 522, 523, 224, 225, 673, 672, 671, 670, 524, 669, 190, 668, 667, 666, 226, 665, 525, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 142, 664, 663, 142, 142, 662, 661, 660, 659, 658, 657, 656, 142, 142, 143, 655, 654, 143, 143, 653, 652, 651, 650, 649, 648, 647, 143, 143, 175, 175, 646, 175, 175, 175, 175, 175, 175, 175, 175, 645, 175, 175, 175, 175, 175, 180, 180, 644, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 177, 177, 643, 177, 177, 177, 177, 177, 177, 177, 177, 642, 177, 177, 177, 177, 177, 182, 641, 640, 182, 639, 182, 182, 182, 182, 182, 638, 637, 636, 182, 182, 182, 182, 184, 184, 635, 184, 634, 184, 184, 184, 184, 184, 633, 184, 632, 184, 184, 184, 184, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 188, 188, 188, 188, 631, 188, 188, 188, 188, 188, 188, 188, 188, 188, 630, 188, 188, 194, 629, 628, 627, 626, 625, 624, 623, 622, 194, 194, 196, 196, 196, 196, 196, 196, 196, 621, 196, 196, 196, 196, 196, 196, 219, 219, 620, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 223, 223, 223, 223, 223, 619, 223, 223, 223, 223, 223, 223, 223, 223, 618, 223, 223, 233, 617, 616, 233, 233, 615, 614, 613, 612, 611, 193, 610, 233, 233, 236, 609, 236, 608, 607, 606, 605, 604, 236, 238, 603, 602, 238, 238, 601, 238, 598, 597, 596, 238, 595, 238, 238, 278, 594, 278, 593, 592, 278, 278, 591, 590, 589, 278, 278, 588, 587, 278, 278, 183, 586, 183, 585, 584, 183, 183, 583, 582, 193, 183, 580, 579, 578, 183, 183, 280, 577, 576, 575, 574, 573, 572, 571, 570, 280, 280, 343, 569, 568, 567, 566, 565, 564, 563, 562, 343, 343, 344, 561, 560, 557, 556, 555, 554, 553, 552, 344, 344, 387, 551, 550, 193, 193, 548, 547, 546, 545, 387, 387, 388, 544, 543, 542, 541, 540, 539, 538, 537, 388, 388, 430, 536, 535, 534, 533, 532, 531, 530, 529, 430, 430, 431, 528, 527, 526, 521, 520, 519, 518, 517, 431, 431, 475, 516, 515, 193, 193, 512, 511, 510, 509, 475, 475, 476, 508, 507, 506, 505, 504, 503, 502, 501, 476, 476, 513, 500, 499, 498, 497, 496, 495, 494, 493, 513, 513, 514, 492, 491, 490, 489, 488, 487, 486, 485, 514, 514, 549, 484, 483, 482, 481, 480, 479, 193, 193, 549, 549, 581, 474, 473, 472, 471, 470, 469, 468, 467, 581, 581, 466, 465, 464, 463, 462, 461, 460, 459, 458, 455, 452, 451, 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440, 437, 436, 435, 434, 433, 432, 193, 193, 429, 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, 193, 193, 386, 385, 384, 383, 382, 381, 380, 379, 374, 373, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, 351, 348, 347, 346, 345, 193, 193, 342, 341, 340, 339, 338, 337, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 321, 320, 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 222, 300, 299, 298, 297, 296, 295, 294, 293, 292, 287, 286, 285, 284, 283, 282, 281, 200, 198, 193, 191, 187, 185, 277, 276, 275, 274, 273, 272, 269, 268, 267, 266, 260, 255, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 239, 237, 235, 234, 232, 231, 229, 222, 220, 218, 212, 211, 206, 203, 200, 199, 198, 197, 195, 193, 192, 191, 187, 172, 158, 155, 154, 150, 141, 713, 129, 129, 31, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713 } ; static yyconst flex_int16_t yy_chk[1508] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 17, 17, 0, 1, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 48, 3, 3, 3, 3, 18, 18, 3, 48, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 50, 4, 4, 4, 4, 115, 115, 4, 709, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 53, 5, 5, 5, 5, 704, 53, 5, 50, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 100, 6, 6, 6, 6, 7, 7, 6, 7, 6, 6, 6, 6, 6, 6, 8, 8, 54, 8, 43, 100, 7, 54, 43, 96, 43, 157, 157, 208, 96, 208, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 11, 41, 19, 19, 12, 13, 19, 19, 14, 15, 15, 15, 20, 20, 62, 41, 20, 20, 19, 41, 15, 101, 52, 328, 98, 39, 52, 15, 20, 62, 15, 56, 15, 15, 39, 101, 15, 98, 52, 15, 15, 15, 159, 39, 51, 15, 15, 328, 51, 15, 16, 16, 16, 56, 105, 57, 104, 159, 51, 57, 104, 16, 51, 71, 71, 145, 71, 105, 16, 160, 57, 16, 145, 16, 16, 160, 104, 16, 209, 71, 16, 16, 16, 226, 226, 209, 16, 16, 278, 278, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 308, 23, 23, 23, 308, 411, 411, 23, 270, 23, 23, 23, 23, 23, 23, 167, 176, 270, 23, 24, 24, 24, 24, 175, 24, 24, 24, 175, 703, 167, 24, 176, 24, 24, 24, 24, 24, 24, 175, 258, 177, 24, 27, 27, 27, 329, 258, 368, 306, 329, 701, 27, 700, 27, 27, 177, 162, 179, 306, 162, 27, 27, 27, 27, 27, 27, 28, 28, 28, 162, 162, 179, 179, 162, 368, 28, 333, 28, 28, 334, 333, 409, 699, 334, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 698, 29, 29, 29, 409, 697, 433, 29, 696, 395, 29, 29, 29, 433, 29, 30, 30, 30, 30, 395, 30, 30, 30, 524, 741, 741, 30, 524, 569, 30, 30, 30, 695, 30, 61, 61, 747, 747, 569, 61, 61, 61, 694, 693, 692, 61, 691, 61, 61, 61, 61, 61, 61, 63, 63, 690, 688, 687, 63, 63, 63, 686, 685, 684, 63, 683, 63, 63, 63, 63, 63, 63, 68, 68, 680, 679, 678, 677, 68, 68, 676, 675, 674, 68, 673, 68, 672, 68, 671, 68, 68, 70, 70, 670, 669, 110, 110, 70, 70, 110, 110, 668, 70, 665, 70, 664, 70, 663, 70, 70, 662, 110, 186, 186, 661, 186, 221, 221, 484, 484, 221, 221, 660, 659, 657, 656, 484, 655, 186, 654, 653, 652, 221, 651, 484, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 727, 650, 648, 727, 727, 646, 645, 644, 643, 642, 641, 640, 727, 727, 728, 639, 637, 728, 728, 636, 635, 634, 633, 631, 630, 628, 728, 728, 729, 729, 627, 729, 729, 729, 729, 729, 729, 729, 729, 626, 729, 729, 729, 729, 729, 730, 730, 625, 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, 731, 731, 624, 731, 731, 731, 731, 731, 731, 731, 731, 619, 731, 731, 731, 731, 731, 732, 618, 617, 732, 616, 732, 732, 732, 732, 732, 615, 614, 612, 732, 732, 732, 732, 733, 733, 611, 733, 610, 733, 733, 733, 733, 733, 608, 733, 607, 733, 733, 733, 733, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 735, 735, 735, 735, 606, 735, 735, 735, 735, 735, 735, 735, 735, 735, 604, 735, 735, 736, 602, 601, 600, 599, 598, 597, 596, 594, 736, 736, 737, 737, 737, 737, 737, 737, 737, 593, 737, 737, 737, 737, 737, 737, 738, 738, 591, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 740, 740, 740, 740, 740, 590, 740, 740, 740, 740, 740, 740, 740, 740, 589, 740, 740, 742, 588, 587, 742, 742, 586, 585, 584, 583, 582, 581, 580, 742, 742, 743, 578, 743, 577, 576, 575, 574, 573, 743, 744, 572, 571, 744, 744, 570, 744, 568, 567, 566, 744, 565, 744, 744, 745, 564, 745, 563, 562, 745, 745, 560, 559, 558, 745, 745, 557, 556, 745, 745, 746, 555, 746, 554, 553, 746, 746, 551, 550, 549, 746, 548, 547, 546, 746, 746, 748, 543, 542, 541, 540, 539, 538, 536, 535, 748, 748, 749, 534, 533, 532, 531, 530, 529, 528, 527, 749, 749, 750, 526, 525, 523, 522, 520, 519, 518, 517, 750, 750, 751, 516, 515, 514, 513, 512, 511, 510, 509, 751, 751, 752, 508, 507, 506, 504, 503, 502, 499, 497, 752, 752, 753, 496, 495, 494, 492, 491, 490, 489, 488, 753, 753, 754, 487, 486, 485, 483, 482, 481, 480, 479, 754, 754, 755, 478, 477, 476, 475, 474, 472, 471, 470, 755, 755, 756, 469, 468, 466, 465, 464, 463, 461, 460, 756, 756, 757, 459, 458, 457, 456, 455, 454, 453, 451, 757, 757, 758, 450, 449, 448, 447, 446, 445, 444, 442, 758, 758, 759, 441, 439, 437, 436, 435, 434, 431, 430, 759, 759, 760, 429, 428, 427, 426, 425, 424, 423, 422, 760, 760, 421, 420, 419, 417, 416, 415, 414, 413, 412, 410, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, 396, 394, 393, 392, 391, 390, 389, 388, 387, 386, 385, 384, 383, 382, 381, 380, 379, 378, 377, 376, 375, 373, 372, 371, 370, 369, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, 336, 335, 331, 330, 327, 326, 324, 323, 322, 321, 320, 319, 318, 317, 316, 315, 313, 312, 311, 307, 305, 304, 303, 302, 280, 279, 277, 276, 274, 273, 272, 271, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 234, 231, 223, 218, 217, 216, 215, 214, 213, 212, 211, 210, 207, 206, 205, 204, 203, 202, 201, 200, 198, 194, 190, 188, 183, 174, 173, 172, 171, 170, 168, 166, 165, 164, 163, 161, 158, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 144, 138, 133, 127, 125, 121, 119, 112, 109, 106, 103, 102, 99, 97, 95, 94, 90, 89, 84, 80, 79, 75, 73, 55, 49, 45, 44, 42, 35, 31, 26, 25, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713 } ; extern int yy_flex_debug; int yy_flex_debug = 0; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; static char *yy_full_match; static int yy_lp; static int yy_looking_for_trail_begin = 0; static int yy_full_lp; static int *yy_full_state; #define YY_TRAILING_MASK 0x2000 #define YY_TRAILING_HEAD_MASK 0x4000 #define REJECT \ { \ *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \ yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ (yy_lp) = yy_full_lp; /* restore orig. accepting pos. */ \ (yy_state_ptr) = yy_full_state; /* restore orig. state */ \ yy_current_state = *(yy_state_ptr); /* restore curr. state */ \ ++(yy_lp); \ goto find_rule; \ } static int yy_more_flag = 0; static int yy_more_len = 0; #define yymore() ((yy_more_flag) = 1) #define YY_MORE_ADJ (yy_more_len) #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "scanner.lxx" /* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #line 20 "scanner.lxx" #include #include #include #include #include "parse_ctrl.h" #include "parser.h" #include "util.h" #include "audits/memman.h" using namespace std; #line 1240 "scanner.cxx" #define INITIAL 0 #define C_URI 1 #define C_URI_SPECIAL 2 #define C_QSTRING 3 #define C_LANG 4 #define C_WORD 5 #define C_NUM 6 #define C_DATE 7 #define C_LINE 8 #define C_COMMENT 9 #define C_NEW 10 #define C_AUTH_SCHEME 11 #define C_RPAREN 12 #define C_IPV6ADDR 13 #define C_PARAMVAL 14 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = NULL; static void yy_push_state (int new_state ); static void yy_pop_state (void ); static int yy_top_state (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 58 "scanner.lxx" switch (t_parser::context) { case t_parser::X_URI: BEGIN(C_URI); break; case t_parser::X_URI_SPECIAL: BEGIN(C_URI_SPECIAL); break; case t_parser::X_LANG: BEGIN(C_LANG); break; case t_parser::X_WORD: BEGIN(C_WORD); break; case t_parser::X_NUM: BEGIN(C_NUM); break; case t_parser::X_DATE: BEGIN(C_DATE); break; case t_parser::X_LINE: BEGIN(C_LINE); break; case t_parser::X_COMMENT: BEGIN(C_COMMENT); break; case t_parser::X_NEW: BEGIN(C_NEW); break; case t_parser::X_AUTH_SCHEME: BEGIN(C_AUTH_SCHEME); break; case t_parser::X_IPV6ADDR: BEGIN(C_IPV6ADDR); break; case t_parser::X_PARAMVAL: BEGIN(C_PARAMVAL); break; default: BEGIN(INITIAL); } /* Headers */ #line 1439 "scanner.cxx" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif /* Create the reject buffer large enough to save one state per allowed character. */ if ( ! (yy_state_buf) ) (yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE ); if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { (yy_more_len) = 0; if ( (yy_more_flag) ) { (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); (yy_more_flag) = 0; } yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 714 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *(yy_state_ptr)++ = yy_current_state; ++yy_cp; } while ( yy_base[yy_current_state] != 1462 ); yy_find_action: yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; find_rule: /* we branch to this label when backing up */ for ( ; ; ) /* until we find what rule we matched */ { if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) { yy_act = yy_acclist[(yy_lp)]; if ( yy_act & YY_TRAILING_HEAD_MASK || yy_looking_for_trail_begin ) { if ( yy_act == yy_looking_for_trail_begin ) { yy_looking_for_trail_begin = 0; yy_act &= ~YY_TRAILING_HEAD_MASK; break; } } else if ( yy_act & YY_TRAILING_MASK ) { yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK; yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK; } else { (yy_full_match) = yy_cp; yy_full_state = (yy_state_ptr); yy_full_lp = (yy_lp); break; } ++(yy_lp); goto find_rule; } --yy_cp; yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 1: YY_RULE_SETUP #line 76 "scanner.lxx" { return T_HDR_ACCEPT; } YY_BREAK case 2: YY_RULE_SETUP #line 77 "scanner.lxx" { return T_HDR_ACCEPT_ENCODING; } YY_BREAK case 3: YY_RULE_SETUP #line 78 "scanner.lxx" { return T_HDR_ACCEPT_LANGUAGE; } YY_BREAK case 4: YY_RULE_SETUP #line 79 "scanner.lxx" { return T_HDR_ALERT_INFO; } YY_BREAK case 5: YY_RULE_SETUP #line 80 "scanner.lxx" { return T_HDR_ALLOW; } YY_BREAK case 6: YY_RULE_SETUP #line 81 "scanner.lxx" { return T_HDR_ALLOW_EVENTS; } YY_BREAK case 7: YY_RULE_SETUP #line 82 "scanner.lxx" { return T_HDR_AUTHENTICATION_INFO; } YY_BREAK case 8: YY_RULE_SETUP #line 83 "scanner.lxx" { return T_HDR_AUTHORIZATION; } YY_BREAK case 9: YY_RULE_SETUP #line 84 "scanner.lxx" { return T_HDR_CALL_ID; } YY_BREAK case 10: YY_RULE_SETUP #line 85 "scanner.lxx" { return T_HDR_CALL_INFO; } YY_BREAK case 11: YY_RULE_SETUP #line 86 "scanner.lxx" { return T_HDR_CONTACT; } YY_BREAK case 12: YY_RULE_SETUP #line 87 "scanner.lxx" { return T_HDR_CONTENT_DISP; } YY_BREAK case 13: YY_RULE_SETUP #line 88 "scanner.lxx" { return T_HDR_CONTENT_ENCODING; } YY_BREAK case 14: YY_RULE_SETUP #line 89 "scanner.lxx" { return T_HDR_CONTENT_LANGUAGE; } YY_BREAK case 15: YY_RULE_SETUP #line 90 "scanner.lxx" { return T_HDR_CONTENT_LENGTH; } YY_BREAK case 16: YY_RULE_SETUP #line 91 "scanner.lxx" { return T_HDR_CONTENT_TYPE; } YY_BREAK case 17: YY_RULE_SETUP #line 92 "scanner.lxx" { return T_HDR_CSEQ; } YY_BREAK case 18: YY_RULE_SETUP #line 93 "scanner.lxx" { return T_HDR_DATE; } YY_BREAK case 19: YY_RULE_SETUP #line 94 "scanner.lxx" { return T_HDR_ERROR_INFO; } YY_BREAK case 20: YY_RULE_SETUP #line 95 "scanner.lxx" { return T_HDR_EVENT; } YY_BREAK case 21: YY_RULE_SETUP #line 96 "scanner.lxx" { return T_HDR_EXPIRES; } YY_BREAK case 22: YY_RULE_SETUP #line 97 "scanner.lxx" { return T_HDR_FROM; } YY_BREAK case 23: YY_RULE_SETUP #line 98 "scanner.lxx" { return T_HDR_IN_REPLY_TO; } YY_BREAK case 24: YY_RULE_SETUP #line 99 "scanner.lxx" { return T_HDR_MAX_FORWARDS; } YY_BREAK case 25: YY_RULE_SETUP #line 100 "scanner.lxx" { return T_HDR_MIN_EXPIRES; } YY_BREAK case 26: YY_RULE_SETUP #line 101 "scanner.lxx" { return T_HDR_MIME_VERSION; } YY_BREAK case 27: YY_RULE_SETUP #line 102 "scanner.lxx" { return T_HDR_ORGANIZATION; } YY_BREAK case 28: YY_RULE_SETUP #line 103 "scanner.lxx" { return T_HDR_P_ASSERTED_IDENTITY; } YY_BREAK case 29: YY_RULE_SETUP #line 104 "scanner.lxx" { return T_HDR_P_PREFERRED_IDENTITY; } YY_BREAK case 30: YY_RULE_SETUP #line 105 "scanner.lxx" { return T_HDR_PRIORITY; } YY_BREAK case 31: YY_RULE_SETUP #line 106 "scanner.lxx" { return T_HDR_PRIVACY; } YY_BREAK case 32: YY_RULE_SETUP #line 107 "scanner.lxx" { return T_HDR_PROXY_AUTHENTICATE; } YY_BREAK case 33: YY_RULE_SETUP #line 108 "scanner.lxx" { return T_HDR_PROXY_AUTHORIZATION; } YY_BREAK case 34: YY_RULE_SETUP #line 109 "scanner.lxx" { return T_HDR_PROXY_REQUIRE; } YY_BREAK case 35: YY_RULE_SETUP #line 110 "scanner.lxx" { return T_HDR_RACK; } YY_BREAK case 36: YY_RULE_SETUP #line 111 "scanner.lxx" { return T_HDR_RECORD_ROUTE; } YY_BREAK case 37: YY_RULE_SETUP #line 112 "scanner.lxx" { return T_HDR_SERVICE_ROUTE; } YY_BREAK case 38: YY_RULE_SETUP #line 113 "scanner.lxx" { return T_HDR_REFER_SUB; } YY_BREAK case 39: YY_RULE_SETUP #line 114 "scanner.lxx" { return T_HDR_REFER_TO; } YY_BREAK case 40: YY_RULE_SETUP #line 115 "scanner.lxx" { return T_HDR_REFERRED_BY; } YY_BREAK case 41: YY_RULE_SETUP #line 116 "scanner.lxx" { return T_HDR_REPLACES; } YY_BREAK case 42: YY_RULE_SETUP #line 117 "scanner.lxx" { return T_HDR_REPLY_TO; } YY_BREAK case 43: YY_RULE_SETUP #line 118 "scanner.lxx" { return T_HDR_REQUIRE; } YY_BREAK case 44: YY_RULE_SETUP #line 119 "scanner.lxx" {return T_HDR_REQUEST_DISPOSITION; } YY_BREAK case 45: YY_RULE_SETUP #line 120 "scanner.lxx" { return T_HDR_RETRY_AFTER; } YY_BREAK case 46: YY_RULE_SETUP #line 121 "scanner.lxx" { return T_HDR_ROUTE; } YY_BREAK case 47: YY_RULE_SETUP #line 122 "scanner.lxx" { return T_HDR_RSEQ; } YY_BREAK case 48: YY_RULE_SETUP #line 123 "scanner.lxx" { return T_HDR_SERVER; } YY_BREAK case 49: YY_RULE_SETUP #line 124 "scanner.lxx" { return T_HDR_SIP_ETAG; } YY_BREAK case 50: YY_RULE_SETUP #line 125 "scanner.lxx" { return T_HDR_SIP_IF_MATCH; } YY_BREAK case 51: YY_RULE_SETUP #line 126 "scanner.lxx" { return T_HDR_SUBJECT; } YY_BREAK case 52: YY_RULE_SETUP #line 127 "scanner.lxx" { return T_HDR_SUBSCRIPTION_STATE; } YY_BREAK case 53: YY_RULE_SETUP #line 128 "scanner.lxx" { return T_HDR_SUPPORTED; } YY_BREAK case 54: YY_RULE_SETUP #line 129 "scanner.lxx" { return T_HDR_TIMESTAMP; } YY_BREAK case 55: YY_RULE_SETUP #line 130 "scanner.lxx" { return T_HDR_TO; } YY_BREAK case 56: YY_RULE_SETUP #line 131 "scanner.lxx" { return T_HDR_UNSUPPORTED; } YY_BREAK case 57: YY_RULE_SETUP #line 132 "scanner.lxx" { return T_HDR_USER_AGENT; } YY_BREAK case 58: YY_RULE_SETUP #line 133 "scanner.lxx" { return T_HDR_VIA; } YY_BREAK case 59: YY_RULE_SETUP #line 134 "scanner.lxx" { return T_HDR_WARNING; } YY_BREAK case 60: YY_RULE_SETUP #line 135 "scanner.lxx" { return T_HDR_WWW_AUTHENTICATE; } YY_BREAK case 61: YY_RULE_SETUP #line 136 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_HDR_UNKNOWN; } YY_BREAK /* Token as define in RFC 3261 */ case 62: YY_RULE_SETUP #line 141 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_TOKEN; } YY_BREAK /* Switch to quoted string context */ case 63: YY_RULE_SETUP #line 146 "scanner.lxx" { yy_push_state(C_QSTRING); } YY_BREAK /* End of line */ case 64: /* rule 64 can match eol */ YY_RULE_SETUP #line 149 "scanner.lxx" { return T_CRLF; } YY_BREAK case 65: /* rule 65 can match eol */ YY_RULE_SETUP #line 150 "scanner.lxx" { return T_CRLF; } YY_BREAK case 66: YY_RULE_SETUP #line 152 "scanner.lxx" /* Skip white space */ YY_BREAK /* Single character token */ case 67: YY_RULE_SETUP #line 155 "scanner.lxx" { return yytext[0]; } YY_BREAK /* URI. This context scans a URI including parameters. The syntax of a URI will be checked outside the scanner */ case 68: YY_RULE_SETUP #line 161 "scanner.lxx" { yy_push_state(C_QSTRING); } YY_BREAK case 69: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 162 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_DISPLAY; } YY_BREAK case 70: YY_RULE_SETUP #line 166 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_URI; } YY_BREAK case 71: YY_RULE_SETUP #line 170 "scanner.lxx" { return T_URI_WILDCARD; } YY_BREAK case 72: YY_RULE_SETUP #line 171 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_URI; } YY_BREAK case 73: YY_RULE_SETUP #line 175 "scanner.lxx" /* Skip white space */ YY_BREAK case 74: YY_RULE_SETUP #line 176 "scanner.lxx" { return yytext[0]; } YY_BREAK case 75: /* rule 75 can match eol */ YY_RULE_SETUP #line 177 "scanner.lxx" { return T_ERROR; } YY_BREAK /* URI special case. In several headers (eg. From, To, Contact, Reply-To) the URI can be enclosed by < and > If it is enclosed then parameters belong to the URI, if it is not enclosed then parameters belong to the header. Parameters are seperated by a semi-colon. For the URI special case, parameters belong to the header. If the parser receives a < from the scanner, then the parser will switch to the normal URI case. The syntax of a URI will be checked outside the scanner */ case 76: YY_RULE_SETUP #line 190 "scanner.lxx" { yy_push_state(C_QSTRING); } YY_BREAK case 77: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 191 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_DISPLAY; } YY_BREAK case 78: YY_RULE_SETUP #line 195 "scanner.lxx" { return T_URI_WILDCARD; } YY_BREAK case 79: YY_RULE_SETUP #line 196 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_URI; } YY_BREAK case 80: YY_RULE_SETUP #line 200 "scanner.lxx" /* Skip white space */ YY_BREAK case 81: YY_RULE_SETUP #line 201 "scanner.lxx" { return yytext[0]; } YY_BREAK case 82: /* rule 82 can match eol */ YY_RULE_SETUP #line 202 "scanner.lxx" { return T_ERROR; } YY_BREAK /* Quoted string (starting after open quote, closing quote will be consumed but not returned. */ case 83: YY_RULE_SETUP #line 206 "scanner.lxx" { yymore(); } YY_BREAK case 84: YY_RULE_SETUP #line 207 "scanner.lxx" { yymore(); } YY_BREAK case 85: YY_RULE_SETUP #line 208 "scanner.lxx" { yy_pop_state(); yytext[strlen(yytext)-1] = '\0'; yylval.yyt_str = new string(unescape(string(yytext))); MEMMAN_NEW(yylval.yyt_str); return T_QSTRING; } YY_BREAK case 86: /* rule 86 can match eol */ YY_RULE_SETUP #line 213 "scanner.lxx" { yy_pop_state(); return T_ERROR; } YY_BREAK case 87: YY_RULE_SETUP #line 214 "scanner.lxx" { yy_pop_state(); return T_ERROR; } YY_BREAK /* Comment (starting after LPAREN till RPAREN) */ case 88: YY_RULE_SETUP #line 217 "scanner.lxx" { yymore(); } YY_BREAK case 89: YY_RULE_SETUP #line 218 "scanner.lxx" { yymore(); } YY_BREAK case 90: YY_RULE_SETUP #line 219 "scanner.lxx" { yymore(); } YY_BREAK case 91: YY_RULE_SETUP #line 220 "scanner.lxx" { t_parser::inc_comment_level(); yymore(); } YY_BREAK case 92: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 221 "scanner.lxx" { if (t_parser::dec_comment_level()) { BEGIN(C_RPAREN); yymore(); } else { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_COMMENT; } } YY_BREAK case 93: /* rule 93 can match eol */ YY_RULE_SETUP #line 230 "scanner.lxx" { return T_ERROR; } YY_BREAK case 94: YY_RULE_SETUP #line 231 "scanner.lxx" { return T_ERROR; } YY_BREAK case 95: YY_RULE_SETUP #line 232 "scanner.lxx" { BEGIN(C_COMMENT); yymore(); } YY_BREAK /* Language tag */ case 96: YY_RULE_SETUP #line 235 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_LANG; } YY_BREAK case 97: YY_RULE_SETUP #line 238 "scanner.lxx" /* Skip white space */ YY_BREAK case 98: YY_RULE_SETUP #line 239 "scanner.lxx" { return yytext[0]; } YY_BREAK case 99: /* rule 99 can match eol */ YY_RULE_SETUP #line 240 "scanner.lxx" { return T_CRLF; } YY_BREAK case 100: /* rule 100 can match eol */ YY_RULE_SETUP #line 241 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Word */ case 101: YY_RULE_SETUP #line 244 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_WORD; } YY_BREAK case 102: YY_RULE_SETUP #line 247 "scanner.lxx" /* Skip white space */ YY_BREAK case 103: YY_RULE_SETUP #line 248 "scanner.lxx" { return yytext[0]; } YY_BREAK case 104: /* rule 104 can match eol */ YY_RULE_SETUP #line 249 "scanner.lxx" { return T_CRLF; } YY_BREAK case 105: /* rule 105 can match eol */ YY_RULE_SETUP #line 250 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Number */ case 106: YY_RULE_SETUP #line 253 "scanner.lxx" { yylval.yyt_ulong = strtoul(yytext, NULL, 10); return T_NUM; } YY_BREAK case 107: YY_RULE_SETUP #line 254 "scanner.lxx" /* Skip white space */ YY_BREAK case 108: YY_RULE_SETUP #line 255 "scanner.lxx" { return yytext[0]; } YY_BREAK case 109: /* rule 109 can match eol */ YY_RULE_SETUP #line 256 "scanner.lxx" { return T_CRLF; } YY_BREAK case 110: /* rule 110 can match eol */ YY_RULE_SETUP #line 257 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Date */ case 111: YY_RULE_SETUP #line 260 "scanner.lxx" { yylval.yyt_int = 1; return T_WKDAY; } YY_BREAK case 112: YY_RULE_SETUP #line 261 "scanner.lxx" { yylval.yyt_int = 2; return T_WKDAY; } YY_BREAK case 113: YY_RULE_SETUP #line 262 "scanner.lxx" { yylval.yyt_int = 3; return T_WKDAY; } YY_BREAK case 114: YY_RULE_SETUP #line 263 "scanner.lxx" { yylval.yyt_int = 4; return T_WKDAY; } YY_BREAK case 115: YY_RULE_SETUP #line 264 "scanner.lxx" { yylval.yyt_int = 5; return T_WKDAY; } YY_BREAK case 116: YY_RULE_SETUP #line 265 "scanner.lxx" { yylval.yyt_int = 6; return T_WKDAY; } YY_BREAK case 117: YY_RULE_SETUP #line 266 "scanner.lxx" { yylval.yyt_int = 0; return T_WKDAY; } YY_BREAK case 118: YY_RULE_SETUP #line 267 "scanner.lxx" { yylval.yyt_int = 0; return T_MONTH; } YY_BREAK case 119: YY_RULE_SETUP #line 268 "scanner.lxx" { yylval.yyt_int = 1; return T_MONTH; } YY_BREAK case 120: YY_RULE_SETUP #line 269 "scanner.lxx" { yylval.yyt_int = 2; return T_MONTH; } YY_BREAK case 121: YY_RULE_SETUP #line 270 "scanner.lxx" { yylval.yyt_int = 3; return T_MONTH; } YY_BREAK case 122: YY_RULE_SETUP #line 271 "scanner.lxx" { yylval.yyt_int = 4; return T_MONTH; } YY_BREAK case 123: YY_RULE_SETUP #line 272 "scanner.lxx" { yylval.yyt_int = 5; return T_MONTH; } YY_BREAK case 124: YY_RULE_SETUP #line 273 "scanner.lxx" { yylval.yyt_int = 6; return T_MONTH; } YY_BREAK case 125: YY_RULE_SETUP #line 274 "scanner.lxx" { yylval.yyt_int = 7; return T_MONTH; } YY_BREAK case 126: YY_RULE_SETUP #line 275 "scanner.lxx" { yylval.yyt_int = 8; return T_MONTH; } YY_BREAK case 127: YY_RULE_SETUP #line 276 "scanner.lxx" { yylval.yyt_int = 9; return T_MONTH; } YY_BREAK case 128: YY_RULE_SETUP #line 277 "scanner.lxx" { yylval.yyt_int = 10; return T_MONTH; } YY_BREAK case 129: YY_RULE_SETUP #line 278 "scanner.lxx" { yylval.yyt_int = 11; return T_MONTH; } YY_BREAK case 130: YY_RULE_SETUP #line 279 "scanner.lxx" { return T_GMT; } YY_BREAK case 131: YY_RULE_SETUP #line 280 "scanner.lxx" { yylval.yyt_ulong = strtoul(yytext, NULL, 10); return T_NUM; } YY_BREAK case 132: YY_RULE_SETUP #line 281 "scanner.lxx" /* Skip white space */ YY_BREAK case 133: YY_RULE_SETUP #line 282 "scanner.lxx" { return yytext[0]; } YY_BREAK case 134: /* rule 134 can match eol */ YY_RULE_SETUP #line 283 "scanner.lxx" { return T_CRLF; } YY_BREAK case 135: /* rule 135 can match eol */ YY_RULE_SETUP #line 284 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Get all text till end of line */ case 136: YY_RULE_SETUP #line 287 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_LINE; } YY_BREAK case 137: /* rule 137 can match eol */ YY_RULE_SETUP #line 290 "scanner.lxx" { return T_CRLF; } YY_BREAK case 138: /* rule 138 can match eol */ YY_RULE_SETUP #line 291 "scanner.lxx" { return T_CRLF; } YY_BREAK case 139: YY_RULE_SETUP #line 292 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Start of a new message */ case 140: YY_RULE_SETUP #line 295 "scanner.lxx" { return T_SIP; } YY_BREAK case 141: YY_RULE_SETUP #line 296 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_METHOD; } YY_BREAK case 142: YY_RULE_SETUP #line 299 "scanner.lxx" /* Skip white space */ YY_BREAK case 143: YY_RULE_SETUP #line 300 "scanner.lxx" { return T_ERROR; } YY_BREAK case 144: /* rule 144 can match eol */ YY_RULE_SETUP #line 301 "scanner.lxx" { return T_CRLF; } YY_BREAK case 145: /* rule 145 can match eol */ YY_RULE_SETUP #line 302 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Authorization scheme */ case 146: YY_RULE_SETUP #line 305 "scanner.lxx" { return T_AUTH_DIGEST; } YY_BREAK case 147: YY_RULE_SETUP #line 306 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_AUTH_OTHER; } YY_BREAK case 148: YY_RULE_SETUP #line 309 "scanner.lxx" /* Skip white space */ YY_BREAK case 149: YY_RULE_SETUP #line 310 "scanner.lxx" { return T_ERROR; } YY_BREAK case 150: /* rule 150 can match eol */ YY_RULE_SETUP #line 311 "scanner.lxx" { return T_CRLF; } YY_BREAK case 151: /* rule 151 can match eol */ YY_RULE_SETUP #line 312 "scanner.lxx" { return T_CRLF; } YY_BREAK /* IPv6 address * NOTE: the validity of the format is not checked here. */ case 152: YY_RULE_SETUP #line 317 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_IPV6ADDR; } YY_BREAK case 153: YY_RULE_SETUP #line 320 "scanner.lxx" /* Skip white space */ YY_BREAK case 154: YY_RULE_SETUP #line 321 "scanner.lxx" { return T_ERROR; } YY_BREAK case 155: /* rule 155 can match eol */ YY_RULE_SETUP #line 322 "scanner.lxx" { return T_CRLF; } YY_BREAK case 156: /* rule 156 can match eol */ YY_RULE_SETUP #line 323 "scanner.lxx" { return T_CRLF; } YY_BREAK /* Parameter values may contain an IPv6 address or reference. */ case 157: YY_RULE_SETUP #line 326 "scanner.lxx" { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_PARAMVAL; } YY_BREAK case 158: YY_RULE_SETUP #line 329 "scanner.lxx" { yy_push_state(C_QSTRING); } YY_BREAK case 159: YY_RULE_SETUP #line 330 "scanner.lxx" /* Skip white space */ YY_BREAK case 160: YY_RULE_SETUP #line 331 "scanner.lxx" { return T_ERROR; } YY_BREAK case 161: /* rule 161 can match eol */ YY_RULE_SETUP #line 332 "scanner.lxx" { return T_CRLF; } YY_BREAK case 162: /* rule 162 can match eol */ YY_RULE_SETUP #line 333 "scanner.lxx" { return T_CRLF; } YY_BREAK case 163: YY_RULE_SETUP #line 334 "scanner.lxx" ECHO; YY_BREAK #line 2482 "scanner.cxx" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(C_URI): case YY_STATE_EOF(C_URI_SPECIAL): case YY_STATE_EOF(C_QSTRING): case YY_STATE_EOF(C_LANG): case YY_STATE_EOF(C_WORD): case YY_STATE_EOF(C_NUM): case YY_STATE_EOF(C_DATE): case YY_STATE_EOF(C_LINE): case YY_STATE_EOF(C_COMMENT): case YY_STATE_EOF(C_NEW): case YY_STATE_EOF(C_AUTH_SCHEME): case YY_STATE_EOF(C_RPAREN): case YY_STATE_EOF(C_IPV6ADDR): case YY_STATE_EOF(C_PARAMVAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 714 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *(yy_state_ptr)++ = yy_current_state; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register YY_CHAR yy_c = 1; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 714 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 713); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param str a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } static void yy_push_state (int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) yyalloc(new_size ); else (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } static void yy_pop_state (void) { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } static int yy_top_state (void) { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; (yy_start_stack_ptr) = 0; (yy_start_stack_depth) = 0; (yy_start_stack) = NULL; (yy_state_buf) = 0; (yy_state_ptr) = 0; (yy_full_match) = 0; (yy_lp) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Destroy the start condition stack. */ yyfree((yy_start_stack) ); (yy_start_stack) = NULL; yyfree ( (yy_state_buf) ); (yy_state_buf) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 334 "scanner.lxx" twinkle-1.4.2/src/parser/scanner.lxx0000644000175000001440000002702411142376337014375 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %{ #include #include #include #include #include "parse_ctrl.h" #include "parser.h" #include "util.h" #include "audits/memman.h" using namespace std; %} %option noyywrap %option stack DIGIT [0-9] HEXDIG [0-9a-fA-F] ALPHA [a-zA-Z] CAPITALS [A-Z] ALNUM [a-zA-Z0-9] TOKEN_SYM [[:alnum:]\-\.!%\*_\+\`\'~] WORD_SYM [[:alnum:]\-\.!%\*_\+\`\'~\(\)<>:\\\"\/\[\]\?\{\}] %x C_URI %x C_URI_SPECIAL %x C_QSTRING %x C_LANG %x C_WORD %x C_NUM %x C_DATE %x C_LINE %x C_COMMENT %x C_NEW %x C_AUTH_SCHEME %x C_RPAREN %x C_IPV6ADDR %x C_PARAMVAL %% switch (t_parser::context) { case t_parser::X_URI: BEGIN(C_URI); break; case t_parser::X_URI_SPECIAL: BEGIN(C_URI_SPECIAL); break; case t_parser::X_LANG: BEGIN(C_LANG); break; case t_parser::X_WORD: BEGIN(C_WORD); break; case t_parser::X_NUM: BEGIN(C_NUM); break; case t_parser::X_DATE: BEGIN(C_DATE); break; case t_parser::X_LINE: BEGIN(C_LINE); break; case t_parser::X_COMMENT: BEGIN(C_COMMENT); break; case t_parser::X_NEW: BEGIN(C_NEW); break; case t_parser::X_AUTH_SCHEME: BEGIN(C_AUTH_SCHEME); break; case t_parser::X_IPV6ADDR: BEGIN(C_IPV6ADDR); break; case t_parser::X_PARAMVAL: BEGIN(C_PARAMVAL); break; default: BEGIN(INITIAL); } /* Headers */ ^Accept { return T_HDR_ACCEPT; } ^Accept-Encoding { return T_HDR_ACCEPT_ENCODING; } ^Accept-Language { return T_HDR_ACCEPT_LANGUAGE; } ^Alert-Info { return T_HDR_ALERT_INFO; } ^Allow { return T_HDR_ALLOW; } ^(Allow-Events)|u { return T_HDR_ALLOW_EVENTS; } ^Authentication-Info { return T_HDR_AUTHENTICATION_INFO; } ^Authorization { return T_HDR_AUTHORIZATION; } ^(Call-ID)|i { return T_HDR_CALL_ID; } ^Call-Info { return T_HDR_CALL_INFO; } ^(Contact)|m { return T_HDR_CONTACT; } ^Content-Disposition { return T_HDR_CONTENT_DISP; } ^(Content-Encoding)|e { return T_HDR_CONTENT_ENCODING; } ^Content-Language { return T_HDR_CONTENT_LANGUAGE; } ^(Content-Length)|l { return T_HDR_CONTENT_LENGTH; } ^(Content-Type)|c { return T_HDR_CONTENT_TYPE; } ^CSeq { return T_HDR_CSEQ; } ^Date { return T_HDR_DATE; } ^Error-Info { return T_HDR_ERROR_INFO; } ^(Event)|o { return T_HDR_EVENT; } ^Expires { return T_HDR_EXPIRES; } ^(From|f) { return T_HDR_FROM; } ^In-Reply-To { return T_HDR_IN_REPLY_TO; } ^Max-Forwards { return T_HDR_MAX_FORWARDS; } ^Min-Expires { return T_HDR_MIN_EXPIRES; } ^MIME-Version { return T_HDR_MIME_VERSION; } ^Organization { return T_HDR_ORGANIZATION; } ^P-Asserted-Identity { return T_HDR_P_ASSERTED_IDENTITY; } ^P-Preferred-Identity { return T_HDR_P_PREFERRED_IDENTITY; } ^Priority { return T_HDR_PRIORITY; } ^Privacy { return T_HDR_PRIVACY; } ^Proxy-Authenticate { return T_HDR_PROXY_AUTHENTICATE; } ^Proxy-Authorization { return T_HDR_PROXY_AUTHORIZATION; } ^Proxy-Require { return T_HDR_PROXY_REQUIRE; } ^RAck { return T_HDR_RACK; } ^Record-Route { return T_HDR_RECORD_ROUTE; } ^Service-Route { return T_HDR_SERVICE_ROUTE; } ^Refer-Sub { return T_HDR_REFER_SUB; } ^(Refer-To)|r { return T_HDR_REFER_TO; } ^(Referred-By)|b { return T_HDR_REFERRED_BY; } ^Replaces { return T_HDR_REPLACES; } ^Reply-To { return T_HDR_REPLY_TO; } ^Require { return T_HDR_REQUIRE; } ^(Request-Disposition)|d {return T_HDR_REQUEST_DISPOSITION; } ^Retry-After { return T_HDR_RETRY_AFTER; } ^Route { return T_HDR_ROUTE; } ^RSeq { return T_HDR_RSEQ; } ^Server { return T_HDR_SERVER; } ^SIP-ETag { return T_HDR_SIP_ETAG; } ^SIP-If-Match { return T_HDR_SIP_IF_MATCH; } ^(Subject)|s { return T_HDR_SUBJECT; } ^Subscription-State { return T_HDR_SUBSCRIPTION_STATE; } ^(Supported)|k { return T_HDR_SUPPORTED; } ^Timestamp { return T_HDR_TIMESTAMP; } ^(To)|t { return T_HDR_TO; } ^unsupported { return T_HDR_UNSUPPORTED; } ^User-Agent { return T_HDR_USER_AGENT; } ^(Via)|v { return T_HDR_VIA; } ^Warning { return T_HDR_WARNING; } ^WWW-Authenticate { return T_HDR_WWW_AUTHENTICATE; } ^{TOKEN_SYM}+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_HDR_UNKNOWN; } /* Token as define in RFC 3261 */ {TOKEN_SYM}+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_TOKEN; } /* Switch to quoted string context */ \" { yy_push_state(C_QSTRING); } /* End of line */ \r\n { return T_CRLF; } \n { return T_CRLF; } [[:blank:]] /* Skip white space */ /* Single character token */ . { return yytext[0]; } /* URI. This context scans a URI including parameters. The syntax of a URI will be checked outside the scanner */ \" { yy_push_state(C_QSTRING); } {TOKEN_SYM}({TOKEN_SYM}|[[:blank:]])*/< { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_DISPLAY; } [^[:blank:]<>\r\n]+/[[:blank:]]*> { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_URI; } \* { return T_URI_WILDCARD; } [^[:blank:]<>\"\r\n]+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_URI; } [[:blank:]] /* Skip white space */ . { return yytext[0]; } \n { return T_ERROR; } /* URI special case. In several headers (eg. From, To, Contact, Reply-To) the URI can be enclosed by < and > If it is enclosed then parameters belong to the URI, if it is not enclosed then parameters belong to the header. Parameters are seperated by a semi-colon. For the URI special case, parameters belong to the header. If the parser receives a < from the scanner, then the parser will switch to the normal URI case. The syntax of a URI will be checked outside the scanner */ \" { yy_push_state(C_QSTRING); } {TOKEN_SYM}({TOKEN_SYM}|[[:blank:]])*/< { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_DISPLAY; } \* { return T_URI_WILDCARD; } [^[:blank:]<>;\"\r\n]+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_URI; } [[:blank:]] /* Skip white space */ . { return yytext[0]; } \n { return T_ERROR; } /* Quoted string (starting after open quote, closing quote will be consumed but not returned. */ \\ { yymore(); } [^\"\\\r\n]*\\\" { yymore(); } [^\"\\\r\n]*\" { yy_pop_state(); yytext[strlen(yytext)-1] = '\0'; yylval.yyt_str = new string(unescape(string(yytext))); MEMMAN_NEW(yylval.yyt_str); return T_QSTRING; } [^\"\\\n]*\n { yy_pop_state(); return T_ERROR; } . { yy_pop_state(); return T_ERROR; } /* Comment (starting after LPAREN till RPAREN) */ \\ { yymore(); } [^\(\)\\\r\n]*\\\) { yymore(); } [^\(\)\\\r\n]*\\\( { yymore(); } [^\(\)\\\r\n]*\( { t_parser::inc_comment_level(); yymore(); } [^\(\)\\\r\n]*/\) { if (t_parser::dec_comment_level()) { BEGIN(C_RPAREN); yymore(); } else { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_COMMENT; } } [^\(\)\\\n]*\n { return T_ERROR; } . { return T_ERROR; } \) { BEGIN(C_COMMENT); yymore(); } /* Language tag */ {ALPHA}{1,8}(\-{ALPHA}{1,8})* { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_LANG; } [[:blank:]] /* Skip white space */ . { return yytext[0]; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Word */ {WORD_SYM}+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_WORD; } [[:blank:]] /* Skip white space */ . { return yytext[0]; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Number */ {DIGIT}+ { yylval.yyt_ulong = strtoul(yytext, NULL, 10); return T_NUM; } [[:blank:]] /* Skip white space */ . { return yytext[0]; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Date */ Mon { yylval.yyt_int = 1; return T_WKDAY; } Tue { yylval.yyt_int = 2; return T_WKDAY; } Wed { yylval.yyt_int = 3; return T_WKDAY; } Thu { yylval.yyt_int = 4; return T_WKDAY; } Fri { yylval.yyt_int = 5; return T_WKDAY; } Sat { yylval.yyt_int = 6; return T_WKDAY; } Sun { yylval.yyt_int = 0; return T_WKDAY; } Jan { yylval.yyt_int = 0; return T_MONTH; } Feb { yylval.yyt_int = 1; return T_MONTH; } Mar { yylval.yyt_int = 2; return T_MONTH; } Apr { yylval.yyt_int = 3; return T_MONTH; } May { yylval.yyt_int = 4; return T_MONTH; } Jun { yylval.yyt_int = 5; return T_MONTH; } Jul { yylval.yyt_int = 6; return T_MONTH; } Aug { yylval.yyt_int = 7; return T_MONTH; } Sep { yylval.yyt_int = 8; return T_MONTH; } Oct { yylval.yyt_int = 9; return T_MONTH; } Nov { yylval.yyt_int = 10; return T_MONTH; } Dec { yylval.yyt_int = 11; return T_MONTH; } GMT { return T_GMT; } {DIGIT}+ { yylval.yyt_ulong = strtoul(yytext, NULL, 10); return T_NUM; } [[:blank:]] /* Skip white space */ . { return yytext[0]; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Get all text till end of line */ [^\r\n]+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_LINE; } \r\n { return T_CRLF; } \n { return T_CRLF; } \r { return T_CRLF; } /* Start of a new message */ SIP { return T_SIP; } {CAPITALS}+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_METHOD; } [[:blank:]] /* Skip white space */ . { return T_ERROR; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Authorization scheme */ Digest { return T_AUTH_DIGEST; } {TOKEN_SYM}+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_AUTH_OTHER; } [[:blank:]] /* Skip white space */ . { return T_ERROR; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* IPv6 address * NOTE: the validity of the format is not checked here. */ ({HEXDIG}|[:\.])+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_IPV6ADDR; } [[:blank:]] /* Skip white space */ . { return T_ERROR; } \r\n { return T_CRLF; } \n { return T_CRLF; } /* Parameter values may contain an IPv6 address or reference. */ ({TOKEN_SYM}|[:\[\]])+ { yylval.yyt_str = new string(yytext); MEMMAN_NEW(yylval.yyt_str); return T_PARAMVAL; } \" { yy_push_state(C_QSTRING); } [[:blank:]] /* Skip white space */ . { return T_ERROR; } \r\n { return T_CRLF; } \n { return T_CRLF; } twinkle-1.4.2/src/parser/hdr_proxy_require.h0000644000175000001440000000214111127714050016112 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Proxy-Require header #ifndef _H_HDR_PROXY_REQUIRE #define _H_HDR_PROXY_REQUIRE #include #include #include "header.h" class t_hdr_proxy_require : public t_header { public: list features; t_hdr_proxy_require(); void add_feature(const string &f); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_warning.h0000644000175000001440000000474511127714050014656 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Warning header #ifndef _H_HDR_WARNING #define _H_HDR_WARNING #include #include #include "header.h" // Warning codes #define W_300_INCOMPATIBLE_NWK_PROT 300 #define W_301_INCOMPATIBLE_ADDR_FORMAT 301 #define W_302_INCOMPATIBLE_TRANS_PROT 302 #define W_303_INCOMPATIBLE_BW_UNITS 303 #define W_304_MEDIA_TYPE_NOT_AVAILABLE 304 #define W_305_INCOMPATIBLE_MEDIA_FORMAT 305 #define W_306_ATTRIBUTE_NOT_UNDERSTOOD 306 #define W_307_PARAMETER_NOT_UNDERSTOOD 307 #define W_330_MULTICAST_NOT_AVAILABLE 330 #define W_331_UNICAST_NOT_AVAILABLE 331 #define W_370_INSUFFICIENT_BANDWITH 370 #define W_399_MISCELLANEOUS 399 // Warning texts #define WARNING_300 "Incompatible network protocol" #define WARNING_301 "Incompatible network address formats" #define WARNING_302 "Incompatible transport protocol" #define WARNING_303 "Incompatible bandwith units" #define WARNING_304 "Media type not available" #define WARNING_305 "Incompatible media format" #define WARNING_306 "Attribute not understood" #define WARNING_307 "Session description parameter not understood" #define WARNING_330 "Multicast not available" #define WARNING_331 "Unicast not available" #define WARNING_370 "Insufficient bandwith" #define WARNING_399 "Miscellanous warning" using namespace std; class t_warning { public: int code; string host; int port; string text; t_warning(); // The default text will be used as warning appended with passed // text if present t_warning(const string &_host, int _port, int _code, string _text); string encode(void) const; }; class t_hdr_warning : public t_header { public: list warnings; t_hdr_warning(); void add_warning(const t_warning &w); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_priority.cpp0000644000175000001440000000211411127714057015420 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_priority.h" t_hdr_priority::t_hdr_priority() : t_header("Priority") {}; void t_hdr_priority::set_priority(const string &p) { populated = true; priority = p; } string t_hdr_priority::encode_value(void) const { if (!populated) return ""; return priority; } twinkle-1.4.2/src/parser/hdr_p_preferred_identity.h0000644000175000001440000000230711127714050017407 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3325 9.2 // P-Preferred-Identity header #ifndef _H_HDR_P_PREFERRED_IDENTITY #define _H_HDR_P_PREFERRED_IDENTITY #include #include "header.h" #include "identity.h" using namespace std; class t_hdr_p_preferred_identity : public t_header { public: list identity_list; t_hdr_p_preferred_identity(); void add_identity(const t_identity &identity); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_error_info.h0000644000175000001440000000256611127714050015354 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Error-Info header #ifndef _HDR_ERROR_INFO_H #define _HDR_ERROR_INFO_H #include #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_error_param { public: t_url uri; list parameter_list; void add_param(const t_parameter &p); string encode(void) const; }; class t_hdr_error_info : public t_header { public: list error_param_list; t_hdr_error_info(); // Add a paramter to the list of error parameters void add_param(const t_error_param &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_route.cpp0000644000175000001440000000327211127714057014703 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_route.h" #include "parse_ctrl.h" t_hdr_route::t_hdr_route() : t_header("Route") { route_to_first_route = false; } void t_hdr_route::add_route(const t_route &r) { populated = true; route_list.push_back(r); } string t_hdr_route::encode(void) const { return (t_parser::multi_values_as_list ? t_header::encode() : encode_multi_header()); } string t_hdr_route::encode_multi_header(void) const { string s; if (!populated) return s; for (list::const_iterator i = route_list.begin(); i != route_list.end(); i++) { s += header_name; s += ": "; s += i->encode(); s += CRLF; } return s; } string t_hdr_route::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = route_list.begin(); i != route_list.end(); i++) { if (i != route_list.begin()) s += ","; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_content_length.h0000644000175000001440000000214711134635663016230 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Content-Length header #ifndef _HDR_CONTENT_LENGTH #define _HDR_CONTENT_LENGTH #include #include "header.h" using namespace std; class t_hdr_content_length : public t_header { public: unsigned long length; t_hdr_content_length(); void set_length(unsigned long l); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_mime_version.h0000644000175000001440000000213211127714050015671 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // MIME-Version header #ifndef _H_HDR_MIME_VERSION #define _H_HDR_MIME_VERSION #include #include "header.h" using namespace std; class t_hdr_mime_version : public t_header { public: string version; t_hdr_mime_version(); void set_version(const string &v); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_organization.cpp0000644000175000001440000000213011127714057016241 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_organization.h" t_hdr_organization::t_hdr_organization() : t_header("Organization") {}; void t_hdr_organization::set_name(const string &n) { populated = true; name = n; } string t_hdr_organization::encode_value(void) const { if (!populated) return ""; return name; } twinkle-1.4.2/src/parser/hdr_privacy.h0000644000175000001440000000255711127714050014665 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3323 // Privacy header #ifndef _H_HDR_PRIVACY #define _H_HDR_PRICACY #include #include #include "header.h" #define PRIVACY_HEADER "header" #define PRIVACY_SESSION "session" #define PRIVACY_USER "user" #define PRIVACY_NONE "none" #define PRIVACY_CRITICAL "critical" // RFC 3325 9.3 defines id privacy #define PRIVACY_ID "id" class t_hdr_privacy : public t_header { public: list privacy_list; t_hdr_privacy(); void add_privacy(const string &privacy); bool contains_privacy(const string &privacy) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_refer_sub.cpp0000644000175000001440000000260511127714057015520 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_refer_sub.h" t_hdr_refer_sub::t_hdr_refer_sub() : t_header("Refer-Sub"), create_refer_sub(true) {} void t_hdr_refer_sub::set_create_refer_sub(bool on) { populated = true; create_refer_sub = on; } void t_hdr_refer_sub::add_extension(const t_parameter &p) { populated = true; extensions.push_back(p); } void t_hdr_refer_sub::set_extensions(const list &l) { populated = true; extensions = l; } string t_hdr_refer_sub::encode_value(void) const { string s; if (!populated) return s; s = (create_refer_sub ? "true" : "false"); s += param_list2str(extensions); return s; } twinkle-1.4.2/src/parser/hdr_from.cpp0000644000175000001440000000357611127714057014517 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_from.h" #include "definitions.h" #include "parse_ctrl.h" #include "util.h" t_hdr_from::t_hdr_from() : t_header("From", "f") {} void t_hdr_from::set_display(const string &d) { populated = true; display = d; } void t_hdr_from::set_uri(const string &u) { populated = true; uri.set_url(u); } void t_hdr_from::set_uri(const t_url &u) { populated = true; uri = u; } void t_hdr_from::set_tag(const string &t) { populated = true; tag = t; } void t_hdr_from::set_params(const list &l) { populated = true; params = l; } void t_hdr_from::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_from::encode_value(void) const { string s; if (!populated) return s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; if (tag != "") { s += ";tag="; s += tag; } s += param_list2str(params); return s; } string t_hdr_from::get_display_presentation(void) const { if (display_override.empty()) { return display; } else { return display_override; } } twinkle-1.4.2/src/parser/hdr_proxy_authorization.h0000644000175000001440000000277511127714050017353 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Proxy-Authorization header #ifndef _HDR_PROXY_AUTHORIZATION #define _HDR_PROXY_AUTHORIZATION #include #include #include "credentials.h" #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_proxy_authorization : public t_header { public: list credentials_list; t_hdr_proxy_authorization(); void add_credentials(const t_credentials &c); string encode(void) const; string encode_value(void) const; // Return true if the header contains credentials for a realm/dest bool contains(const string &realm, const t_url &uri) const; // Remove credentials for a realm/dest void remove_credentials(const string &realm, const t_url &uri); }; #endif twinkle-1.4.2/src/parser/rijndael.cpp0000644000175000001440000006602711127714057014507 00000000000000/*------------------------------------------------------------------- * Rijndael Implementation *------------------------------------------------------------------- * * A sample 32-bit orientated implementation of Rijndael, the * suggested kernel for the example 3GPP authentication and key * agreement functions. * * This implementation draws on the description in section 5.2 of * the AES proposal and also on the implementation by * Dr B. R. Gladman 9th October 2000. * It uses a number of large (4k) lookup tables to implement the * algorithm in an efficient manner. * * Note: in this implementation the State is stored in four 32-bit * words, one per column of the State, with the top byte of the * column being the _least_ significant byte of the word. * *-----------------------------------------------------------------*/ #include "twinkle_config.h" typedef unsigned char u8; typedef unsigned int u32; /* Circular byte rotates of 32 bit values */ #define rot1(x) ((x << 8) | (x >> 24)) #define rot2(x) ((x << 16) | (x >> 16)) #define rot3(x) ((x << 24) | (x >> 8)) /* Extract a byte from a 32-bit u32 */ #define byte0(x) ((u8)(x)) #define byte1(x) ((u8)(x >> 8)) #define byte2(x) ((u8)(x >> 16)) #define byte3(x) ((u8)(x >> 24)) /* Put or get a 32 bit u32 (v) in machine order from a byte * * address in (x) */ #ifndef WORDS_BIGENDIAN #define u32_in(x) (*(u32*)(x)) #define u32_out(x,y) (*(u32*)(x) = y) #else /* Invert byte order in a 32 bit variable */ __inline u32 byte_swap(const u32 x) { return rot1(x) & 0x00ff00ff | rot3(x) & 0xff00ff00; } __inline u32 u32_in(const u8 x[]) { return byte_swap(*(u32*)x); }; __inline void u32_out(u8 x[], const u32 v) { *(u32*)x = byte_swap(v); }; #endif /*--------------- The lookup tables ----------------------------*/ static u32 rnd_con[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 }; static u32 ft_tab[4][256] = { { 0xA56363C6,0x847C7CF8,0x997777EE,0x8D7B7BF6,0x0DF2F2FF,0xBD6B6BD6,0xB16F6FDE,0x54C5C591, 0x50303060,0x03010102,0xA96767CE,0x7D2B2B56,0x19FEFEE7,0x62D7D7B5,0xE6ABAB4D,0x9A7676EC, 0x45CACA8F,0x9D82821F,0x40C9C989,0x877D7DFA,0x15FAFAEF,0xEB5959B2,0xC947478E,0x0BF0F0FB, 0xECADAD41,0x67D4D4B3,0xFDA2A25F,0xEAAFAF45,0xBF9C9C23,0xF7A4A453,0x967272E4,0x5BC0C09B, 0xC2B7B775,0x1CFDFDE1,0xAE93933D,0x6A26264C,0x5A36366C,0x413F3F7E,0x02F7F7F5,0x4FCCCC83, 0x5C343468,0xF4A5A551,0x34E5E5D1,0x08F1F1F9,0x937171E2,0x73D8D8AB,0x53313162,0x3F15152A, 0x0C040408,0x52C7C795,0x65232346,0x5EC3C39D,0x28181830,0xA1969637,0x0F05050A,0xB59A9A2F, 0x0907070E,0x36121224,0x9B80801B,0x3DE2E2DF,0x26EBEBCD,0x6927274E,0xCDB2B27F,0x9F7575EA, 0x1B090912,0x9E83831D,0x742C2C58,0x2E1A1A34,0x2D1B1B36,0xB26E6EDC,0xEE5A5AB4,0xFBA0A05B, 0xF65252A4,0x4D3B3B76,0x61D6D6B7,0xCEB3B37D,0x7B292952,0x3EE3E3DD,0x712F2F5E,0x97848413, 0xF55353A6,0x68D1D1B9,0000000000,0x2CEDEDC1,0x60202040,0x1FFCFCE3,0xC8B1B179,0xED5B5BB6, 0xBE6A6AD4,0x46CBCB8D,0xD9BEBE67,0x4B393972,0xDE4A4A94,0xD44C4C98,0xE85858B0,0x4ACFCF85, 0x6BD0D0BB,0x2AEFEFC5,0xE5AAAA4F,0x16FBFBED,0xC5434386,0xD74D4D9A,0x55333366,0x94858511, 0xCF45458A,0x10F9F9E9,0x06020204,0x817F7FFE,0xF05050A0,0x443C3C78,0xBA9F9F25,0xE3A8A84B, 0xF35151A2,0xFEA3A35D,0xC0404080,0x8A8F8F05,0xAD92923F,0xBC9D9D21,0x48383870,0x04F5F5F1, 0xDFBCBC63,0xC1B6B677,0x75DADAAF,0x63212142,0x30101020,0x1AFFFFE5,0x0EF3F3FD,0x6DD2D2BF, 0x4CCDCD81,0x140C0C18,0x35131326,0x2FECECC3,0xE15F5FBE,0xA2979735,0xCC444488,0x3917172E, 0x57C4C493,0xF2A7A755,0x827E7EFC,0x473D3D7A,0xAC6464C8,0xE75D5DBA,0x2B191932,0x957373E6, 0xA06060C0,0x98818119,0xD14F4F9E,0x7FDCDCA3,0x66222244,0x7E2A2A54,0xAB90903B,0x8388880B, 0xCA46468C,0x29EEEEC7,0xD3B8B86B,0x3C141428,0x79DEDEA7,0xE25E5EBC,0x1D0B0B16,0x76DBDBAD, 0x3BE0E0DB,0x56323264,0x4E3A3A74,0x1E0A0A14,0xDB494992,0x0A06060C,0x6C242448,0xE45C5CB8, 0x5DC2C29F,0x6ED3D3BD,0xEFACAC43,0xA66262C4,0xA8919139,0xA4959531,0x37E4E4D3,0x8B7979F2, 0x32E7E7D5,0x43C8C88B,0x5937376E,0xB76D6DDA,0x8C8D8D01,0x64D5D5B1,0xD24E4E9C,0xE0A9A949, 0xB46C6CD8,0xFA5656AC,0x07F4F4F3,0x25EAEACF,0xAF6565CA,0x8E7A7AF4,0xE9AEAE47,0x18080810, 0xD5BABA6F,0x887878F0,0x6F25254A,0x722E2E5C,0x241C1C38,0xF1A6A657,0xC7B4B473,0x51C6C697, 0x23E8E8CB,0x7CDDDDA1,0x9C7474E8,0x211F1F3E,0xDD4B4B96,0xDCBDBD61,0x868B8B0D,0x858A8A0F, 0x907070E0,0x423E3E7C,0xC4B5B571,0xAA6666CC,0xD8484890,0x05030306,0x01F6F6F7,0x120E0E1C, 0xA36161C2,0x5F35356A,0xF95757AE,0xD0B9B969,0x91868617,0x58C1C199,0x271D1D3A,0xB99E9E27, 0x38E1E1D9,0x13F8F8EB,0xB398982B,0x33111122,0xBB6969D2,0x70D9D9A9,0x898E8E07,0xA7949433, 0xB69B9B2D,0x221E1E3C,0x92878715,0x20E9E9C9,0x49CECE87,0xFF5555AA,0x78282850,0x7ADFDFA5, 0x8F8C8C03,0xF8A1A159,0x80898909,0x170D0D1A,0xDABFBF65,0x31E6E6D7,0xC6424284,0xB86868D0, 0xC3414182,0xB0999929,0x772D2D5A,0x110F0F1E,0xCBB0B07B,0xFC5454A8,0xD6BBBB6D,0x3A16162C }, { 0x6363C6A5,0x7C7CF884,0x7777EE99,0x7B7BF68D,0xF2F2FF0D,0x6B6BD6BD,0x6F6FDEB1,0xC5C59154, 0x30306050,0x01010203,0x6767CEA9,0x2B2B567D,0xFEFEE719,0xD7D7B562,0xABAB4DE6,0x7676EC9A, 0xCACA8F45,0x82821F9D,0xC9C98940,0x7D7DFA87,0xFAFAEF15,0x5959B2EB,0x47478EC9,0xF0F0FB0B, 0xADAD41EC,0xD4D4B367,0xA2A25FFD,0xAFAF45EA,0x9C9C23BF,0xA4A453F7,0x7272E496,0xC0C09B5B, 0xB7B775C2,0xFDFDE11C,0x93933DAE,0x26264C6A,0x36366C5A,0x3F3F7E41,0xF7F7F502,0xCCCC834F, 0x3434685C,0xA5A551F4,0xE5E5D134,0xF1F1F908,0x7171E293,0xD8D8AB73,0x31316253,0x15152A3F, 0x0404080C,0xC7C79552,0x23234665,0xC3C39D5E,0x18183028,0x969637A1,0x05050A0F,0x9A9A2FB5, 0x07070E09,0x12122436,0x80801B9B,0xE2E2DF3D,0xEBEBCD26,0x27274E69,0xB2B27FCD,0x7575EA9F, 0x0909121B,0x83831D9E,0x2C2C5874,0x1A1A342E,0x1B1B362D,0x6E6EDCB2,0x5A5AB4EE,0xA0A05BFB, 0x5252A4F6,0x3B3B764D,0xD6D6B761,0xB3B37DCE,0x2929527B,0xE3E3DD3E,0x2F2F5E71,0x84841397, 0x5353A6F5,0xD1D1B968,0000000000,0xEDEDC12C,0x20204060,0xFCFCE31F,0xB1B179C8,0x5B5BB6ED, 0x6A6AD4BE,0xCBCB8D46,0xBEBE67D9,0x3939724B,0x4A4A94DE,0x4C4C98D4,0x5858B0E8,0xCFCF854A, 0xD0D0BB6B,0xEFEFC52A,0xAAAA4FE5,0xFBFBED16,0x434386C5,0x4D4D9AD7,0x33336655,0x85851194, 0x45458ACF,0xF9F9E910,0x02020406,0x7F7FFE81,0x5050A0F0,0x3C3C7844,0x9F9F25BA,0xA8A84BE3, 0x5151A2F3,0xA3A35DFE,0x404080C0,0x8F8F058A,0x92923FAD,0x9D9D21BC,0x38387048,0xF5F5F104, 0xBCBC63DF,0xB6B677C1,0xDADAAF75,0x21214263,0x10102030,0xFFFFE51A,0xF3F3FD0E,0xD2D2BF6D, 0xCDCD814C,0x0C0C1814,0x13132635,0xECECC32F,0x5F5FBEE1,0x979735A2,0x444488CC,0x17172E39, 0xC4C49357,0xA7A755F2,0x7E7EFC82,0x3D3D7A47,0x6464C8AC,0x5D5DBAE7,0x1919322B,0x7373E695, 0x6060C0A0,0x81811998,0x4F4F9ED1,0xDCDCA37F,0x22224466,0x2A2A547E,0x90903BAB,0x88880B83, 0x46468CCA,0xEEEEC729,0xB8B86BD3,0x1414283C,0xDEDEA779,0x5E5EBCE2,0x0B0B161D,0xDBDBAD76, 0xE0E0DB3B,0x32326456,0x3A3A744E,0x0A0A141E,0x494992DB,0x06060C0A,0x2424486C,0x5C5CB8E4, 0xC2C29F5D,0xD3D3BD6E,0xACAC43EF,0x6262C4A6,0x919139A8,0x959531A4,0xE4E4D337,0x7979F28B, 0xE7E7D532,0xC8C88B43,0x37376E59,0x6D6DDAB7,0x8D8D018C,0xD5D5B164,0x4E4E9CD2,0xA9A949E0, 0x6C6CD8B4,0x5656ACFA,0xF4F4F307,0xEAEACF25,0x6565CAAF,0x7A7AF48E,0xAEAE47E9,0x08081018, 0xBABA6FD5,0x7878F088,0x25254A6F,0x2E2E5C72,0x1C1C3824,0xA6A657F1,0xB4B473C7,0xC6C69751, 0xE8E8CB23,0xDDDDA17C,0x7474E89C,0x1F1F3E21,0x4B4B96DD,0xBDBD61DC,0x8B8B0D86,0x8A8A0F85, 0x7070E090,0x3E3E7C42,0xB5B571C4,0x6666CCAA,0x484890D8,0x03030605,0xF6F6F701,0x0E0E1C12, 0x6161C2A3,0x35356A5F,0x5757AEF9,0xB9B969D0,0x86861791,0xC1C19958,0x1D1D3A27,0x9E9E27B9, 0xE1E1D938,0xF8F8EB13,0x98982BB3,0x11112233,0x6969D2BB,0xD9D9A970,0x8E8E0789,0x949433A7, 0x9B9B2DB6,0x1E1E3C22,0x87871592,0xE9E9C920,0xCECE8749,0x5555AAFF,0x28285078,0xDFDFA57A, 0x8C8C038F,0xA1A159F8,0x89890980,0x0D0D1A17,0xBFBF65DA,0xE6E6D731,0x424284C6,0x6868D0B8, 0x414182C3,0x999929B0,0x2D2D5A77,0x0F0F1E11,0xB0B07BCB,0x5454A8FC,0xBBBB6DD6,0x16162C3A }, { 0x63C6A563,0x7CF8847C,0x77EE9977,0x7BF68D7B,0xF2FF0DF2,0x6BD6BD6B,0x6FDEB16F,0xC59154C5, 0x30605030,0x01020301,0x67CEA967,0x2B567D2B,0xFEE719FE,0xD7B562D7,0xAB4DE6AB,0x76EC9A76, 0xCA8F45CA,0x821F9D82,0xC98940C9,0x7DFA877D,0xFAEF15FA,0x59B2EB59,0x478EC947,0xF0FB0BF0, 0xAD41ECAD,0xD4B367D4,0xA25FFDA2,0xAF45EAAF,0x9C23BF9C,0xA453F7A4,0x72E49672,0xC09B5BC0, 0xB775C2B7,0xFDE11CFD,0x933DAE93,0x264C6A26,0x366C5A36,0x3F7E413F,0xF7F502F7,0xCC834FCC, 0x34685C34,0xA551F4A5,0xE5D134E5,0xF1F908F1,0x71E29371,0xD8AB73D8,0x31625331,0x152A3F15, 0x04080C04,0xC79552C7,0x23466523,0xC39D5EC3,0x18302818,0x9637A196,0x050A0F05,0x9A2FB59A, 0x070E0907,0x12243612,0x801B9B80,0xE2DF3DE2,0xEBCD26EB,0x274E6927,0xB27FCDB2,0x75EA9F75, 0x09121B09,0x831D9E83,0x2C58742C,0x1A342E1A,0x1B362D1B,0x6EDCB26E,0x5AB4EE5A,0xA05BFBA0, 0x52A4F652,0x3B764D3B,0xD6B761D6,0xB37DCEB3,0x29527B29,0xE3DD3EE3,0x2F5E712F,0x84139784, 0x53A6F553,0xD1B968D1,0000000000,0xEDC12CED,0x20406020,0xFCE31FFC,0xB179C8B1,0x5BB6ED5B, 0x6AD4BE6A,0xCB8D46CB,0xBE67D9BE,0x39724B39,0x4A94DE4A,0x4C98D44C,0x58B0E858,0xCF854ACF, 0xD0BB6BD0,0xEFC52AEF,0xAA4FE5AA,0xFBED16FB,0x4386C543,0x4D9AD74D,0x33665533,0x85119485, 0x458ACF45,0xF9E910F9,0x02040602,0x7FFE817F,0x50A0F050,0x3C78443C,0x9F25BA9F,0xA84BE3A8, 0x51A2F351,0xA35DFEA3,0x4080C040,0x8F058A8F,0x923FAD92,0x9D21BC9D,0x38704838,0xF5F104F5, 0xBC63DFBC,0xB677C1B6,0xDAAF75DA,0x21426321,0x10203010,0xFFE51AFF,0xF3FD0EF3,0xD2BF6DD2, 0xCD814CCD,0x0C18140C,0x13263513,0xECC32FEC,0x5FBEE15F,0x9735A297,0x4488CC44,0x172E3917, 0xC49357C4,0xA755F2A7,0x7EFC827E,0x3D7A473D,0x64C8AC64,0x5DBAE75D,0x19322B19,0x73E69573, 0x60C0A060,0x81199881,0x4F9ED14F,0xDCA37FDC,0x22446622,0x2A547E2A,0x903BAB90,0x880B8388, 0x468CCA46,0xEEC729EE,0xB86BD3B8,0x14283C14,0xDEA779DE,0x5EBCE25E,0x0B161D0B,0xDBAD76DB, 0xE0DB3BE0,0x32645632,0x3A744E3A,0x0A141E0A,0x4992DB49,0x060C0A06,0x24486C24,0x5CB8E45C, 0xC29F5DC2,0xD3BD6ED3,0xAC43EFAC,0x62C4A662,0x9139A891,0x9531A495,0xE4D337E4,0x79F28B79, 0xE7D532E7,0xC88B43C8,0x376E5937,0x6DDAB76D,0x8D018C8D,0xD5B164D5,0x4E9CD24E,0xA949E0A9, 0x6CD8B46C,0x56ACFA56,0xF4F307F4,0xEACF25EA,0x65CAAF65,0x7AF48E7A,0xAE47E9AE,0x08101808, 0xBA6FD5BA,0x78F08878,0x254A6F25,0x2E5C722E,0x1C38241C,0xA657F1A6,0xB473C7B4,0xC69751C6, 0xE8CB23E8,0xDDA17CDD,0x74E89C74,0x1F3E211F,0x4B96DD4B,0xBD61DCBD,0x8B0D868B,0x8A0F858A, 0x70E09070,0x3E7C423E,0xB571C4B5,0x66CCAA66,0x4890D848,0x03060503,0xF6F701F6,0x0E1C120E, 0x61C2A361,0x356A5F35,0x57AEF957,0xB969D0B9,0x86179186,0xC19958C1,0x1D3A271D,0x9E27B99E, 0xE1D938E1,0xF8EB13F8,0x982BB398,0x11223311,0x69D2BB69,0xD9A970D9,0x8E07898E,0x9433A794, 0x9B2DB69B,0x1E3C221E,0x87159287,0xE9C920E9,0xCE8749CE,0x55AAFF55,0x28507828,0xDFA57ADF, 0x8C038F8C,0xA159F8A1,0x89098089,0x0D1A170D,0xBF65DABF,0xE6D731E6,0x4284C642,0x68D0B868, 0x4182C341,0x9929B099,0x2D5A772D,0x0F1E110F,0xB07BCBB0,0x54A8FC54,0xBB6DD6BB,0x162C3A16 }, { 0xC6A56363,0xF8847C7C,0xEE997777,0xF68D7B7B,0xFF0DF2F2,0xD6BD6B6B,0xDEB16F6F,0x9154C5C5, 0x60503030,0x02030101,0xCEA96767,0x567D2B2B,0xE719FEFE,0xB562D7D7,0x4DE6ABAB,0xEC9A7676, 0x8F45CACA,0x1F9D8282,0x8940C9C9,0xFA877D7D,0xEF15FAFA,0xB2EB5959,0x8EC94747,0xFB0BF0F0, 0x41ECADAD,0xB367D4D4,0x5FFDA2A2,0x45EAAFAF,0x23BF9C9C,0x53F7A4A4,0xE4967272,0x9B5BC0C0, 0x75C2B7B7,0xE11CFDFD,0x3DAE9393,0x4C6A2626,0x6C5A3636,0x7E413F3F,0xF502F7F7,0x834FCCCC, 0x685C3434,0x51F4A5A5,0xD134E5E5,0xF908F1F1,0xE2937171,0xAB73D8D8,0x62533131,0x2A3F1515, 0x080C0404,0x9552C7C7,0x46652323,0x9D5EC3C3,0x30281818,0x37A19696,0x0A0F0505,0x2FB59A9A, 0x0E090707,0x24361212,0x1B9B8080,0xDF3DE2E2,0xCD26EBEB,0x4E692727,0x7FCDB2B2,0xEA9F7575, 0x121B0909,0x1D9E8383,0x58742C2C,0x342E1A1A,0x362D1B1B,0xDCB26E6E,0xB4EE5A5A,0x5BFBA0A0, 0xA4F65252,0x764D3B3B,0xB761D6D6,0x7DCEB3B3,0x527B2929,0xDD3EE3E3,0x5E712F2F,0x13978484, 0xA6F55353,0xB968D1D1,0000000000,0xC12CEDED,0x40602020,0xE31FFCFC,0x79C8B1B1,0xB6ED5B5B, 0xD4BE6A6A,0x8D46CBCB,0x67D9BEBE,0x724B3939,0x94DE4A4A,0x98D44C4C,0xB0E85858,0x854ACFCF, 0xBB6BD0D0,0xC52AEFEF,0x4FE5AAAA,0xED16FBFB,0x86C54343,0x9AD74D4D,0x66553333,0x11948585, 0x8ACF4545,0xE910F9F9,0x04060202,0xFE817F7F,0xA0F05050,0x78443C3C,0x25BA9F9F,0x4BE3A8A8, 0xA2F35151,0x5DFEA3A3,0x80C04040,0x058A8F8F,0x3FAD9292,0x21BC9D9D,0x70483838,0xF104F5F5, 0x63DFBCBC,0x77C1B6B6,0xAF75DADA,0x42632121,0x20301010,0xE51AFFFF,0xFD0EF3F3,0xBF6DD2D2, 0x814CCDCD,0x18140C0C,0x26351313,0xC32FECEC,0xBEE15F5F,0x35A29797,0x88CC4444,0x2E391717, 0x9357C4C4,0x55F2A7A7,0xFC827E7E,0x7A473D3D,0xC8AC6464,0xBAE75D5D,0x322B1919,0xE6957373, 0xC0A06060,0x19988181,0x9ED14F4F,0xA37FDCDC,0x44662222,0x547E2A2A,0x3BAB9090,0x0B838888, 0x8CCA4646,0xC729EEEE,0x6BD3B8B8,0x283C1414,0xA779DEDE,0xBCE25E5E,0x161D0B0B,0xAD76DBDB, 0xDB3BE0E0,0x64563232,0x744E3A3A,0x141E0A0A,0x92DB4949,0x0C0A0606,0x486C2424,0xB8E45C5C, 0x9F5DC2C2,0xBD6ED3D3,0x43EFACAC,0xC4A66262,0x39A89191,0x31A49595,0xD337E4E4,0xF28B7979, 0xD532E7E7,0x8B43C8C8,0x6E593737,0xDAB76D6D,0x018C8D8D,0xB164D5D5,0x9CD24E4E,0x49E0A9A9, 0xD8B46C6C,0xACFA5656,0xF307F4F4,0xCF25EAEA,0xCAAF6565,0xF48E7A7A,0x47E9AEAE,0x10180808, 0x6FD5BABA,0xF0887878,0x4A6F2525,0x5C722E2E,0x38241C1C,0x57F1A6A6,0x73C7B4B4,0x9751C6C6, 0xCB23E8E8,0xA17CDDDD,0xE89C7474,0x3E211F1F,0x96DD4B4B,0x61DCBDBD,0x0D868B8B,0x0F858A8A, 0xE0907070,0x7C423E3E,0x71C4B5B5,0xCCAA6666,0x90D84848,0x06050303,0xF701F6F6,0x1C120E0E, 0xC2A36161,0x6A5F3535,0xAEF95757,0x69D0B9B9,0x17918686,0x9958C1C1,0x3A271D1D,0x27B99E9E, 0xD938E1E1,0xEB13F8F8,0x2BB39898,0x22331111,0xD2BB6969,0xA970D9D9,0x07898E8E,0x33A79494, 0x2DB69B9B,0x3C221E1E,0x15928787,0xC920E9E9,0x8749CECE,0xAAFF5555,0x50782828,0xA57ADFDF, 0x038F8C8C,0x59F8A1A1,0x09808989,0x1A170D0D,0x65DABFBF,0xD731E6E6,0x84C64242,0xD0B86868, 0x82C34141,0x29B09999,0x5A772D2D,0x1E110F0F,0x7BCBB0B0,0xA8FC5454,0x6DD6BBBB,0x2C3A1616 } }; static u32 fl_tab[4][256] = { { 0x00000063,0x0000007C,0x00000077,0x0000007B,0x000000F2,0x0000006B,0x0000006F,0x000000C5, 0x00000030,0x00000001,0x00000067,0x0000002B,0x000000FE,0x000000D7,0x000000AB,0x00000076, 0x000000CA,0x00000082,0x000000C9,0x0000007D,0x000000FA,0x00000059,0x00000047,0x000000F0, 0x000000AD,0x000000D4,0x000000A2,0x000000AF,0x0000009C,0x000000A4,0x00000072,0x000000C0, 0x000000B7,0x000000FD,0x00000093,0x00000026,0x00000036,0x0000003F,0x000000F7,0x000000CC, 0x00000034,0x000000A5,0x000000E5,0x000000F1,0x00000071,0x000000D8,0x00000031,0x00000015, 0x00000004,0x000000C7,0x00000023,0x000000C3,0x00000018,0x00000096,0x00000005,0x0000009A, 0x00000007,0x00000012,0x00000080,0x000000E2,0x000000EB,0x00000027,0x000000B2,0x00000075, 0x00000009,0x00000083,0x0000002C,0x0000001A,0x0000001B,0x0000006E,0x0000005A,0x000000A0, 0x00000052,0x0000003B,0x000000D6,0x000000B3,0x00000029,0x000000E3,0x0000002F,0x00000084, 0x00000053,0x000000D1,0x00000000,0x000000ED,0x00000020,0x000000FC,0x000000B1,0x0000005B, 0x0000006A,0x000000CB,0x000000BE,0x00000039,0x0000004A,0x0000004C,0x00000058,0x000000CF, 0x000000D0,0x000000EF,0x000000AA,0x000000FB,0x00000043,0x0000004D,0x00000033,0x00000085, 0x00000045,0x000000F9,0x00000002,0x0000007F,0x00000050,0x0000003C,0x0000009F,0x000000A8, 0x00000051,0x000000A3,0x00000040,0x0000008F,0x00000092,0x0000009D,0x00000038,0x000000F5, 0x000000BC,0x000000B6,0x000000DA,0x00000021,0x00000010,0x000000FF,0x000000F3,0x000000D2, 0x000000CD,0x0000000C,0x00000013,0x000000EC,0x0000005F,0x00000097,0x00000044,0x00000017, 0x000000C4,0x000000A7,0x0000007E,0x0000003D,0x00000064,0x0000005D,0x00000019,0x00000073, 0x00000060,0x00000081,0x0000004F,0x000000DC,0x00000022,0x0000002A,0x00000090,0x00000088, 0x00000046,0x000000EE,0x000000B8,0x00000014,0x000000DE,0x0000005E,0x0000000B,0x000000DB, 0x000000E0,0x00000032,0x0000003A,0x0000000A,0x00000049,0x00000006,0x00000024,0x0000005C, 0x000000C2,0x000000D3,0x000000AC,0x00000062,0x00000091,0x00000095,0x000000E4,0x00000079, 0x000000E7,0x000000C8,0x00000037,0x0000006D,0x0000008D,0x000000D5,0x0000004E,0x000000A9, 0x0000006C,0x00000056,0x000000F4,0x000000EA,0x00000065,0x0000007A,0x000000AE,0x00000008, 0x000000BA,0x00000078,0x00000025,0x0000002E,0x0000001C,0x000000A6,0x000000B4,0x000000C6, 0x000000E8,0x000000DD,0x00000074,0x0000001F,0x0000004B,0x000000BD,0x0000008B,0x0000008A, 0x00000070,0x0000003E,0x000000B5,0x00000066,0x00000048,0x00000003,0x000000F6,0x0000000E, 0x00000061,0x00000035,0x00000057,0x000000B9,0x00000086,0x000000C1,0x0000001D,0x0000009E, 0x000000E1,0x000000F8,0x00000098,0x00000011,0x00000069,0x000000D9,0x0000008E,0x00000094, 0x0000009B,0x0000001E,0x00000087,0x000000E9,0x000000CE,0x00000055,0x00000028,0x000000DF, 0x0000008C,0x000000A1,0x00000089,0x0000000D,0x000000BF,0x000000E6,0x00000042,0x00000068, 0x00000041,0x00000099,0x0000002D,0x0000000F,0x000000B0,0x00000054,0x000000BB,0x00000016 }, { 0x00006300,0x00007C00,0x00007700,0x00007B00,0x0000F200,0x00006B00,0x00006F00,0x0000C500, 0x00003000,0x00000100,0x00006700,0x00002B00,0x0000FE00,0x0000D700,0x0000AB00,0x00007600, 0x0000CA00,0x00008200,0x0000C900,0x00007D00,0x0000FA00,0x00005900,0x00004700,0x0000F000, 0x0000AD00,0x0000D400,0x0000A200,0x0000AF00,0x00009C00,0x0000A400,0x00007200,0x0000C000, 0x0000B700,0x0000FD00,0x00009300,0x00002600,0x00003600,0x00003F00,0x0000F700,0x0000CC00, 0x00003400,0x0000A500,0x0000E500,0x0000F100,0x00007100,0x0000D800,0x00003100,0x00001500, 0x00000400,0x0000C700,0x00002300,0x0000C300,0x00001800,0x00009600,0x00000500,0x00009A00, 0x00000700,0x00001200,0x00008000,0x0000E200,0x0000EB00,0x00002700,0x0000B200,0x00007500, 0x00000900,0x00008300,0x00002C00,0x00001A00,0x00001B00,0x00006E00,0x00005A00,0x0000A000, 0x00005200,0x00003B00,0x0000D600,0x0000B300,0x00002900,0x0000E300,0x00002F00,0x00008400, 0x00005300,0x0000D100,0000000000,0x0000ED00,0x00002000,0x0000FC00,0x0000B100,0x00005B00, 0x00006A00,0x0000CB00,0x0000BE00,0x00003900,0x00004A00,0x00004C00,0x00005800,0x0000CF00, 0x0000D000,0x0000EF00,0x0000AA00,0x0000FB00,0x00004300,0x00004D00,0x00003300,0x00008500, 0x00004500,0x0000F900,0x00000200,0x00007F00,0x00005000,0x00003C00,0x00009F00,0x0000A800, 0x00005100,0x0000A300,0x00004000,0x00008F00,0x00009200,0x00009D00,0x00003800,0x0000F500, 0x0000BC00,0x0000B600,0x0000DA00,0x00002100,0x00001000,0x0000FF00,0x0000F300,0x0000D200, 0x0000CD00,0x00000C00,0x00001300,0x0000EC00,0x00005F00,0x00009700,0x00004400,0x00001700, 0x0000C400,0x0000A700,0x00007E00,0x00003D00,0x00006400,0x00005D00,0x00001900,0x00007300, 0x00006000,0x00008100,0x00004F00,0x0000DC00,0x00002200,0x00002A00,0x00009000,0x00008800, 0x00004600,0x0000EE00,0x0000B800,0x00001400,0x0000DE00,0x00005E00,0x00000B00,0x0000DB00, 0x0000E000,0x00003200,0x00003A00,0x00000A00,0x00004900,0x00000600,0x00002400,0x00005C00, 0x0000C200,0x0000D300,0x0000AC00,0x00006200,0x00009100,0x00009500,0x0000E400,0x00007900, 0x0000E700,0x0000C800,0x00003700,0x00006D00,0x00008D00,0x0000D500,0x00004E00,0x0000A900, 0x00006C00,0x00005600,0x0000F400,0x0000EA00,0x00006500,0x00007A00,0x0000AE00,0x00000800, 0x0000BA00,0x00007800,0x00002500,0x00002E00,0x00001C00,0x0000A600,0x0000B400,0x0000C600, 0x0000E800,0x0000DD00,0x00007400,0x00001F00,0x00004B00,0x0000BD00,0x00008B00,0x00008A00, 0x00007000,0x00003E00,0x0000B500,0x00006600,0x00004800,0x00000300,0x0000F600,0x00000E00, 0x00006100,0x00003500,0x00005700,0x0000B900,0x00008600,0x0000C100,0x00001D00,0x00009E00, 0x0000E100,0x0000F800,0x00009800,0x00001100,0x00006900,0x0000D900,0x00008E00,0x00009400, 0x00009B00,0x00001E00,0x00008700,0x0000E900,0x0000CE00,0x00005500,0x00002800,0x0000DF00, 0x00008C00,0x0000A100,0x00008900,0x00000D00,0x0000BF00,0x0000E600,0x00004200,0x00006800, 0x00004100,0x00009900,0x00002D00,0x00000F00,0x0000B000,0x00005400,0x0000BB00,0x00001600 }, { 0x00630000,0x007C0000,0x00770000,0x007B0000,0x00F20000,0x006B0000,0x006F0000,0x00C50000, 0x00300000,0x00010000,0x00670000,0x002B0000,0x00FE0000,0x00D70000,0x00AB0000,0x00760000, 0x00CA0000,0x00820000,0x00C90000,0x007D0000,0x00FA0000,0x00590000,0x00470000,0x00F00000, 0x00AD0000,0x00D40000,0x00A20000,0x00AF0000,0x009C0000,0x00A40000,0x00720000,0x00C00000, 0x00B70000,0x00FD0000,0x00930000,0x00260000,0x00360000,0x003F0000,0x00F70000,0x00CC0000, 0x00340000,0x00A50000,0x00E50000,0x00F10000,0x00710000,0x00D80000,0x00310000,0x00150000, 0x00040000,0x00C70000,0x00230000,0x00C30000,0x00180000,0x00960000,0x00050000,0x009A0000, 0x00070000,0x00120000,0x00800000,0x00E20000,0x00EB0000,0x00270000,0x00B20000,0x00750000, 0x00090000,0x00830000,0x002C0000,0x001A0000,0x001B0000,0x006E0000,0x005A0000,0x00A00000, 0x00520000,0x003B0000,0x00D60000,0x00B30000,0x00290000,0x00E30000,0x002F0000,0x00840000, 0x00530000,0x00D10000,0000000000,0x00ED0000,0x00200000,0x00FC0000,0x00B10000,0x005B0000, 0x006A0000,0x00CB0000,0x00BE0000,0x00390000,0x004A0000,0x004C0000,0x00580000,0x00CF0000, 0x00D00000,0x00EF0000,0x00AA0000,0x00FB0000,0x00430000,0x004D0000,0x00330000,0x00850000, 0x00450000,0x00F90000,0x00020000,0x007F0000,0x00500000,0x003C0000,0x009F0000,0x00A80000, 0x00510000,0x00A30000,0x00400000,0x008F0000,0x00920000,0x009D0000,0x00380000,0x00F50000, 0x00BC0000,0x00B60000,0x00DA0000,0x00210000,0x00100000,0x00FF0000,0x00F30000,0x00D20000, 0x00CD0000,0x000C0000,0x00130000,0x00EC0000,0x005F0000,0x00970000,0x00440000,0x00170000, 0x00C40000,0x00A70000,0x007E0000,0x003D0000,0x00640000,0x005D0000,0x00190000,0x00730000, 0x00600000,0x00810000,0x004F0000,0x00DC0000,0x00220000,0x002A0000,0x00900000,0x00880000, 0x00460000,0x00EE0000,0x00B80000,0x00140000,0x00DE0000,0x005E0000,0x000B0000,0x00DB0000, 0x00E00000,0x00320000,0x003A0000,0x000A0000,0x00490000,0x00060000,0x00240000,0x005C0000, 0x00C20000,0x00D30000,0x00AC0000,0x00620000,0x00910000,0x00950000,0x00E40000,0x00790000, 0x00E70000,0x00C80000,0x00370000,0x006D0000,0x008D0000,0x00D50000,0x004E0000,0x00A90000, 0x006C0000,0x00560000,0x00F40000,0x00EA0000,0x00650000,0x007A0000,0x00AE0000,0x00080000, 0x00BA0000,0x00780000,0x00250000,0x002E0000,0x001C0000,0x00A60000,0x00B40000,0x00C60000, 0x00E80000,0x00DD0000,0x00740000,0x001F0000,0x004B0000,0x00BD0000,0x008B0000,0x008A0000, 0x00700000,0x003E0000,0x00B50000,0x00660000,0x00480000,0x00030000,0x00F60000,0x000E0000, 0x00610000,0x00350000,0x00570000,0x00B90000,0x00860000,0x00C10000,0x001D0000,0x009E0000, 0x00E10000,0x00F80000,0x00980000,0x00110000,0x00690000,0x00D90000,0x008E0000,0x00940000, 0x009B0000,0x001E0000,0x00870000,0x00E90000,0x00CE0000,0x00550000,0x00280000,0x00DF0000, 0x008C0000,0x00A10000,0x00890000,0x000D0000,0x00BF0000,0x00E60000,0x00420000,0x00680000, 0x00410000,0x00990000,0x002D0000,0x000F0000,0x00B00000,0x00540000,0x00BB0000,0x00160000 }, { 0x63000000,0x7C000000,0x77000000,0x7B000000,0xF2000000,0x6B000000,0x6F000000,0xC5000000, 0x30000000,0x01000000,0x67000000,0x2B000000,0xFE000000,0xD7000000,0xAB000000,0x76000000, 0xCA000000,0x82000000,0xC9000000,0x7D000000,0xFA000000,0x59000000,0x47000000,0xF0000000, 0xAD000000,0xD4000000,0xA2000000,0xAF000000,0x9C000000,0xA4000000,0x72000000,0xC0000000, 0xB7000000,0xFD000000,0x93000000,0x26000000,0x36000000,0x3F000000,0xF7000000,0xCC000000, 0x34000000,0xA5000000,0xE5000000,0xF1000000,0x71000000,0xD8000000,0x31000000,0x15000000, 0x04000000,0xC7000000,0x23000000,0xC3000000,0x18000000,0x96000000,0x05000000,0x9A000000, 0x07000000,0x12000000,0x80000000,0xE2000000,0xEB000000,0x27000000,0xB2000000,0x75000000, 0x09000000,0x83000000,0x2C000000,0x1A000000,0x1B000000,0x6E000000,0x5A000000,0xA0000000, 0x52000000,0x3B000000,0xD6000000,0xB3000000,0x29000000,0xE3000000,0x2F000000,0x84000000, 0x53000000,0xD1000000,0000000000,0xED000000,0x20000000,0xFC000000,0xB1000000,0x5B000000, 0x6A000000,0xCB000000,0xBE000000,0x39000000,0x4A000000,0x4C000000,0x58000000,0xCF000000, 0xD0000000,0xEF000000,0xAA000000,0xFB000000,0x43000000,0x4D000000,0x33000000,0x85000000, 0x45000000,0xF9000000,0x02000000,0x7F000000,0x50000000,0x3C000000,0x9F000000,0xA8000000, 0x51000000,0xA3000000,0x40000000,0x8F000000,0x92000000,0x9D000000,0x38000000,0xF5000000, 0xBC000000,0xB6000000,0xDA000000,0x21000000,0x10000000,0xFF000000,0xF3000000,0xD2000000, 0xCD000000,0x0C000000,0x13000000,0xEC000000,0x5F000000,0x97000000,0x44000000,0x17000000, 0xC4000000,0xA7000000,0x7E000000,0x3D000000,0x64000000,0x5D000000,0x19000000,0x73000000, 0x60000000,0x81000000,0x4F000000,0xDC000000,0x22000000,0x2A000000,0x90000000,0x88000000, 0x46000000,0xEE000000,0xB8000000,0x14000000,0xDE000000,0x5E000000,0x0B000000,0xDB000000, 0xE0000000,0x32000000,0x3A000000,0x0A000000,0x49000000,0x06000000,0x24000000,0x5C000000, 0xC2000000,0xD3000000,0xAC000000,0x62000000,0x91000000,0x95000000,0xE4000000,0x79000000, 0xE7000000,0xC8000000,0x37000000,0x6D000000,0x8D000000,0xD5000000,0x4E000000,0xA9000000, 0x6C000000,0x56000000,0xF4000000,0xEA000000,0x65000000,0x7A000000,0xAE000000,0x08000000, 0xBA000000,0x78000000,0x25000000,0x2E000000,0x1C000000,0xA6000000,0xB4000000,0xC6000000, 0xE8000000,0xDD000000,0x74000000,0x1F000000,0x4B000000,0xBD000000,0x8B000000,0x8A000000, 0x70000000,0x3E000000,0xB5000000,0x66000000,0x48000000,0x03000000,0xF6000000,0x0E000000, 0x61000000,0x35000000,0x57000000,0xB9000000,0x86000000,0xC1000000,0x1D000000,0x9E000000, 0xE1000000,0xF8000000,0x98000000,0x11000000,0x69000000,0xD9000000,0x8E000000,0x94000000, 0x9B000000,0x1E000000,0x87000000,0xE9000000,0xCE000000,0x55000000,0x28000000,0xDF000000, 0x8C000000,0xA1000000,0x89000000,0x0D000000,0xBF000000,0xE6000000,0x42000000,0x68000000, 0x41000000,0x99000000,0x2D000000,0x0F000000,0xB0000000,0x54000000,0xBB000000,0x16000000 } }; /*----------------- The workspace ------------------------------*/ static u32 Ekey[44]; /* The expanded key */ /*------ The round Function. 4 table lookups and 4 Exors ------*/ #define f_rnd(x, n) \ ( ft_tab[0][byte0(x[n])] \ ^ ft_tab[1][byte1(x[(n + 1) & 3])] \ ^ ft_tab[2][byte2(x[(n + 2) & 3])] \ ^ ft_tab[3][byte3(x[(n + 3) & 3])] ) #define f_round(bo, bi, k) \ bo[0] = f_rnd(bi, 0) ^ k[0]; \ bo[1] = f_rnd(bi, 1) ^ k[1]; \ bo[2] = f_rnd(bi, 2) ^ k[2]; \ bo[3] = f_rnd(bi, 3) ^ k[3]; \ k += 4 /*--- The S Box lookup used in constructing the Key schedule ---*/ #define ls_box(x) \ ( fl_tab[0][byte0(x)] \ ^ fl_tab[1][byte1(x)] \ ^ fl_tab[2][byte2(x)] \ ^ fl_tab[3][byte3(x)] ) /*------------ The last round function (no MixColumn) ----------*/ #define lf_rnd(x, n) \ ( fl_tab[0][byte0(x[n])] \ ^ fl_tab[1][byte1(x[(n + 1) & 3])] \ ^ fl_tab[2][byte2(x[(n + 2) & 3])] \ ^ fl_tab[3][byte3(x[(n + 3) & 3])] ) /*----------------------------------------------------------- * RijndaelKeySchedule * Initialise the key schedule from a supplied key */ void RijndaelKeySchedule(u8 key[16]) { u32 t; u32 *ek=Ekey, /* pointer to the expanded key */ *rc=rnd_con; /* pointer to the round constant */ Ekey[0] = u32_in(key ); Ekey[1] = u32_in(key + 4); Ekey[2] = u32_in(key + 8); Ekey[3] = u32_in(key + 12); while(ek < Ekey + 40) { t = rot3(ek[3]); ek[4] = ek[0] ^ ls_box(t) ^ *rc++; ek[5] = ek[1] ^ ek[4]; ek[6] = ek[2] ^ ek[5]; ek[7] = ek[3] ^ ek[6]; ek += 4; } } /*----------------------------------------------------------- * RijndaelEncrypt * Encrypt an input block */ void RijndaelEncrypt(u8 in[16], u8 out[16]) { u32 b0[4], b1[4], *kp = Ekey; b0[0] = u32_in(in ) ^ *kp++; b0[1] = u32_in(in + 4) ^ *kp++; b0[2] = u32_in(in + 8) ^ *kp++; b0[3] = u32_in(in + 12) ^ *kp++; f_round(b1, b0, kp); f_round(b0, b1, kp); f_round(b1, b0, kp); f_round(b0, b1, kp); f_round(b1, b0, kp); f_round(b0, b1, kp); f_round(b1, b0, kp); f_round(b0, b1, kp); f_round(b1, b0, kp); u32_out(out, lf_rnd(b1, 0) ^ kp[0]); u32_out(out + 4, lf_rnd(b1, 1) ^ kp[1]); u32_out(out + 8, lf_rnd(b1, 2) ^ kp[2]); u32_out(out + 12, lf_rnd(b1, 3) ^ kp[3]); } twinkle-1.4.2/src/parser/request.h0000644000175000001440000001734711127714050014046 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Request #ifndef _REQUEST_H #define _REQUEST_H #include #include "response.h" #include "sip_message.h" #include "sockets/url.h" #include "user.h" // Forward declaration class t_user; using namespace std; class t_request : public t_sip_message { private: /** * A DNS lookup on the request URI (or outbound proxy) might resolve * into multiple destinations. @ref get_destination() will return the first * destination. All destinations are stored here. * @ref next_destination() will remove the first destination of this * list. */ list destinations; /** * Indicates if the destination specified a transport, i.e. via the * transport parameter in a URI. */ bool transport_specified; /** * Add destinations for a given URI based on transport settings. * @param user_profile [in] User profile * @param dst_uri [in] The URI to resolve. */ void add_destinations(const t_user &user_profile, const t_url &dst_uri); /** * Calculate credentials based on the challenge. * @param chlg [in] The challenge * @param user_config [in] User configuration for user to be authorized. * @param username [in] User authentication name * @param passwd [in] Authentication password. * @param nc [in] Nonce count * @param cnonce [in] Client nonce * @param cr [out] Credentials on succesful return. * @param fail_reason [out] Failure reason on failure return. * @return false, if authorization fails. * @return true, if authorization succeeded */ bool authorize(const t_challenge &chlg, t_user *user_config, const string &username, const string &passwd, unsigned long nc, const string &cnonce, t_credentials &cr, string &fail_reason) const; /** * Calculate MD5 response based on the challenge. * @param chlg [in] The challenge * @param username [in] User authentication name * @param passwd [in] Authentication password. * @param nc [in] Nonce count * @param cnonce [in] Client nonce * @param qop [in] Quality of protection * @param resp [out] Response on succesful return. * @param fail_reason [out] Failure reason on failure return. * @return false, if authorization fails. * @return true, if authorization succeeded */ bool authorize_md5(const t_digest_challenge &dchlg, const string &username, const string &passwd, unsigned long nc, const string &cnonce, const string &qop, string &resp, string &fail_reason) const; /** * Calculate AKAv1-MD5 response based on the challenge. * @param chlg [in] The challenge * @param username [in] User authentication name * @param passwd [in] Authentication password. * @param op [in] Operator variant key * @param amf [in] Authentication method field * @param nc [in] Nonce count * @param cnonce [in] Client nonce * @param qop [in] Quality of protection * @param resp [out] Response on succesful return. * @param fail_reason [out] Failure reason on failure return. * @return false, if authorization fails. * @return true, if authorization succeeded */ bool authorize_akav1_md5(const t_digest_challenge &dchlg, const string &username, const string &passwd, uint8 *op, uint8 *amf, unsigned long nc, const string &cnonce, const string &qop, string &resp, string &fail_reason) const; public: t_url uri; t_method method; string unknown_method; // set if method is UNKNOWN t_request(); t_request(const t_request &r); t_request(const t_method m); t_msg_type get_type(void) const { return MSG_REQUEST; } void set_method(const string &s); string encode(bool add_content_length = true); list encode_env(void); t_sip_message *copy(void) const; /** * Set the Request-URI and the Route header. * This is done according to the procedures of RFC 3261 12.2.1.1 * @param target_uri [in] The URI of the destination for this request. * @param route_set [in] The route set for this request (may be empty). */ void set_route(const t_url &target_uri, const list &route_set); // Create a response with response code based on the // request. The response is created following the general // rules in RFC 3261 8.2.6.2. // The to-hdr is simply copied from the request to the // response. // If the to-tag is missing, then // a to-tag will be generated and added to the to-header // of the response. // A specific reason may be added to the status code. t_response *create_response(int code, string reason = "") const; bool is_valid(bool &fatal, string &reason) const; // Calculate the set of possible destinations for this request. void calc_destinations(const t_user &user_profile); // Get destination to send this request to. void get_destination(t_ip_port &ip_port, const t_user &user_profile); void get_current_destination(t_ip_port &ip_port); // Move to next destination. This method should only be called after // calc_destination() was called. // Returns true if there is a next destination, otherwise returns false. bool next_destination(void); // Set a single destination to send this request to. void set_destination(const t_ip_port &ip_port); /** * Create WWW authorization credentials based on the challenge. * @param chlg [in] The challenge * @param user_config [in] User configuration for user to be authorized. * @param username [in] User authentication name * @param passwd [in] Authentication password. * @param nc [in] Nonce count * @param cnonce [in] Client nonce * @param cr [out] Credentials on succesful return. * @param fail_reason [out] Failure reason on failure return. * @return false, if challenge is not supported. * @return true, if authorization succeeded */ bool www_authorize(const t_challenge &chlg, t_user *user_config, const string &username, const string &passwd, unsigned long nc, const string &cnonce, t_credentials &cr, string &fail_reason); /** * Create proxy authorization credentials based on the challenge. * @param chlg [in] The challenge * @param user_config [in] User configuration for user to be authorized. * @param username [in] User authentication name * @param passwd [in] Authentication password. * @param nc [in] Nonce count * @param cnonce [in] Client nonce * @param cr [out] Credentials on succesful return. * @param fail_reason [out] Failure reason on failure return. * @return false, if challenge is not supported. * @return true, if authorization succeeded */ bool proxy_authorize(const t_challenge &chlg, t_user *user_config, const string &username, const string &passwd, unsigned long nc, const string &cnonce, t_credentials &cr, string &fail_reason); virtual void calc_local_ip(void); /** * Check if the request is a registration request. * @return True if the request is a registration request, otherwise false. */ bool is_registration_request(void) const; /** * Check if the request is a de-registration request. * @return True if the request is a de-registration request, otherwise false. */ bool is_de_registration_request(void) const; }; #endif twinkle-1.4.2/src/parser/Makefile.am0000644000175000001440000001200511142400501014211 00000000000000AM_CPPFLAGS = -Wall $(XML2_CFLAGS) -I$(top_srcdir)/src # bison flags AM_YFLAGS = -d # flex flags # The -s flag is not used on purpose. As it is better to have # some unmatched symbols echoed to stdout then a jammed flex # causing the process to die. AM_LFLAGS = -i # The output of bison cannot be compiled with the -O2 flag. # With the -O2 flag g++ crashes. The -O2 flag is stripped from # CXXFLAGS by configure. # rumen: # Above don't work. # It is enought to drop -funit-at-a-time set when -O2 flag is set. # The error is: # "cc1plus: out of memory allocating 336746144 bytes after a total of 10846208 bytes." # Note user can specify -O2 in CXXFLAGS at configure time ! # Also note that unit-at-a-time if new for gcc 3.4 ! # See http://lists.debian.org/debian-gcc/2006/07/msg00281.html # that claim to be fixed in gcc-4.1+ . AM_CXXFLAGS = -fno-unit-at-a-time # This target is only for testing the parser in isolation #noinst_PROGRAMS = sipparse # #sipparse_SOURCES = main.cpp # #sipparse_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/parser/libsipparser.a\ # $(top_builddir)/src/sdp/libsdpparser.a\ # $(top_builddir)/src/sockets/libsocket.a\ # -lresolv noinst_LIBRARIES = libsipparser.a libsipparser_a_SOURCES =\ challenge.cpp\ coding.cpp\ credentials.cpp\ definitions.cpp\ hdr_accept.cpp\ hdr_accept_encoding.cpp\ hdr_accept_language.cpp\ hdr_alert_info.cpp\ hdr_allow.cpp\ hdr_allow_events.cpp\ hdr_auth_info.cpp\ hdr_authorization.cpp\ hdr_call_id.cpp\ hdr_call_info.cpp\ hdr_contact.cpp\ hdr_content_disp.cpp\ hdr_content_encoding.cpp\ hdr_content_language.cpp\ hdr_content_length.cpp\ hdr_content_type.cpp\ hdr_cseq.cpp\ hdr_date.cpp\ hdr_error_info.cpp\ hdr_event.cpp\ hdr_expires.cpp\ hdr_from.cpp\ hdr_in_reply_to.cpp\ hdr_max_forwards.cpp\ hdr_min_expires.cpp\ hdr_mime_version.cpp\ hdr_organization.cpp\ hdr_priority.cpp\ hdr_privacy.cpp\ hdr_p_asserted_identity.cpp\ hdr_p_preferred_identity.cpp\ hdr_proxy_authenticate.cpp\ hdr_proxy_authorization.cpp\ hdr_proxy_require.cpp\ hdr_rack.cpp\ hdr_record_route.cpp\ hdr_refer_sub.cpp\ hdr_refer_to.cpp\ hdr_referred_by.cpp\ hdr_replaces.cpp\ hdr_reply_to.cpp\ hdr_require.cpp\ hdr_request_disposition.cpp\ hdr_retry_after.cpp\ hdr_route.cpp\ hdr_rseq.cpp\ hdr_server.cpp\ hdr_service_route.cpp\ hdr_sip_etag.cpp\ hdr_sip_if_match.cpp\ hdr_subject.cpp\ hdr_subscription_state.cpp\ hdr_supported.cpp\ hdr_timestamp.cpp\ hdr_to.cpp\ hdr_unsupported.cpp\ hdr_user_agent.cpp\ hdr_via.cpp\ hdr_warning.cpp\ hdr_www_authenticate.cpp\ header.cpp\ identity.cpp\ media_type.cpp\ milenage.cpp\ parameter.cpp\ parse_ctrl.cpp\ parser.yxx\ request.cpp\ response.cpp\ rijndael.cpp\ route.cpp\ scanner.lxx\ sip_body.cpp\ sip_message.cpp\ challenge.h\ coding.h\ credentials.h\ definitions.h\ hdr_accept.h\ hdr_accept_encoding.h\ hdr_accept_language.h\ hdr_alert_info.h\ hdr_allow.h\ hdr_allow_events.h\ hdr_auth_info.h\ hdr_authorization.h\ hdr_call_id.h\ hdr_call_info.h\ hdr_contact.h\ hdr_content_disp.h\ hdr_content_encoding.h\ hdr_content_language.h\ hdr_content_length.h\ hdr_content_type.h\ hdr_cseq.h\ hdr_date.h\ hdr_error_info.h\ hdr_event.h\ hdr_expires.h\ hdr_from.h\ hdr_in_reply_to.h\ hdr_max_forwards.h\ hdr_min_expires.h\ hdr_mime_version.h\ hdr_organization.h\ hdr_p_asserted_identity.h\ hdr_p_preferred_identity.h\ hdr_priority.h\ hdr_privacy.h\ hdr_proxy_authenticate.h\ hdr_proxy_authorization.h\ hdr_proxy_require.h\ hdr_rack.h\ hdr_record_route.h\ hdr_refer_sub.h\ hdr_refer_to.h\ hdr_referred_by.h\ hdr_replaces.h\ hdr_reply_to.h\ hdr_require.h\ hdr_request_disposition.h\ hdr_retry_after.h\ hdr_route.h\ hdr_rseq.h\ hdr_server.h\ hdr_service_route.h\ hdr_sip_etag.h\ hdr_sip_if_match.h\ hdr_subject.h\ hdr_subscription_state.h\ hdr_supported.h\ hdr_timestamp.h\ hdr_to.h\ hdr_unsupported.h\ hdr_user_agent.h\ hdr_via.h\ hdr_warning.h\ hdr_www_authenticate.h\ header.h\ identity.h\ media_type.h\ milenage.h\ parameter.h\ parse_ctrl.h\ request.h\ response.h\ rijndael.h\ route.h\ sip_body.h\ sip_message.h twinkle-1.4.2/src/parser/Makefile.in0000644000175000001440000007407311151323407014250 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/parser DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in parser.cxx \ parser.h scanner.cxx ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libsipparser_a_AR = $(AR) $(ARFLAGS) libsipparser_a_LIBADD = am_libsipparser_a_OBJECTS = challenge.$(OBJEXT) coding.$(OBJEXT) \ credentials.$(OBJEXT) definitions.$(OBJEXT) \ hdr_accept.$(OBJEXT) hdr_accept_encoding.$(OBJEXT) \ hdr_accept_language.$(OBJEXT) hdr_alert_info.$(OBJEXT) \ hdr_allow.$(OBJEXT) hdr_allow_events.$(OBJEXT) \ hdr_auth_info.$(OBJEXT) hdr_authorization.$(OBJEXT) \ hdr_call_id.$(OBJEXT) hdr_call_info.$(OBJEXT) \ hdr_contact.$(OBJEXT) hdr_content_disp.$(OBJEXT) \ hdr_content_encoding.$(OBJEXT) hdr_content_language.$(OBJEXT) \ hdr_content_length.$(OBJEXT) hdr_content_type.$(OBJEXT) \ hdr_cseq.$(OBJEXT) hdr_date.$(OBJEXT) hdr_error_info.$(OBJEXT) \ hdr_event.$(OBJEXT) hdr_expires.$(OBJEXT) hdr_from.$(OBJEXT) \ hdr_in_reply_to.$(OBJEXT) hdr_max_forwards.$(OBJEXT) \ hdr_min_expires.$(OBJEXT) hdr_mime_version.$(OBJEXT) \ hdr_organization.$(OBJEXT) hdr_priority.$(OBJEXT) \ hdr_privacy.$(OBJEXT) hdr_p_asserted_identity.$(OBJEXT) \ hdr_p_preferred_identity.$(OBJEXT) \ hdr_proxy_authenticate.$(OBJEXT) \ hdr_proxy_authorization.$(OBJEXT) hdr_proxy_require.$(OBJEXT) \ hdr_rack.$(OBJEXT) hdr_record_route.$(OBJEXT) \ hdr_refer_sub.$(OBJEXT) hdr_refer_to.$(OBJEXT) \ hdr_referred_by.$(OBJEXT) hdr_replaces.$(OBJEXT) \ hdr_reply_to.$(OBJEXT) hdr_require.$(OBJEXT) \ hdr_request_disposition.$(OBJEXT) hdr_retry_after.$(OBJEXT) \ hdr_route.$(OBJEXT) hdr_rseq.$(OBJEXT) hdr_server.$(OBJEXT) \ hdr_service_route.$(OBJEXT) hdr_sip_etag.$(OBJEXT) \ hdr_sip_if_match.$(OBJEXT) hdr_subject.$(OBJEXT) \ hdr_subscription_state.$(OBJEXT) hdr_supported.$(OBJEXT) \ hdr_timestamp.$(OBJEXT) hdr_to.$(OBJEXT) \ hdr_unsupported.$(OBJEXT) hdr_user_agent.$(OBJEXT) \ hdr_via.$(OBJEXT) hdr_warning.$(OBJEXT) \ hdr_www_authenticate.$(OBJEXT) header.$(OBJEXT) \ identity.$(OBJEXT) media_type.$(OBJEXT) milenage.$(OBJEXT) \ parameter.$(OBJEXT) parse_ctrl.$(OBJEXT) parser.$(OBJEXT) \ request.$(OBJEXT) response.$(OBJEXT) rijndael.$(OBJEXT) \ route.$(OBJEXT) scanner.$(OBJEXT) sip_body.$(OBJEXT) \ sip_message.$(OBJEXT) libsipparser_a_OBJECTS = $(am_libsipparser_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libsipparser_a_SOURCES) DIST_SOURCES = $(libsipparser_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = -Wall $(XML2_CFLAGS) -I$(top_srcdir)/src # bison flags AM_YFLAGS = -d # flex flags # The -s flag is not used on purpose. As it is better to have # some unmatched symbols echoed to stdout then a jammed flex # causing the process to die. AM_LFLAGS = -i # The output of bison cannot be compiled with the -O2 flag. # With the -O2 flag g++ crashes. The -O2 flag is stripped from # CXXFLAGS by configure. # rumen: # Above don't work. # It is enought to drop -funit-at-a-time set when -O2 flag is set. # The error is: # "cc1plus: out of memory allocating 336746144 bytes after a total of 10846208 bytes." # Note user can specify -O2 in CXXFLAGS at configure time ! # Also note that unit-at-a-time if new for gcc 3.4 ! # See http://lists.debian.org/debian-gcc/2006/07/msg00281.html # that claim to be fixed in gcc-4.1+ . AM_CXXFLAGS = -fno-unit-at-a-time # This target is only for testing the parser in isolation #noinst_PROGRAMS = sipparse # #sipparse_SOURCES = main.cpp # #sipparse_LDADD = $(top_builddir)/src/util.o\ # $(top_builddir)/src/parser/libsipparser.a\ # $(top_builddir)/src/sdp/libsdpparser.a\ # $(top_builddir)/src/sockets/libsocket.a\ # -lresolv noinst_LIBRARIES = libsipparser.a libsipparser_a_SOURCES = \ challenge.cpp\ coding.cpp\ credentials.cpp\ definitions.cpp\ hdr_accept.cpp\ hdr_accept_encoding.cpp\ hdr_accept_language.cpp\ hdr_alert_info.cpp\ hdr_allow.cpp\ hdr_allow_events.cpp\ hdr_auth_info.cpp\ hdr_authorization.cpp\ hdr_call_id.cpp\ hdr_call_info.cpp\ hdr_contact.cpp\ hdr_content_disp.cpp\ hdr_content_encoding.cpp\ hdr_content_language.cpp\ hdr_content_length.cpp\ hdr_content_type.cpp\ hdr_cseq.cpp\ hdr_date.cpp\ hdr_error_info.cpp\ hdr_event.cpp\ hdr_expires.cpp\ hdr_from.cpp\ hdr_in_reply_to.cpp\ hdr_max_forwards.cpp\ hdr_min_expires.cpp\ hdr_mime_version.cpp\ hdr_organization.cpp\ hdr_priority.cpp\ hdr_privacy.cpp\ hdr_p_asserted_identity.cpp\ hdr_p_preferred_identity.cpp\ hdr_proxy_authenticate.cpp\ hdr_proxy_authorization.cpp\ hdr_proxy_require.cpp\ hdr_rack.cpp\ hdr_record_route.cpp\ hdr_refer_sub.cpp\ hdr_refer_to.cpp\ hdr_referred_by.cpp\ hdr_replaces.cpp\ hdr_reply_to.cpp\ hdr_require.cpp\ hdr_request_disposition.cpp\ hdr_retry_after.cpp\ hdr_route.cpp\ hdr_rseq.cpp\ hdr_server.cpp\ hdr_service_route.cpp\ hdr_sip_etag.cpp\ hdr_sip_if_match.cpp\ hdr_subject.cpp\ hdr_subscription_state.cpp\ hdr_supported.cpp\ hdr_timestamp.cpp\ hdr_to.cpp\ hdr_unsupported.cpp\ hdr_user_agent.cpp\ hdr_via.cpp\ hdr_warning.cpp\ hdr_www_authenticate.cpp\ header.cpp\ identity.cpp\ media_type.cpp\ milenage.cpp\ parameter.cpp\ parse_ctrl.cpp\ parser.yxx\ request.cpp\ response.cpp\ rijndael.cpp\ route.cpp\ scanner.lxx\ sip_body.cpp\ sip_message.cpp\ challenge.h\ coding.h\ credentials.h\ definitions.h\ hdr_accept.h\ hdr_accept_encoding.h\ hdr_accept_language.h\ hdr_alert_info.h\ hdr_allow.h\ hdr_allow_events.h\ hdr_auth_info.h\ hdr_authorization.h\ hdr_call_id.h\ hdr_call_info.h\ hdr_contact.h\ hdr_content_disp.h\ hdr_content_encoding.h\ hdr_content_language.h\ hdr_content_length.h\ hdr_content_type.h\ hdr_cseq.h\ hdr_date.h\ hdr_error_info.h\ hdr_event.h\ hdr_expires.h\ hdr_from.h\ hdr_in_reply_to.h\ hdr_max_forwards.h\ hdr_min_expires.h\ hdr_mime_version.h\ hdr_organization.h\ hdr_p_asserted_identity.h\ hdr_p_preferred_identity.h\ hdr_priority.h\ hdr_privacy.h\ hdr_proxy_authenticate.h\ hdr_proxy_authorization.h\ hdr_proxy_require.h\ hdr_rack.h\ hdr_record_route.h\ hdr_refer_sub.h\ hdr_refer_to.h\ hdr_referred_by.h\ hdr_replaces.h\ hdr_reply_to.h\ hdr_require.h\ hdr_request_disposition.h\ hdr_retry_after.h\ hdr_route.h\ hdr_rseq.h\ hdr_server.h\ hdr_service_route.h\ hdr_sip_etag.h\ hdr_sip_if_match.h\ hdr_subject.h\ hdr_subscription_state.h\ hdr_supported.h\ hdr_timestamp.h\ hdr_to.h\ hdr_unsupported.h\ hdr_user_agent.h\ hdr_via.h\ hdr_warning.h\ hdr_www_authenticate.h\ header.h\ identity.h\ media_type.h\ milenage.h\ parameter.h\ parse_ctrl.h\ request.h\ response.h\ rijndael.h\ route.h\ sip_body.h\ sip_message.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .cxx .lxx .o .obj .yxx $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/parser/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/parser/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) parser.h: parser.cxx @if test ! -f $@; then \ rm -f parser.cxx; \ $(MAKE) parser.cxx; \ else :; fi libsipparser.a: $(libsipparser_a_OBJECTS) $(libsipparser_a_DEPENDENCIES) -rm -f libsipparser.a $(libsipparser_a_AR) libsipparser.a $(libsipparser_a_OBJECTS) $(libsipparser_a_LIBADD) $(RANLIB) libsipparser.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/challenge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/credentials.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/definitions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_accept.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_accept_encoding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_accept_language.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_alert_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_allow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_allow_events.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_auth_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_authorization.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_call_id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_call_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_contact.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_content_disp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_content_encoding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_content_language.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_content_length.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_content_type.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_cseq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_date.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_error_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_expires.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_from.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_in_reply_to.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_max_forwards.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_mime_version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_min_expires.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_organization.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_p_asserted_identity.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_p_preferred_identity.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_priority.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_privacy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_proxy_authenticate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_proxy_authorization.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_proxy_require.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_rack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_record_route.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_refer_sub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_refer_to.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_referred_by.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_replaces.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_reply_to.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_request_disposition.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_require.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_retry_after.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_route.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_rseq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_service_route.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_sip_etag.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_sip_if_match.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_subject.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_subscription_state.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_supported.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_timestamp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_to.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_unsupported.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_user_agent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_via.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_warning.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdr_www_authenticate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/header.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identity.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/media_type.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/milenage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parameter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_ctrl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/response.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_body.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sip_message.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .lxx.cxx: $(LEXCOMPILE) $< sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@ rm -f $(LEX_OUTPUT_ROOT).c .yxx.cxx: $(YACCCOMPILE) $< if test -f y.tab.h; then \ to=`echo "$*_H" | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \ sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \ y.tab.h >$*.ht; \ rm -f y.tab.h; \ if cmp -s $*.ht $*.h; then \ rm -f $*.ht ;\ else \ mv $*.ht $*.h; \ fi; \ fi if test -f y.output; then \ mv y.output $*.output; \ fi sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@ rm -f y.tab.c uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f parser.cxx -rm -f parser.h -rm -f scanner.cxx clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/parser/hdr_server.h0000644000175000001440000000260711127714050014512 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Server header #ifndef _H_HDR_SERVER #define _H_HDR_SERVER #include #include #include "header.h" using namespace std; class t_server { public: string product; string version; string comment; t_server(); t_server(const string &_product, const string &_version, const string &_comment = ""); string encode(void) const; }; class t_hdr_server : public t_header { public: list server_info; t_hdr_server(); void add_server(const t_server &s); // Get a string representation of server_info string get_server_info(void) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/challenge.h0000644000175000001440000000333211127714050014265 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Challenges are used in Proxy-Authenticate and // WWW-Authenticate headers #ifndef _CHALLENGE_H #define _CHALLENGE_H #include #include #include "parameter.h" #include "sockets/url.h" using namespace std; class t_digest_challenge { public: string realm; list domain; string nonce; string opaque; bool stale; string algorithm; list qop_options; list auth_params; t_digest_challenge(); // Set one of the attributes to a value. The parameter p // indicated wich attribute (p.name) should be set to // which value (p.value). // Returns false if p does not contain a valid attribute // setting. bool set_attr(const t_parameter &p); string encode(void) const; }; class t_challenge { public: string auth_scheme; t_digest_challenge digest_challenge; // auth_params is used when auth_scheme is not Digest. list auth_params; string encode(void) const; }; #endif twinkle-1.4.2/src/parser/rijndael.h0000644000175000001440000000160211127714050014131 00000000000000/*------------------------------------------------------------------- * Example algorithms f1, f1*, f2, f3, f4, f5, f5* *------------------------------------------------------------------- * * A sample implementation of the example 3GPP authentication and * key agreement functions f1, f1*, f2, f3, f4, f5 and f5*. This is * a byte-oriented implementation of the functions, and of the block * cipher kernel function Rijndael. * * This has been coded for clarity, not necessarily for efficiency. * * The functions f2, f3, f4 and f5 share the same inputs and have * been coded together as a single function. f1, f1* and f5* are * all coded separately. * *-----------------------------------------------------------------*/ #ifndef RIJNDAEL_H #define RIJNDAEL_H void RijndaelKeySchedule( u8 key[16] ); void RijndaelEncrypt( u8 input[16], u8 output[16] ); #endif twinkle-1.4.2/src/parser/request.cpp0000644000175000001440000004660211134633523014400 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "request.h" #include "util.h" #include "parse_ctrl.h" #include "protocol.h" #include "milenage.h" #include "audits/memman.h" #include #include using namespace ost; // AKAv1-MD5 algorithm specific helpers #define B64_ENC_SZ(x) (4 * ((x + 2) / 3)) #define B64_DEC_SZ(x) (3 * ((x + 3) / 4)) int b64_enc(const u8 * src, u8 * dst, int len) { static char tbl[64] = { 'A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X', 'Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n', 'o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3', '4','5','6','7','8','9','+','/' }; u8 * dst0 = dst; int i, v, div = len / 3, mod = len % 3; for (i = 0; i < div * 3; i += 3) { v = (src[i+0] & 0xfc) >> 2; *(dst++) = tbl[v]; v = (src[i+0] & 0x03) << 4; v |= (src[i+1] & 0xf0) >> 4; *(dst++) = tbl[v]; v = (src[i+1] & 0x0f) << 2; v |= (src[i+2] & 0xc0) >> 6; *(dst++) = tbl[v]; v = src[i+2] & 0x3f; *(dst++) = tbl[v]; } if (mod == 1) { v = (src[i+0] & 0xfc) >> 2; *(dst++) = tbl[v]; v = (src[i+0] & 0x03) << 4; *(dst++) = tbl[v]; *(dst++) = '='; *(dst++) = '='; } else if (mod == 2) { v = (src[i+0] & 0xfc) >> 2; *(dst++) = tbl[v]; v = (src[i+0] & 0x03) << 4; v |= (src[i+1] & 0xf0) >> 4; *(dst++) = tbl[v]; v = (src[i+1] & 0x0f) << 2; *(dst++) = tbl[v]; *(dst++) = '='; } return dst - dst0; } static int b64_val(u8 x) { if (x >= 'A' && x <= 'Z') return x - 'A'; else if (x >= 'a' && x <= 'z') return x - 'a' + 26; else if (x >= '0' && x <= '9') return x - '0' + 52; else if (x == '+') return 62; else if (x == '/') return 63; //else if (x == '=') return -1; } int b64_dec(const u8 * src, u8 * dst, int len) { u8 * dst0 = dst; int i, x1, x2, x3, x4; if (len % 4) return 0; for (i=0; i+4 < len; i += 4) { x1 = b64_val(*(src++)); x2 = b64_val(*(src++)); x3 = b64_val(*(src++)); x4 = b64_val(*(src++)); *(dst++) = (x1 << 2) | ((x2 & 0x30) >> 4); *(dst++) = ((x2 & 0x0F) << 4) | ((x3 & 0x3C) >> 2); *(dst++) = ((x3 & 0x03) << 6) | (x4 & 0x3F); } if (len) { x1 = b64_val(*(src++)); x2 = b64_val(*(src++)); x3 = b64_val(*(src++)); x4 = b64_val(*(src++)); *(dst++) = (x1 << 2) | ((x2 & 0x30) >> 4); if (x3 != -1) { *(dst++) = ((x2 & 0x0F) << 4) | ((x3 & 0x3C) >> 2); if (x4 != -1) *(dst++) = ((x3 & 0x03) << 6) | (x4 & 0x3F); } } return dst - dst0; } #define HASH_HEX_LEN 32 #define HASH_LEN 16 // authentication with AKAv1-MD5 algorithm (RFC 3310) bool t_request::authorize_akav1_md5(const t_digest_challenge &dchlg, const string &username, const string &passwd, uint8 *op, uint8 *amf, unsigned long nc, const string &cnonce, const string &qop, string &resp, string &fail_reason) const { u8 nonce64[B64_DEC_SZ(dchlg.nonce.size())]; int len = b64_dec((const u8 *)dchlg.nonce.c_str(), nonce64, dchlg.nonce.size()); u8 rnd[AKA_RANDLEN]; u8 sqnxoraka[AKA_SQNLEN]; u8 sqn[AKA_SQNLEN]; u8 k[AKA_KLEN]; u8 res[AKA_RESLEN]; u8 ck[AKA_CKLEN]; u8 ik[AKA_IKLEN]; u8 ak[AKA_AKLEN]; int i; if (len < AKA_RANDLEN+AKA_AUTNLEN) { fail_reason = "nonce base64 data too short (need 32 bytes)"; return false; } memset(rnd, 0, AKA_RANDLEN); memset(sqnxoraka, 0, AKA_SQNLEN); memset(k, 0, AKA_KLEN); memcpy(rnd, nonce64, AKA_RANDLEN); memcpy(sqnxoraka, nonce64 + AKA_RANDLEN, AKA_SQNLEN); memcpy(k, passwd.c_str(), passwd.size()); f2345(k, rnd, res, ck, ik, ak, op); for (i=0; i < AKA_SQNLEN; i++) sqn[i] = sqnxoraka[i] ^ ak[i]; string res_str = string((char *)res, AKA_RESLEN); return authorize_md5(dchlg, username, res_str, nc, cnonce, qop, resp, fail_reason); } // authentication with MD5 algorithm bool t_request::authorize_md5(const t_digest_challenge &dchlg, const string &username, const string &passwd, unsigned long nc, const string &cnonce, const string &qop, string &resp, string &fail_reason) const { string A1, A2; // RFC 2617 3.2.2.2 A1 = username + ":" + dchlg.realm + ":" + passwd; // RFC 2617 3.2.2.3 if (cmp_nocase(qop, QOP_AUTH) == 0 || qop == "") { A2 = method2str(method, unknown_method) + ":" + uri.encode(); } else { A2 = method2str(method, unknown_method) + ":" + uri.encode(); A2 += ":"; if (body) { MD5Digest MD5body; MD5body << body->encode(); ostringstream os; os << MD5body; A2 += os.str(); } else { MD5Digest MD5body; MD5body << ""; ostringstream os; os << MD5body; A2 += os.str(); } } // RFC 2716 3.2.2.1 // Caculate digest MD5Digest MD5A1; MD5Digest MD5A2; ostringstream HA1; ostringstream HA2; MD5A1 << A1; MD5A2 << A2; HA1 << MD5A1; HA2 << MD5A2; string x; if (cmp_nocase(qop, QOP_AUTH) == 0 || cmp_nocase(qop, QOP_AUTH_INT) == 0) { x = HA1.str() + ":"; x += dchlg.nonce + ":"; x += int2str(nc, "%08x") + ":"; x += cnonce + ":"; x += qop + ":"; x += HA2.str(); } else { x = HA1.str() + ":"; x += dchlg.nonce + ":"; x += HA2.str(); } MD5Digest digest; digest << x; ostringstream dresp; dresp << digest; resp = dresp.str(); return true; } bool t_request::authorize(const t_challenge &chlg, t_user *user_config, const string &username, const string &passwd, unsigned long nc, const string &cnonce, t_credentials &cr, string &fail_reason) const { // Only Digest authentication is supported if (cmp_nocase(chlg.auth_scheme, AUTH_DIGEST) != 0) { fail_reason = "Authentication scheme " + chlg.auth_scheme; fail_reason += " not supported."; return false; } const t_digest_challenge &dchlg = chlg.digest_challenge; string qop = ""; // Determine QOP // If both auth and auth-int are supported by the server, then // choose auth to avoid problems with SIP ALGs. A SIP ALG rewrites // the body of a message, thereby breaking auth-int authentication. if (!dchlg.qop_options.empty()) { const list::const_iterator i = find( dchlg.qop_options.begin(), dchlg.qop_options.end(), QOP_AUTH_INT); const list::const_iterator j = find( dchlg.qop_options.begin(), dchlg.qop_options.end(), QOP_AUTH); if (j != dchlg.qop_options.end()) qop = QOP_AUTH; else { if (i != dchlg.qop_options.end()) qop = QOP_AUTH_INT; else { fail_reason = "Non of the qop values are supported."; return false; } } } bool ret = false; string resp; if (cmp_nocase(dchlg.algorithm, ALG_MD5) == 0) { ret = authorize_md5(dchlg, username, passwd, nc, cnonce, qop, resp, fail_reason); } else if (cmp_nocase(dchlg.algorithm, ALG_AKAV1_MD5) == 0) { uint8 aka_op[AKA_OPLEN]; uint8 aka_amf[AKA_AMFLEN]; user_config->get_auth_aka_op(aka_op); user_config->get_auth_aka_amf(aka_amf); ret = authorize_akav1_md5(dchlg, username, passwd, aka_op, aka_amf, nc, cnonce, qop, resp, fail_reason); } else { fail_reason = "Authentication algorithm " + dchlg.algorithm; fail_reason += " not supported."; return false; } if (!ret) return false; // Create credentials cr.auth_scheme = AUTH_DIGEST; t_digest_response &dr = cr.digest_response; dr.dresponse = resp; dr.username = username; dr.realm = dchlg.realm; dr.nonce = dchlg.nonce; dr.digest_uri = uri; dr.algorithm = dchlg.algorithm; dr.opaque = dchlg.opaque; // RFC 2617 3.2.2 if (qop != "") { dr.message_qop = qop; dr.cnonce = cnonce; dr.nonce_count = nc; } return true; } t_request::t_request() : t_sip_message(), transport_specified(false), method(METHOD_UNKNOWN) { } t_request::t_request(const t_request &r) : t_sip_message(r), destinations(r.destinations), transport_specified(r.transport_specified), uri(r.uri), method(r.method), unknown_method(r.unknown_method) { } t_request::t_request(const t_method m) : t_sip_message() { method = m; } void t_request::set_method(const string &s) { method = str2method(s); if (method == METHOD_UNKNOWN) { unknown_method = s; } } string t_request::encode(bool add_content_length) { string s; s = method2str(method, unknown_method) + ' ' + uri.encode(); s += " SIP/"; s += version; s += CRLF; s += t_sip_message::encode(add_content_length); return s; } list t_request::encode_env(void) { string s; list l = t_sip_message::encode_env(); s = "SIPREQUEST_METHOD="; s += method2str(method, unknown_method); l.push_back(s); s = "SIPREQUEST_URI="; s += uri.encode(); l.push_back(s); return l; } t_sip_message *t_request::copy(void) const { t_sip_message *m = new t_request(*this); MEMMAN_NEW(m); return m; } void t_request::set_route(const t_url &target_uri, const list &route_set) { // RFC 3261 12.2.1.1 if (route_set.empty()) { uri = target_uri; } else { if (route_set.front().uri.get_lr()) { // Loose routing uri = target_uri; for (list::const_iterator i = route_set.begin(); i != route_set.end(); ++i) { hdr_route.add_route(*i); } hdr_route.route_to_first_route = true; } else { // Strict routing uri = route_set.front().uri; for (list::const_iterator i = route_set.begin(); i != route_set.end(); ++i) { if (i != route_set.begin()) { hdr_route.add_route(*i); } } // Add target uri to the route list t_route route; route.uri = target_uri; hdr_route.add_route(route); } } } t_response *t_request::create_response(int code, string reason) const { t_response *r; r = new t_response(code, reason); MEMMAN_NEW(r); r->src_ip_port_request = src_ip_port; r->hdr_from = hdr_from; r->hdr_call_id = hdr_call_id; r->hdr_cseq = hdr_cseq; r->hdr_via = hdr_via; r->hdr_to = hdr_to; // Create a to-tag if none was present in the request // NOTE: 100 Trying should not get a to-tag if (hdr_to.tag.size() == 0 && code != R_100_TRYING) { r->hdr_to.set_tag(NEW_TAG); } // Server SET_HDR_SERVER(r->hdr_server); return r; } bool t_request::is_valid(bool &fatal, string &reason) const { if (!t_sip_message::is_valid(fatal, reason)) return false; fatal = false; if (t_parser::check_max_forwards && !hdr_max_forwards.is_populated()) { reason = "Max-Forwards header missing"; return false; } // RFC 3261 8.1.1.5 // The CSeq method must match the request method. if (hdr_cseq.method != method) { reason = "CSeq method does not match request method"; return false; } switch(method) { case INVITE: if (!hdr_contact.is_populated()) { reason = "Contact header missing"; return false; } break; case PRACK: // RFC 3262 7.1 if (!hdr_rack.is_populated()) { reason = "RAck header missing"; return false; } break; case SUBSCRIBE: // RFC 3265 7.1, 7.2 if (!hdr_contact.is_populated()) { reason = "Contact header missing"; return false; } if (!hdr_event.is_populated()) { reason = "Event header missing"; return false; } break; case NOTIFY: // RFC 3265 7.1, 7.2 if (!hdr_contact.is_populated()) { reason = "Contact header missing"; return false; } if (!hdr_event.is_populated()) { reason = "Event header missing"; return false; } // RFC 3265 7.2 // Subscription-State header is mandatory // As an exception Twinkle allows an unsollicited NOTIFY for MWI // without a Subscription-State header. Asterisk sends // unsollicited NOTIFY requests. if (!hdr_to.tag.empty() || hdr_event.event_type != SIP_EVENT_MSG_SUMMARY) { if (!hdr_subscription_state.is_populated()) { reason = "Subscription-State header missing"; return false; } } // The Subscription-State header is mandatory. // However, Asterisk uses an expired draft for sending // unsollicitied NOTIFY messages without a Subscription-State // header. As Asterisk is popular, Twinkle allows this. break; case REFER: // RFC 3515 2.4.1 if (!hdr_refer_to.is_populated()) { reason = "Refer-To header missing"; return false; } break; default: break; } if (hdr_replaces.is_populated()) { // RFC 3891 3 if (method != INVITE) { reason = "Replaces header not allowed"; return false; } } return true; } void t_request::add_destinations(const t_user &user_profile, const t_url &dst_uri) { t_url dest; if (dst_uri.get_scheme() == "tel") { // Send a tel-URI to the configure domain for the user. dest = "sip:" + user_profile.get_domain(); } else { dest = dst_uri; } if ((user_profile.get_sip_transport() == SIP_TRANS_AUTO || user_profile.get_sip_transport() == SIP_TRANS_TCP) && (dest.get_transport().empty() || cmp_nocase(dest.get_transport(), "tcp") == 0)) { list l = dest.get_h_ip_srv("tcp"); destinations.insert(destinations.end(), l.begin(), l.end()); } // Add UDP destinations after TCP, so UDP will be used as a fallback // for large messages, when TCP fails. If the message is not large, // then the TCP destinations will be removed later. // NOTE: If a message is larger than 64K, it cannot be sent via UDP if ((user_profile.get_sip_transport() == SIP_TRANS_AUTO || user_profile.get_sip_transport() == SIP_TRANS_UDP) && (dest.get_transport().empty() || cmp_nocase(dest.get_transport(), "udp") == 0) && (get_encoded_size() < 65536)) { list l = dest.get_h_ip_srv("udp"); destinations.insert(destinations.end(), l.begin(), l.end()); } transport_specified = !dest.get_transport().empty(); } void t_request::calc_destinations(const t_user &user_profile) { destinations.clear(); // Send a REGISTER to the registrar if provisioned. if (method == REGISTER && user_profile.get_use_registrar()) { add_destinations(user_profile, user_profile.get_registrar()); return; } // Bypass the proxy for an out-of-dialog SUBSCRIBE if provisioned. if (method == SUBSCRIBE && hdr_to.tag.empty()) { if (hdr_event.event_type == SIP_EVENT_MSG_SUMMARY) { if (!user_profile.get_mwi_via_proxy()) { // Take Request-URI add_destinations(user_profile, uri); return; } } } if (!user_profile.get_use_outbound_proxy() || (hdr_to.tag != "" && !user_profile.get_all_requests_to_proxy())) { // A mid dialog request will go to the host in the contact // header (put in the request-URI in this request) or route list // specified in the final response of the invite (the Route-header in // this request). // Note that an ACK for a failed INVITE (3XX-6XX) will be // sent by the transaction layer to the ipaddr/port of the // INVITE. if (hdr_route.is_populated() && hdr_route.route_to_first_route) { // Take URI from first route-header t_url &u = hdr_route.route_list.front().uri; add_destinations(user_profile, u); } else { // Take Request-URI add_destinations(user_profile, uri); } } // Send request to outbound proxy if configured if (user_profile.get_use_outbound_proxy()) { if (user_profile.get_non_resolvable_to_proxy() && !destinations.empty()) { // The destination has been resolved, so do not // use the outbound proxy in this case. return; } if (user_profile.get_all_requests_to_proxy() || hdr_to.tag == "") { // All requests should go to the proxy. // Override destination by the outbound proxy address. destinations.clear(); add_destinations(user_profile, user_profile.get_outbound_proxy()); } } } void t_request::get_destination(t_ip_port &ip_port, const t_user &user_profile) { if (destinations.empty()) calc_destinations(user_profile); // RFC 3261 18.1.1 // If the message size is larger than 1300 then the message must be // sent over TCP. // If the destination URI indicated an explicit transport, then the // destination calculation picked the possible destinations already. // The size cannot influence this calculation anymore. if (user_profile.get_sip_transport() == SIP_TRANS_AUTO && !destinations.empty() && destinations.front().transport == "tcp" && get_encoded_size() <= user_profile.get_sip_transport_udp_threshold() && !transport_specified) { // The message can be sent over UDP. Remove all TCP destinations. while (!destinations.empty() && destinations.front().transport == "tcp") { destinations.pop_front(); } } get_current_destination(ip_port); } void t_request::get_current_destination(t_ip_port &ip_port) { if (destinations.empty()) { // No destinations could be found. ip_port.transport = "udp"; ip_port.ipaddr = 0; ip_port.port = 0; } else { // Return first destination ip_port = destinations.front(); } } bool t_request::next_destination(void) { if (destinations.size() <= 1) return false; // Remove current destination destinations.pop_front(); return true; } void t_request::set_destination(const t_ip_port &ip_port) { destinations.clear(); destinations.push_back(ip_port); } bool t_request::www_authorize(const t_challenge &chlg, t_user *user_config, const string &username, const string &passwd, unsigned long nc, const string &cnonce, t_credentials &cr, string &fail_reason) { if (!authorize(chlg, user_config, username, passwd, nc, cnonce, cr, fail_reason)) { return false; } hdr_authorization.add_credentials(cr); return true; } bool t_request::proxy_authorize(const t_challenge &chlg, t_user *user_config, const string &username, const string &passwd, unsigned long nc, const string &cnonce, t_credentials &cr, string &fail_reason) { if (!authorize(chlg, user_config, username, passwd, nc, cnonce, cr, fail_reason)) { return false; } hdr_proxy_authorization.add_credentials(cr); return true; } void t_request::calc_local_ip(void) { t_ip_port dst; get_current_destination(dst); if (dst.ipaddr != 0) { local_ip_ = get_src_ip4_address_for_dst(dst.ipaddr); } } bool t_request::is_registration_request(void) const { if (method != REGISTER) return false; if (hdr_expires.is_populated() && hdr_expires.time > 0) return true; if (hdr_contact.is_populated() && !hdr_contact.contact_list.empty() && hdr_contact.contact_list.front().is_expires_present() && hdr_contact.contact_list.front().get_expires() > 0) { return true; } return false; } bool t_request::is_de_registration_request(void) const { if (method != REGISTER) return false; if (hdr_expires.is_populated() && hdr_expires.time == 0) return true; if (hdr_contact.is_populated() && !hdr_contact.contact_list.empty() && hdr_contact.contact_list.front().is_expires_present() && hdr_contact.contact_list.front().get_expires() == 0) { return true; } return false; } twinkle-1.4.2/src/parser/hdr_expires.cpp0000644000175000001440000000214211127714057015217 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_expires.h" #include "util.h" t_hdr_expires::t_hdr_expires() : t_header("Expires") { time = 0; } void t_hdr_expires::set_time(unsigned long t) { populated = true; time = t; } string t_hdr_expires::encode_value(void) const { if (!populated) return ""; return ulong2str(time); } twinkle-1.4.2/src/parser/hdr_reply_to.h0000644000175000001440000000250611127714050015037 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Reply-To header #ifndef _H_HDR_REPLY_TO #define _H_HDR_REPLY_TO #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_reply_to : public t_header { public: string display; // display name t_url uri; list params; t_hdr_reply_to(); void set_display(const string &d); void set_uri(const string &u); void set_uri(const t_url &u); void set_params(const list &l); void add_param(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_allow.cpp0000644000175000001440000000365211127714057014665 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "definitions.h" #include "hdr_allow.h" using namespace std; t_hdr_allow::t_hdr_allow() : t_header("Allow") {} void t_hdr_allow::add_method(const t_method &m, const string &unknown) { populated = true; if (m != METHOD_UNKNOWN) { method_list.push_back(m); } else { unknown_methods.push_back(unknown); } } void t_hdr_allow::add_method(const string &s) { populated = true; t_method m = str2method(s); if (m != METHOD_UNKNOWN) { method_list.push_back(m); } else { unknown_methods.push_back(s); } } bool t_hdr_allow::contains_method(const t_method &m) const { return (find(method_list.begin(), method_list.end(), m) != method_list.end()); } string t_hdr_allow::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = method_list.begin(); i != method_list.end(); i++) { if (i != method_list.begin()) s += ","; s += method2str(*i); } for (list::const_iterator i = unknown_methods.begin(); i != unknown_methods.end(); i++) { if (i != unknown_methods.begin() || method_list.size() != 0) { s += ","; } s += *i; } return s; } twinkle-1.4.2/src/parser/parameter.h0000644000175000001440000000321411127714050014322 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PARAMETER_H #define _PARAMETER_H #include #include using namespace std; class t_parameter { public: enum t_param_type{ NOVALUE, // a parameter without a value VALUE // parameter having a value (default) }; t_param_type type; // type of parameter string name; // name of parameter string value; // value of parameter if type is VALUE t_parameter(); // Construct a NOVALUE parameter with name = n t_parameter(const string &n); // Construct a VALUE parameter with name = n, value = v t_parameter(const string &n, const string &v); string encode(void) const; bool operator==(const t_parameter &rhs); }; // Decode a parameter t_parameter str2param(const string &s); // Encode a parameter list string param_list2str(const list &l); // Decode a parameter list list str2param_list(const string &s); #endif twinkle-1.4.2/src/parser/hdr_in_reply_to.h0000644000175000001440000000215611127714050015526 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // In-Reply-To header #ifndef _H_HDR_IN_REPLY_TO #define _H_HDR_IN_REPLY_TO #include #include #include "header.h" using namespace std; class t_hdr_in_reply_to : public t_header { public: list call_ids; t_hdr_in_reply_to(); void add_call_id(const string &id); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_p_asserted_identity.cpp0000644000175000001440000000251411127714057017605 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_p_asserted_identity.h" t_hdr_p_asserted_identity::t_hdr_p_asserted_identity() : t_header("P-Asserted-Identity") {} void t_hdr_p_asserted_identity::add_identity(const t_identity &identity) { populated = true; identity_list.push_back(identity); } string t_hdr_p_asserted_identity::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = identity_list.begin(); i != identity_list.end(); i++) { if (i != identity_list.begin()) s += ','; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_content_language.cpp0000644000175000001440000000254111127714057017060 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_content_language.h" #include "util.h" t_hdr_content_language::t_hdr_content_language() : t_header("Content-Language") {}; void t_hdr_content_language::add_language(const t_language &language) { populated = true; language_list.push_back(language); } string t_hdr_content_language::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = language_list.begin(); i != language_list.end(); i++) { if (i != language_list.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_content_disp.h0000644000175000001440000000260411127714050015672 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Content-Disposition header #ifndef _HDR_CONTENT_DISP #define _HDR_CONTENT_DISP #include #include #include "header.h" #include "parameter.h" using namespace std; //@{ /** @name Disposition types */ #define DISPOSITION_ATTACHMENT "attachment" //@} class t_hdr_content_disp : public t_header { public: string type; string filename; list params; t_hdr_content_disp(); void set_type(const string &t); void set_filename(const string &name); void add_param(const t_parameter &p); void set_params(const list &l); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_via.cpp0000644000175000001440000001146411134633201014313 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "definitions.h" #include "hdr_via.h" #include "util.h" #include "parse_ctrl.h" #include "protocol.h" #include "sockets/url.h" t_via::t_via() { port = 0; ttl = 0; rport_present = false; rport = 0; } t_via::t_via(const string &_host, const int _port, bool add_rport) { protocol_name = "SIP"; protocol_version = SIP_VERSION; transport = "UDP"; host = _host; branch = RFC3261_COOKIE + random_token(8); if (_port != get_default_port("sip")) { port = _port; } else { port = 0; } ttl = 0; rport_present = add_rport; rport = 0; } void t_via::add_extension(const t_parameter &p) { extensions.push_back(p); } string t_via::encode(void) const { string s; s = protocol_name + '/' + protocol_version + '/' + transport; s += ' '; s += host; if (port > 0) { s += ':'; s += int2str(port); } if (ttl > 0) s += int2str(ttl, ";ttl=%d"); if (maddr.size() > 0) { s += ";maddr="; s += maddr; } if (received.size() > 0) { s += ";received="; s += received; } if (rport_present) { s += ";rport"; if (rport > 0) { s += "="; s += int2str(rport); } } if (branch.size() > 0) { s += ";branch="; s += branch; } s += param_list2str(extensions); return s; } void t_via::get_response_dst(t_ip_port &ip_port) const { string url_str("sip:"); // RFC 3261 18.2.2 // Determine the address to send a repsonse to // NOTE: the received-parameter will be added by the listener if needed. if (tolower(transport) == "tcp") { // NOTE: The response must be sent over the connection on which // the request was received. The address returned here is an // alternative if that connection is closed already. if (received.size() > 0) { url_str += received; } else { url_str += host; } url_str += ":"; // NOTE: The rport parameter is not processed here as it only // applies to unreliable transports (RFC 3581 4) url_str += int2str(port); t_url u(url_str); list ip_list = u.get_h_ip_srv("tcp"); ip_port = ip_list.front(); } else { if (maddr.size() > 0) { url_str += maddr; } else if (received.size() > 0) { url_str += received; } else { url_str += host; } // RFC 3581 4 if (rport_present && rport > 0) { // NOTE: the rport value will be added by the UDP listener // if the rport parameter without value was present. url_str += ':'; url_str += int2str(rport); } else if (port != 0) { url_str += ':'; url_str += int2str(port); } // If there was no maddr parameter, then the URL will always point to // an IP address; either the host was an IP address or a received parameter // containing an IP address was added (see RFC 3261 18.2.1) // If there was an maddr, then the URL can be a domain that could have // multiple SRV records. RFC 3263 section 5 does not specify what to do in // this case. So just send the response to the first destination. t_url u(url_str); list ip_list = u.get_h_ip_srv("udp"); ip_port = ip_list.front(); } } bool t_via::rfc3261_compliant(void) const { return (branch.find(RFC3261_COOKIE) == 0); } t_hdr_via::t_hdr_via() : t_header("Via", "v") {} void t_hdr_via::add_via(const t_via &v) { populated = true; via_list.push_back(v); } string t_hdr_via::encode(void) const { return (t_parser::multi_values_as_list ? t_header::encode() : encode_multi_header()); } string t_hdr_via::encode_multi_header(void) const { string s; if (!populated) return s; for (list::const_iterator i = via_list.begin(); i != via_list.end(); i++) { s += (t_parser::compact_headers ? compact_name : header_name); s += ": "; s += i->encode(); s += CRLF; } return s; } string t_hdr_via::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = via_list.begin(); i != via_list.end(); i++) { if (i != via_list.begin()) s += ","; s += i->encode(); } return s; } void t_hdr_via::get_response_dst(t_ip_port &ip_port) const { if (!populated) { ip_port.clear(); return; } via_list.front().get_response_dst(ip_port); } twinkle-1.4.2/src/parser/hdr_alert_info.cpp0000644000175000001440000000301711127714057015664 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_alert_info.h" void t_alert_param::add_param(const t_parameter &p) { parameter_list.push_back(p); } string t_alert_param::encode(void) const { string s; s = '<' + uri.encode() + '>'; s += param_list2str(parameter_list); return s; } t_hdr_alert_info::t_hdr_alert_info() : t_header("Alert-Info") {}; void t_hdr_alert_info::add_param(const t_alert_param &p) { populated = true; alert_param_list.push_back(p); } string t_hdr_alert_info::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = alert_param_list.begin(); i != alert_param_list.end(); i++) { if (i != alert_param_list.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_priority.h0000644000175000001440000000213011127714050015054 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Priority header #ifndef _H_HDR_PRIORITY_VERSION #define _H_HDR_PRIORITY_VERSION #include #include "header.h" using namespace std; class t_hdr_priority : public t_header { public: string priority; t_hdr_priority(); void set_priority(const string &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_subject.cpp0000644000175000001440000000214011127714057015175 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_subject.h" #include "parse_ctrl.h" t_hdr_subject::t_hdr_subject() : t_header("Subject", "s") {}; void t_hdr_subject::set_subject(const string &s) { populated = true; subject = s; } string t_hdr_subject::encode_value(void) const { if (!populated) return ""; return subject; } twinkle-1.4.2/src/parser/hdr_expires.h0000644000175000001440000000215011127714050014654 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Expires header #ifndef _HDR_EXPIRES_LENGTH #define _HDR_EXPIRES_LENGTH #include #include "header.h" using namespace std; class t_hdr_expires : public t_header { public: unsigned long time; // expiry time in seconds t_hdr_expires(); void set_time(unsigned long t); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_allow.h0000644000175000001440000000245411127714050014322 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Allow header #ifndef _HDR_ALLOW_H #define _HDR_ALLOW_H #include #include #include "header.h" #include "definitions.h" using namespace std; class t_hdr_allow : public t_header { public: list method_list; // Unknown methods are represented as strings list unknown_methods; t_hdr_allow(); void add_method(const t_method &m, const string &unknown = ""); void add_method(const string &s); bool contains_method(const t_method &m) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/identity.h0000644000175000001440000000215711127714050014200 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _IDENTITY_H #define _IDENTITY_H #include #include "sockets/url.h" using namespace std; class t_identity { public: string display; // display name t_url uri; t_identity(); void set_display(const string &d); void set_uri(const string &u); void set_uri(const t_url &u); string encode(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_record_route.cpp0000644000175000001440000000334411127714057016241 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_record_route.h" #include "parse_ctrl.h" #include "util.h" t_hdr_record_route::t_hdr_record_route() : t_header("Record-Route") {} void t_hdr_record_route::add_route(const t_route &r) { populated = true; route_list.push_back(r); } string t_hdr_record_route::encode(void) const { return (t_parser::multi_values_as_list ? t_header::encode() : encode_multi_header()); } string t_hdr_record_route::encode_multi_header(void) const { string s; if (!populated) return s; for (list::const_iterator i = route_list.begin(); i != route_list.end(); i++) { s += header_name; s += ": "; s += i->encode(); s += CRLF; } return s; } string t_hdr_record_route::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = route_list.begin(); i != route_list.end(); i++) { if (i != route_list.begin()) s += ","; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_subscription_state.h0000644000175000001440000000346011127714050017126 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Subscription-State header // RFC 3265 #ifndef _HDR_SUBSCRIPTION_STATE #define _HDR_SUBSCRIPTION_STATE #include #include #include "header.h" #include "parameter.h" // Subscription states #define SUBSTATE_ACTIVE "active" #define SUBSTATE_PENDING "pending" #define SUBSTATE_TERMINATED "terminated" // Event reasons #define EV_REASON_DEACTIVATED "deactivated" #define EV_REASON_PROBATION "probation" #define EV_REASON_REJECTED "rejected" #define EV_REASON_TIMEOUT "timeout" #define EV_REASON_GIVEUP "giveup" #define EV_REASON_NORESOURCE "noresource" using namespace std; class t_hdr_subscription_state : public t_header { public: string substate; string reason; unsigned long expires; unsigned long retry_after; list extensions; t_hdr_subscription_state(); void set_substate(const string &s); void set_reason(const string &s); void set_expires(unsigned long e); void set_retry_after(unsigned long r); void add_extension(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_user_agent.h0000644000175000001440000000232111127714050015331 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // User-Agent header #ifndef _H_HDR_USER_AGENT #define _H_HDR_USER_AGENT #include #include #include "header.h" #include "hdr_server.h" using namespace std; class t_hdr_user_agent : public t_header { public: list ua_info; t_hdr_user_agent(); void add_server(const t_server &s); // Get string representation of ua_info; string get_ua_info(void) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_proxy_require.cpp0000644000175000001440000000241111127714057016454 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_proxy_require.h" t_hdr_proxy_require::t_hdr_proxy_require() : t_header("Proxy-Require") {}; void t_hdr_proxy_require::add_feature(const string &f) { populated = true; features.push_back(f); } string t_hdr_proxy_require::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (i != features.begin()) s += ", "; s += *i; } return s; } twinkle-1.4.2/src/parser/hdr_request_disposition.cpp0000644000175000001440000001125211142402215017641 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_request_disposition.h" #include #include "util.h" t_hdr_request_disposition::t_hdr_request_disposition() : t_header("Request-Disposition", "d"), proxy_directive(PROXY_NULL), cancel_directive(CANCEL_NULL), fork_directive(FORK_NULL), recurse_directive(RECURSE_NULL), parallel_directive(PARALLEL_NULL), queue_directive(QUEUE_NULL) {} void t_hdr_request_disposition::set_proxy_directive(t_proxy_directive directive) { populated = true; proxy_directive = directive; } void t_hdr_request_disposition::set_cancel_directive(t_cancel_directive directive) { populated = true; cancel_directive = directive; } void t_hdr_request_disposition::set_fork_directive(t_fork_directive directive) { populated = true; fork_directive = directive; } void t_hdr_request_disposition::set_recurse_directive(t_recurse_directive directive) { populated = true; recurse_directive = directive; } void t_hdr_request_disposition::set_parallel_directive(t_parallel_directive directive) { populated = true; parallel_directive = directive; } void t_hdr_request_disposition::set_queue_directive(t_queue_directive directive) { populated = true; queue_directive = directive; } bool t_hdr_request_disposition::set_directive(const string &s) { if (s == REQDIS_PROXY) { if (proxy_directive == REDIRECT) return false; set_proxy_directive(PROXY); return true; } if (s == REQDIS_REDIRECT) { if (proxy_directive == PROXY) return false; set_proxy_directive(REDIRECT); return true; } if (s == REQDIS_CANCEL) { if (cancel_directive == NO_CANCEL) return false; set_cancel_directive(CANCEL); return true; } if (s == REQDIS_NO_CANCEL) { if (cancel_directive == CANCEL) return false; set_cancel_directive(NO_CANCEL); return true; } if (s == REQDIS_FORK) { if (fork_directive == NO_FORK) return false; set_fork_directive(FORK); return true; } if (s == REQDIS_NO_FORK) { if (fork_directive == FORK) return false; set_fork_directive(NO_FORK); return true; } if (s == REQDIS_RECURSE) { if (recurse_directive == NO_RECURSE) return false; set_recurse_directive(RECURSE); return true; } if (s == REQDIS_NO_RECURSE) { if (recurse_directive == RECURSE) return false; set_recurse_directive(NO_RECURSE); return true; } if (s == REQDIS_PARALLEL) { if (parallel_directive == SEQUENTIAL) return false; set_parallel_directive(PARALLEL); return true; } if (s == REQDIS_SEQUENTIAL) { if (parallel_directive == PARALLEL) return false; set_parallel_directive(SEQUENTIAL); return true; } if (s == REQDIS_QUEUE) { if (queue_directive == NO_QUEUE) return false; set_queue_directive(QUEUE); return true; } if (s == REQDIS_NO_QUEUE) { if (queue_directive == QUEUE) return false; set_queue_directive(NO_QUEUE); return true; } return false; } string t_hdr_request_disposition::encode_value(void) const { if (!populated) return ""; vector v; switch (proxy_directive) { case PROXY: v.push_back(REQDIS_PROXY); break; case REDIRECT: v.push_back(REQDIS_REDIRECT); break; default: break; } switch (cancel_directive) { case CANCEL: v.push_back(REQDIS_CANCEL); break; case NO_CANCEL: v.push_back(REQDIS_NO_CANCEL); break; default: break; } switch (fork_directive) { case FORK: v.push_back(REQDIS_FORK); break; case NO_FORK: v.push_back(REQDIS_NO_FORK); break; default: break; } switch (recurse_directive) { case RECURSE: v.push_back(REQDIS_RECURSE); break; case NO_RECURSE: v.push_back(REQDIS_NO_RECURSE); break; default: break; } switch (parallel_directive) { case PARALLEL: v.push_back(REQDIS_PARALLEL); break; case SEQUENTIAL: v.push_back(REQDIS_SEQUENTIAL); break; default: break; } switch (queue_directive) { case QUEUE: v.push_back(REQDIS_QUEUE); break; case NO_QUEUE: v.push_back(REQDIS_NO_QUEUE); break; default: break; } string s = join_strings(v, ","); return s; } twinkle-1.4.2/src/parser/sip_message.cpp0000644000175000001440000003153311142376103015201 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "sip_message.h" #include "util.h" #include "parse_ctrl.h" #include "sdp/sdp.h" #include "audits/memman.h" //////////////////////////////////// // class t_sip_message //////////////////////////////////// t_sip_message::t_sip_message() : local_ip_(0) { src_ip_port.clear(); version = SIP_VERSION; body = NULL; } t_sip_message::t_sip_message(const t_sip_message& m) : local_ip_(m.local_ip_), src_ip_port(m.src_ip_port), version(m.version), hdr_accept(m.hdr_accept), hdr_accept_encoding(m.hdr_accept_encoding), hdr_accept_language(m.hdr_accept_language), hdr_alert_info(m.hdr_alert_info), hdr_allow(m.hdr_allow), hdr_allow_events(m.hdr_allow_events), hdr_auth_info(m.hdr_auth_info), hdr_authorization(m.hdr_authorization), hdr_call_id(m.hdr_call_id), hdr_call_info(m.hdr_call_info), hdr_contact(m.hdr_contact), hdr_content_disp(m.hdr_content_disp), hdr_content_encoding(m.hdr_content_encoding), hdr_content_language(m.hdr_content_language), hdr_content_length(m.hdr_content_length), hdr_content_type(m.hdr_content_type), hdr_cseq(m.hdr_cseq), hdr_date(m.hdr_date), hdr_error_info(m.hdr_error_info), hdr_event(m.hdr_event), hdr_expires(m.hdr_expires), hdr_from(m.hdr_from), hdr_in_reply_to(m.hdr_in_reply_to), hdr_max_forwards(m.hdr_max_forwards), hdr_min_expires(m.hdr_min_expires), hdr_mime_version(m.hdr_mime_version), hdr_organization(m.hdr_organization), hdr_p_asserted_identity(m.hdr_p_asserted_identity), hdr_p_preferred_identity(m.hdr_p_preferred_identity), hdr_priority(m.hdr_priority), hdr_privacy(m.hdr_privacy), hdr_proxy_authenticate(m.hdr_proxy_authenticate), hdr_proxy_authorization(m.hdr_proxy_authorization), hdr_proxy_require(m.hdr_proxy_require), hdr_rack(m.hdr_rack), hdr_record_route(m.hdr_record_route), hdr_refer_sub(m.hdr_refer_sub), hdr_refer_to(m.hdr_refer_to), hdr_referred_by(m.hdr_referred_by), hdr_replaces(m.hdr_replaces), hdr_reply_to(m.hdr_reply_to), hdr_require(m.hdr_require), hdr_request_disposition(m.hdr_request_disposition), hdr_retry_after(m.hdr_retry_after), hdr_route(m.hdr_route), hdr_rseq(m.hdr_rseq), hdr_server(m.hdr_server), hdr_service_route(m.hdr_service_route), hdr_sip_etag(m.hdr_sip_etag), hdr_sip_if_match(m.hdr_sip_if_match), hdr_subject(m.hdr_subject), hdr_subscription_state(m.hdr_subscription_state), hdr_supported(m.hdr_supported), hdr_timestamp(m.hdr_timestamp), hdr_to(m.hdr_to), hdr_unsupported(m.hdr_unsupported), hdr_user_agent(m.hdr_user_agent), hdr_via(m.hdr_via), hdr_warning(m.hdr_warning), hdr_www_authenticate(m.hdr_www_authenticate), unknown_headers(m.unknown_headers) { if (m.body) { body = m.body->copy(); } else { body = NULL; } } t_sip_message::~t_sip_message() { if (body) { MEMMAN_DELETE(body); delete body; } } t_msg_type t_sip_message::get_type(void) const { return MSG_SIPFRAG; } void t_sip_message::add_unknown_header(const string &name, const string &value) { t_parameter h(name, value); unknown_headers.push_back(h); } bool t_sip_message::is_valid(bool &fatal, string &reason) const { // RFC 3261 8.1.1 // Mandatory headers if (!hdr_to.is_populated()) { fatal = true; reason = "To-header missing"; return false; } if (!hdr_from.is_populated()) { fatal = true; reason = "From header missing"; return false; } if (!hdr_cseq.is_populated()) { fatal = true; reason = "CSeq header missing"; return false; } if (!hdr_call_id.is_populated()) { fatal = true; reason = "Call-ID header missing"; return false; } if (!hdr_via.is_populated()) { fatal = true; reason = "Via header missing"; return false; } // RFC 3261 20.15 // Content-Type MUST be present if body is not empty if (body && !hdr_content_type.is_populated()) { fatal = false; reason = "Content-Type header missing"; return false; } // RFC 3261 18.4 // The Content-Length header field MUST be used with stream oriented transports. if (cmp_nocase(hdr_via.via_list.front().transport, "tcp") == 0 && !hdr_content_length.is_populated()) { fatal = false; reason = "Content-Length header missing"; return false; } return true; } string t_sip_message::encode(bool add_content_length) { string s; string encoded_body; // RFC 3261 7.3.1 // Headers needed by a proxy should be on top s += hdr_via.encode(); s += hdr_route.encode(); s += hdr_record_route.encode(); s += hdr_service_route.encode(); s += hdr_proxy_require.encode(); s += hdr_max_forwards.encode(); s += hdr_proxy_authenticate.encode(); s += hdr_proxy_authorization.encode(); // Order as in many examples s += hdr_to.encode(); s += hdr_from.encode(); s += hdr_call_id.encode(); s += hdr_cseq.encode(); s += hdr_contact.encode(); s += hdr_content_type.encode(); // Privacy related headers s += hdr_privacy.encode(); s += hdr_p_asserted_identity.encode(); s += hdr_p_preferred_identity.encode(); // Authentication headers s += hdr_auth_info.encode(); s += hdr_authorization.encode(); s += hdr_www_authenticate.encode(); // Remaining headers in alphabetical order s += hdr_accept.encode(); s += hdr_accept_encoding.encode(); s += hdr_accept_language.encode(); s += hdr_alert_info.encode(); s += hdr_allow.encode(); s += hdr_allow_events.encode(); s += hdr_call_info.encode(); s += hdr_content_disp.encode(); s += hdr_content_encoding.encode(); s += hdr_content_language.encode(); s += hdr_date.encode(); s += hdr_error_info.encode(); s += hdr_event.encode(); s += hdr_expires.encode(); s += hdr_in_reply_to.encode(); s += hdr_min_expires.encode(); s += hdr_mime_version.encode(); s += hdr_organization.encode(); s += hdr_priority.encode(); s += hdr_rack.encode(); s += hdr_refer_sub.encode(); s += hdr_refer_to.encode(); s += hdr_referred_by.encode(); s += hdr_replaces.encode(); s += hdr_reply_to.encode(); s += hdr_require.encode(); s += hdr_request_disposition.encode(); s += hdr_retry_after.encode(); s += hdr_rseq.encode(); s += hdr_server.encode(); s += hdr_sip_etag.encode(); s += hdr_sip_if_match.encode(); s += hdr_subject.encode(); s += hdr_subscription_state.encode(); s += hdr_supported.encode(); s += hdr_timestamp.encode(); s += hdr_unsupported.encode(); s += hdr_user_agent.encode(); s += hdr_warning.encode(); // Unknown headers for (list::const_iterator i = unknown_headers.begin(); i != unknown_headers.end(); i++) { s += i->name; s += ": "; s += i->value; s += CRLF; } // Encode body if present. Set the content length. if (body) { encoded_body = body->encode(); hdr_content_length.set_length(encoded_body.size()); } else { // RFC 3261 20.14 // If no body is present then Content-Length MUST be 0 hdr_content_length.set_length(0); } // Content-Length appears last in examples if (add_content_length) { s += hdr_content_length.encode(); } // Blank line between headers and body s += CRLF; // Add body if (body) s += encoded_body; return s; } list t_sip_message::encode_env(void) { list l; // RFC 3261 7.3.1 // Headers needed by a proxy should be on top l.push_back(hdr_via.encode_env()); l.push_back(hdr_route.encode_env()); l.push_back(hdr_record_route.encode_env()); l.push_back(hdr_service_route.encode_env()); l.push_back(hdr_proxy_require.encode_env()); l.push_back(hdr_max_forwards.encode_env()); l.push_back(hdr_proxy_authenticate.encode_env()); l.push_back(hdr_proxy_authorization.encode_env()); // Order as in many examples l.push_back(hdr_to.encode_env()); l.push_back(hdr_from.encode_env()); l.push_back(hdr_call_id.encode_env()); l.push_back(hdr_cseq.encode_env()); l.push_back(hdr_contact.encode_env()); l.push_back(hdr_content_type.encode_env()); // Authentication headers l.push_back(hdr_auth_info.encode_env()); l.push_back(hdr_authorization.encode_env()); l.push_back(hdr_www_authenticate.encode_env()); // Authentication headers l.push_back(hdr_auth_info.encode_env()); l.push_back(hdr_authorization.encode_env()); l.push_back(hdr_www_authenticate.encode_env()); // Remaining headers in alphabetical order l.push_back(hdr_accept.encode_env()); l.push_back(hdr_accept_encoding.encode_env()); l.push_back(hdr_accept_language.encode_env()); l.push_back(hdr_alert_info.encode_env()); l.push_back(hdr_allow.encode_env()); l.push_back(hdr_allow_events.encode_env()); l.push_back(hdr_call_info.encode_env()); l.push_back(hdr_content_disp.encode_env()); l.push_back(hdr_content_encoding.encode_env()); l.push_back(hdr_content_language.encode_env()); l.push_back(hdr_date.encode_env()); l.push_back(hdr_error_info.encode_env()); l.push_back(hdr_event.encode_env()); l.push_back(hdr_expires.encode_env()); l.push_back(hdr_in_reply_to.encode_env()); l.push_back(hdr_min_expires.encode_env()); l.push_back(hdr_mime_version.encode_env()); l.push_back(hdr_organization.encode_env()); l.push_back(hdr_priority.encode_env()); l.push_back(hdr_rack.encode_env()); l.push_back(hdr_refer_sub.encode_env()); l.push_back(hdr_refer_to.encode_env()); l.push_back(hdr_referred_by.encode_env()); l.push_back(hdr_replaces.encode_env()); l.push_back(hdr_reply_to.encode_env()); l.push_back(hdr_require.encode_env()); l.push_back(hdr_request_disposition.encode_env()); l.push_back(hdr_retry_after.encode_env()); l.push_back(hdr_rseq.encode_env()); l.push_back(hdr_server.encode_env()); l.push_back(hdr_sip_etag.encode_env()); l.push_back(hdr_sip_if_match.encode_env()); l.push_back(hdr_subject.encode_env()); l.push_back(hdr_subscription_state.encode_env()); l.push_back(hdr_supported.encode_env()); l.push_back(hdr_timestamp.encode_env()); l.push_back(hdr_unsupported.encode_env()); l.push_back(hdr_user_agent.encode_env()); l.push_back(hdr_warning.encode_env()); // Unknown headers for (list::const_iterator i = unknown_headers.begin(); i != unknown_headers.end(); i++) { string s = "SIP_"; s += toupper(replace_char(i->name, '-', '_')); s += '='; s += i->value; l.push_back(s); } l.push_back(hdr_content_length.encode_env()); return l; } t_sip_message *t_sip_message::copy(void) const { t_sip_message *m = new t_sip_message(*this); MEMMAN_NEW(m); return m; } void t_sip_message::set_body_plain_text(const string &text, const string &charset) { // Content-Type header t_media mime_type("text", "plain"); mime_type.charset = charset; hdr_content_type.set_media(mime_type); if (body) { MEMMAN_DELETE(body); delete body; } body = new t_sip_body_plain_text(text); MEMMAN_NEW(body); } bool t_sip_message::set_body_from_file(const string &filename, const t_media &media) { // Open file and set read pointer at end so we know the size. ifstream f(filename.c_str(), ios::binary); if (!f) return false; ostringstream body_stream(ios::binary); // Copy file into body body_stream << f.rdbuf(); if (!f.good() || !body_stream.good()) { return false; } // Create body of correct type t_sip_body *new_body = NULL; if (media.type == "text" && media.subtype == "plain") { t_sip_body_plain_text *text_body = new t_sip_body_plain_text(body_stream.str()); MEMMAN_NEW(text_body); new_body = text_body; } else { t_sip_body_opaque *opaque_body = new t_sip_body_opaque(body_stream.str()); MEMMAN_NEW(opaque_body); new_body = opaque_body; } if (body) { MEMMAN_DELETE(body); delete body; } body = new_body; // Content-Type header hdr_content_type.set_media(media); return true; } size_t t_sip_message::get_encoded_size(void) { string s = encode(); return s.size(); } bool t_sip_message::local_ip_check(void) const { if (get_type() == MSG_REQUEST && hdr_via.is_populated()) { const t_via &v = hdr_via.via_list.front(); if (v.host == "0.0.0.0") return false; } if (hdr_contact.is_populated()) { if (!hdr_contact.any_flag && !hdr_contact.contact_list.empty()) { const t_contact_param &c = hdr_contact.contact_list.front(); if (c.uri.get_host() == "0.0.0.0") return false; } } if (body) { return body->local_ip_check(); } return true; } void t_sip_message::calc_local_ip(void) { // Do nothing } unsigned long t_sip_message::get_local_ip(void) { if (local_ip_ == 0) calc_local_ip(); return local_ip_; } twinkle-1.4.2/src/parser/parse_ctrl.h0000644000175000001440000001064711127714050014510 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Parser control #ifndef _PARSE_CTRL_H #define _PARSE_CTRL_H #include "sip_message.h" #include "threads/mutex.h" #define MSG t_parser::msg #define CTXT_INITIAL (t_parser::context = t_parser::X_INITIAL) #define CTXT_URI (t_parser::context = t_parser::X_URI) #define CTXT_URI_SPECIAL (t_parser::context = t_parser::X_URI_SPECIAL) #define CTXT_LANG (t_parser::context = t_parser::X_LANG) #define CTXT_WORD (t_parser::context = t_parser::X_WORD) #define CTXT_NUM (t_parser::context = t_parser::X_NUM) #define CTXT_DATE (t_parser::context = t_parser::X_DATE) #define CTXT_LINE (t_parser::context = t_parser::X_LINE) #define CTXT_COMMENT (t_parser::enter_ctx_comment()) #define CTXT_NEW (t_parser::context = t_parser::X_NEW) #define CTXT_AUTH_SCHEME (t_parser::context = t_parser::X_AUTH_SCHEME) #define CTXT_IPV6ADDR (t_parser::context = t_parser::X_IPV6ADDR) #define CTXT_PARAMVAL (t_parser::context = t_parser::X_PARAMVAL) #define PARSE_ERROR(h) { t_parser::add_header_error(h); CTXT_INITIAL; } // The t_parser controls the direction of the scanner/parser // process and it stores the results from the parser. class t_parser { private: /** Mutex to synchronize parse operations */ static t_mutex mtx_parser; // Level for nested comments static int comment_level; // Non-fatal parse errors generated during parsing. static list parse_errors; // Unfold SIP headers static string unfold(const string &h); public: enum t_context { X_INITIAL, // Initial context X_URI, // URI context where parameters belong to URI X_URI_SPECIAL, // URI context where parameters belong to SIP header // if URI is not enclosed by < and > X_LANG, // Language tag context X_WORD, // Word context X_NUM, // Number context X_DATE, // Date context X_LINE, // Whole line context X_COMMENT, // Comment context X_NEW, // Start of a new SIP message to distinguish // request from responses X_AUTH_SCHEME, // Authorization scheme context X_IPV6ADDR, // IPv6 address context X_PARAMVAL, // Generic parameter value context }; // Parser options // According to RFC3261 the Max-Forwards header is mandatory, but // many implementations do not send this header. static bool check_max_forwards; // Encode headers in compact forom static bool compact_headers; // Encode multiple values as comma separated list or multiple headers static bool multi_values_as_list; static t_context context; // Scan context static t_sip_message *msg; // Message that has been parsed /** * Parse a string representing a SIP message. * @param s [in] String to parse. * @param parse_errors_ [out] List of non-fatal parse errors. * @return The parsed SIP message. * @throw int exception when parsing fails. */ static t_sip_message *parse(const string &s, list &parse_errors_); /** * Parse a string of headers (hdr1=val1;hdr=val2;...) * The resulting SIP message is a SIP request with a fake request line. * @param s [in] String to parse. * @param parse_errors_ [out] List of non-fatal parse errors. * @return The parsed SIP message. * @throw int exception when parsing fails. */ static t_sip_message *parse_headers(const string &s, list &parse_errors_); static void enter_ctx_comment(void); // Increment and decrement levels for nested comments // dec_comment_level returns false if the level cannot be decremented. static void inc_comment_level(void); static bool dec_comment_level(void); // Add parsing error for a header to the list of parse errors static void add_header_error(const string &header_name); }; // Error that can be thrown as exception class t_syntax_error { public: string error; t_syntax_error(const string &e); }; #endif twinkle-1.4.2/src/parser/hdr_contact.cpp0000644000175000001440000000736711127714057015211 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_contact.h" #include "parse_ctrl.h" #include "util.h" t_contact_param::t_contact_param() { qvalue = 1.0; qvalue_present = false; expires = 0; expires_present = false; } void t_contact_param::add_extension(const t_parameter &p) { extensions.push_back(p); } string t_contact_param::encode(void) const { string s; if (display.size() > 0) { s += '"'; s += escape(display, '"'); s += '"'; s += ' '; } s += '<'; s += uri.encode(); s += '>'; if (qvalue_present) { s += ";q="; s += float2str(qvalue, 3); } if (expires_present) s += ulong2str(expires, ";expires=%u"); s += param_list2str(extensions); return s; } bool t_contact_param::operator<(const t_contact_param &c) const { return (qvalue > c.qvalue); } t_hdr_contact::t_hdr_contact() : t_header("Contact", "m") { any_flag = false; } void t_hdr_contact::add_contact(const t_contact_param &contact) { populated = true; contact_list.push_back(contact); } void t_hdr_contact::add_contacts(const list &l) { populated = true; for (list::const_iterator i = l.begin(); i != l.end(); i++) { contact_list.push_back(*i); } } void t_hdr_contact::set_contacts(const list &l) { populated = true; contact_list = l; } void t_hdr_contact::set_contacts(const list &l) { t_contact_param c; float q = 0.9; populated = true; contact_list.clear(); for (list::const_iterator i = l.begin(); i != l.end(); i++) { c.uri = *i; c.set_qvalue(q); contact_list.push_back(c); q = q - 0.1; if (q < 0.1) q = 0.1; } } void t_hdr_contact::set_contacts(const list &l) { t_contact_param c; float q = 0.9; populated = true; contact_list.clear(); for (list::const_iterator i = l.begin(); i != l.end(); i++) { c.uri = i->url; c.display = i->display; c.set_qvalue(q); contact_list.push_back(c); q = q - 0.1; if (q < 0.1) q = 0.1; } } void t_hdr_contact::set_any(void) { populated = true; any_flag = true; contact_list.clear(); } t_contact_param *t_hdr_contact::find_contact(const t_url &u) { for (list::iterator i = contact_list.begin(); i != contact_list.end(); i++) { if (u.sip_match(i->uri)) return &(*i); } return NULL; } bool t_contact_param::is_expires_present(void) const { return expires_present; } unsigned long t_contact_param::get_expires(void) const { return expires; } void t_contact_param::set_expires(unsigned long e) { expires_present = true; expires = e; } float t_contact_param::get_qvalue(void) const { return qvalue; } void t_contact_param::set_qvalue(float q) { qvalue_present = true; qvalue = q; } string t_hdr_contact::encode_value(void) const { string s; if (!populated) return s; if (any_flag) { s += '*'; return s; } for (list::const_iterator i = contact_list.begin(); i != contact_list.end(); i++) { if (i != contact_list.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_proxy_authorization.cpp0000644000175000001440000000460311127714057017705 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_proxy_authorization.h" #include "definitions.h" t_hdr_proxy_authorization::t_hdr_proxy_authorization() : t_header("Proxy-Authorization") {} void t_hdr_proxy_authorization::add_credentials(const t_credentials &c) { populated = true; credentials_list.push_back(c); } string t_hdr_proxy_authorization::encode(void) const { string s; if (!populated) return s; // RFC 3261 20.28 // Each authorization should appear as a separate header for (list::const_iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { s += header_name; s += ": "; s += i->encode(); s += CRLF; } return s; } string t_hdr_proxy_authorization::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { if (i != credentials_list.begin()) s += ", "; s += i->encode(); } return s; } bool t_hdr_proxy_authorization::contains(const string &realm, const t_url &uri) const { for (list::const_iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { if (i->digest_response.realm == realm && i->digest_response.digest_uri == uri) { return true; } } return false; } void t_hdr_proxy_authorization::remove_credentials(const string &realm, const t_url &uri) { for (list::iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { if (i->digest_response.realm == realm && i->digest_response.digest_uri == uri) { credentials_list.erase(i); return; } } } twinkle-1.4.2/src/parser/hdr_p_preferred_identity.cpp0000644000175000001440000000252211127714057017750 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_p_preferred_identity.h" t_hdr_p_preferred_identity::t_hdr_p_preferred_identity() : t_header("P-Preferred-Identity") {} void t_hdr_p_preferred_identity::add_identity(const t_identity &identity) { populated = true; identity_list.push_back(identity); } string t_hdr_p_preferred_identity::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = identity_list.begin(); i != identity_list.end(); i++) { if (i != identity_list.begin()) s += ','; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_min_expires.cpp0000644000175000001440000000217211127714057016065 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_min_expires.h" #include "util.h" t_hdr_min_expires::t_hdr_min_expires() : t_header("Min-Expires") { time = 0; } void t_hdr_min_expires::set_time(unsigned long t) { populated = true; time = t; } string t_hdr_min_expires::encode_value(void) const { if (!populated) return ""; return ulong2str(time); } twinkle-1.4.2/src/parser/hdr_cseq.cpp0000644000175000001440000000322711127714057014500 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_cseq.h" #include "util.h" t_hdr_cseq::t_hdr_cseq() : t_header("CSeq") { seqnr = 0; method = INVITE; } void t_hdr_cseq::set_seqnr(unsigned long l) { populated = true; seqnr = l; } void t_hdr_cseq::set_method(t_method m, const string &unknown) { populated = true; method = m; unknown_method = unknown; } void t_hdr_cseq::set_method(const string &s) { populated = true; method = str2method(s); if (method == METHOD_UNKNOWN) { unknown_method = s; } } string t_hdr_cseq::encode_value(void) const { string s; if (!populated) return s; s = ulong2str(seqnr) + ' '; s += method2str(method, unknown_method); return s; } bool t_hdr_cseq::operator==(const t_hdr_cseq &h) const { if (method != METHOD_UNKNOWN) { return (seqnr == h.seqnr && method == h.method); } return (seqnr == h.seqnr && unknown_method == h.unknown_method); } twinkle-1.4.2/src/parser/hdr_auth_info.cpp0000644000175000001440000000426611127714057015525 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_auth_info.h" #include "definitions.h" #include "util.h" t_hdr_auth_info::t_hdr_auth_info() : t_header("Authentication-Info") { nonce_count = 0; } void t_hdr_auth_info::set_next_nonce(const string &nn) { populated = true; next_nonce = nn; } void t_hdr_auth_info::set_message_qop(const string &mq) { populated = true; message_qop = mq; } void t_hdr_auth_info::set_response_auth(const string &ra) { populated = true; response_auth = ra; } void t_hdr_auth_info::set_cnonce(const string &cn) { populated = true; cnonce = cn; } void t_hdr_auth_info::set_nonce_count(const unsigned long &nc) { populated = true; nonce_count = nc; } string t_hdr_auth_info::encode_value(void) const { string s; bool add_comma = false; if (!populated) return s; if (next_nonce.size() > 0) { s += "nextnonce="; s += '"'; s += next_nonce; s += '"'; add_comma = true; } if (message_qop.size() > 0) { if (add_comma) s += ','; s += "qop="; s += message_qop; add_comma = true; } if (response_auth.size() > 0) { if (add_comma) s += ','; s += "rspauth="; s += '"'; s += response_auth; s += '"'; add_comma = true; } if (cnonce.size() > 0) { if (add_comma) s += ','; s += "cnonce="; s += '"'; s += cnonce; s += '"'; add_comma = true; } if (nonce_count > 0) { if (add_comma) s += ','; s += "nc="; s += ulong2str(nonce_count, "%08x"); add_comma = true; } return s; } twinkle-1.4.2/src/parser/hdr_supported.cpp0000644000175000001440000000344711127714057015576 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_supported.h" #include "parse_ctrl.h" t_hdr_supported::t_hdr_supported() : t_header("Supported", "k") {}; void t_hdr_supported::add_feature(const string &f) { populated = true; if (!contains(f)) { features.push_back(f); } } void t_hdr_supported::add_features(const list &l) { if (l.empty()) return; for (list::const_iterator i = l.begin(); i != l.end(); i++) { add_feature(*i); } populated = true; } void t_hdr_supported::set_empty(void) { populated = true; features.clear(); } bool t_hdr_supported::contains(const string &f) const { if (!populated) return false; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (*i == f) return true; } return false; } string t_hdr_supported::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (i != features.begin()) s += ","; s += *i; } return s; } twinkle-1.4.2/src/parser/hdr_call_info.cpp0000644000175000001440000000300211127714057015462 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_call_info.h" void t_info_param::add_param(const t_parameter &p) { parameter_list.push_back(p); } string t_info_param::encode(void) const { string s; s = '<' + uri.encode() + '>'; s += param_list2str(parameter_list); return s; } t_hdr_call_info::t_hdr_call_info() : t_header("Call-Info") {}; void t_hdr_call_info::add_param(const t_info_param &p) { populated = true; info_param_list.push_back(p); } string t_hdr_call_info::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = info_param_list.begin(); i != info_param_list.end(); i++) { if (i != info_param_list.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/response.cpp0000744000175000001440000001432411134633560014544 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "response.h" #include "util.h" #include "parse_ctrl.h" #include "audits/memman.h" t_response::t_response() : t_sip_message() {} t_response::t_response(const t_response &r) : t_sip_message(r) , code(r.code), reason(r.reason), src_ip_port_request(r.src_ip_port_request) { } t_response::t_response(int _code, string _reason) : t_sip_message() { code = _code; if (_reason == "") { switch (code) { case 100: reason = REASON_100; break; case 180: reason = REASON_180; break; case 181: reason = REASON_181; break; case 182: reason = REASON_182; break; case 183: reason = REASON_183; break; case 200: reason = REASON_200; break; case 202: reason = REASON_202; break; case 300: reason = REASON_300; break; case 301: reason = REASON_301; break; case 302: reason = REASON_302; break; case 305: reason = REASON_305; break; case 380: reason = REASON_380; break; case 400: reason = REASON_400; break; case 401: reason = REASON_401; break; case 402: reason = REASON_402; break; case 403: reason = REASON_403; break; case 404: reason = REASON_404; break; case 405: reason = REASON_405; break; case 406: reason = REASON_406; break; case 407: reason = REASON_407; break; case 408: reason = REASON_408; break; case 410: reason = REASON_410; break; case 412: reason = REASON_412; break; case 413: reason = REASON_413; break; case 414: reason = REASON_414; break; case 415: reason = REASON_415; break; case 416: reason = REASON_416; break; case 420: reason = REASON_420; break; case 421: reason = REASON_421; break; case 423: reason = REASON_423; break; case 480: reason = REASON_480; break; case 481: reason = REASON_481; break; case 482: reason = REASON_482; break; case 483: reason = REASON_483; break; case 484: reason = REASON_484; break; case 485: reason = REASON_485; break; case 486: reason = REASON_486; break; case 487: reason = REASON_487; break; case 488: reason = REASON_488; break; case 489: reason = REASON_489; break; case 491: reason = REASON_491; break; case 493: reason = REASON_493; break; case 500: reason = REASON_500; break; case 501: reason = REASON_501; break; case 502: reason = REASON_502; break; case 503: reason = REASON_503; break; case 504: reason = REASON_504; break; case 505: reason = REASON_505; break; case 513: reason = REASON_513; break; case 600: reason = REASON_600; break; case 603: reason = REASON_603; break; case 604: reason = REASON_604; break; case 606: reason = REASON_606; break; default: reason = "Unknown Error"; } } else { reason = _reason; } } int t_response::get_class(void) const { return code / 100; } bool t_response::is_provisional(void) const { return (get_class() == R_1XX); } bool t_response::is_final(void) const { return (get_class() != R_1XX); } bool t_response::is_success(void) const { return (get_class() == R_2XX); } string t_response::encode(bool add_content_length) { string s; s = "SIP/" + version + ' ' + int2str(code, "%3d") + ' ' + reason; s += CRLF; s += t_sip_message::encode(add_content_length); return s; } list t_response::encode_env(void) { string s; list l = t_sip_message::encode_env(); s = "SIPSTATUS_CODE="; s += int2str(code, "%3d"); l.push_back(s); s = "SIPSTATUS_REASON="; s += reason; l.push_back(s); return l; } t_sip_message *t_response::copy(void) const { t_sip_message *m = new t_response(*this); MEMMAN_NEW(m); return m; } bool t_response::is_valid(bool &fatal, string &reason) const { if (!t_sip_message::is_valid(fatal, reason)) return false; fatal = false; switch(hdr_cseq.method) { case INVITE: if (get_class() == R_2XX && !hdr_contact.is_populated()) { reason = "Contact header missing"; return false; } break; case SUBSCRIBE: // RFC 3265 7.1, 7.2 /* Some SIP servers do not send the mandatory Expires header. For interoperability this deviation is allowed. if (get_class()== R_2XX && !hdr_expires.is_populated()) { reason = "Expires header missing"; return false; } */ switch (code) { case R_489_BAD_EVENT: if (!hdr_allow_events.is_populated()) { reason = "Allow-Events header missing"; return false; } break; } break; case NOTIFY: // RFC 3265 7.1, 7.2 switch (code) { case R_489_BAD_EVENT: if (!hdr_allow_events.is_populated()) { reason = "Allow-Events header is missing"; return false; } break; } break; default: break; } if (hdr_rseq.is_populated()) { // RFC 3262 7.1 // The value ranges from 1 to 2**32 - 1 if (hdr_rseq.resp_nr == 0) { reason = "RSeq is zero"; return false; } } return true; } bool t_response::must_authenticate(void) const { return (code == R_401_UNAUTHORIZED && hdr_www_authenticate.is_populated() || code == R_407_PROXY_AUTH_REQUIRED && hdr_proxy_authenticate.is_populated()); } void t_response::get_destination(t_ip_port &ip_port) const { assert(hdr_via.is_populated()); if (src_ip_port_request.transport == "tcp") { // RFC 3261 18.2.2 // For TCP the response should be sent on the connection on which // the request was received. So the address returned here is the // alternative destination when the connection is closed already. ip_port = src_ip_port_request; } else { hdr_via.get_response_dst(ip_port); } } void t_response::calc_local_ip(void) { t_ip_port dst; get_destination(dst); if (dst.ipaddr != 0) { local_ip_ = get_src_ip4_address_for_dst(dst.ipaddr); } } twinkle-1.4.2/src/parser/credentials.h0000644000175000001440000000343611127714050014645 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Credentials are used in Proxy-Authorization and // Authorization headers #ifndef _CREDENTIALS_H #define _CREDENTIALS_H #include #include #include "parameter.h" #include "sockets/url.h" using namespace std; class t_digest_response { public: string username; string realm; string nonce; t_url digest_uri; string dresponse; string algorithm; string cnonce; string opaque; string message_qop; unsigned long nonce_count; list auth_params; t_digest_response(); // Set one of the attributes to a value. The parameter p // indicated wich attribute (p.name) should be set to // which value (p.value). // Returns false if p does not contain a valid attribute // setting. bool set_attr(const t_parameter &p); string encode(void) const; }; class t_credentials { public: string auth_scheme; t_digest_response digest_response; // auth_params is used when auth_scheme is not Digest. list auth_params; string encode(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_referred_by.h0000644000175000001440000000262011127714050015467 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RFC 3892 // Referred-By header #ifndef _H_HDR_REFERRED_BY #define _H_HDR_REFERRED_BY #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_referred_by : public t_header { public: string display; // display name t_url uri; string cid; list params; t_hdr_referred_by(); void set_display(const string &d); void set_uri(const string &u); void set_uri(const t_url &u); void set_cid(const string &c); void set_params(const list &l); void add_param(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_rseq.cpp0000644000175000001440000000227011127714057014514 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_rseq.h" #include "util.h" t_hdr_rseq::t_hdr_rseq() : t_header("RSeq") { resp_nr = 0; } void t_hdr_rseq::set_resp_nr(unsigned long l) { populated = true; resp_nr = l; } string t_hdr_rseq::encode_value(void) const { if (!populated) return ""; return ulong2str(resp_nr); } bool t_hdr_rseq::operator==(const t_hdr_rseq &h) const { return (resp_nr == h.resp_nr); } twinkle-1.4.2/src/parser/hdr_warning.cpp0000644000175000001440000000426211127714057015212 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_warning.h" #include "util.h" t_warning::t_warning() { code = 0; port = 0; } t_warning::t_warning(const string &_host, int _port, int _code, string _text) { host = _host; port = _port; code = _code; switch(code) { case 300: text = WARNING_300; break; case 301: text = WARNING_301; break; case 302: text = WARNING_302; break; case 303: text = WARNING_303; break; case 304: text = WARNING_304; break; case 305: text = WARNING_305; break; case 306: text = WARNING_306; break; case 307: text = WARNING_307; break; case 330: text = WARNING_330; break; case 331: text = WARNING_331; break; case 370: text = WARNING_370; break; case 399: text = WARNING_399; break; default: text = "Warning"; } if (_text != "") { text += ": "; text += _text; } } string t_warning::encode(void) const { string s; s = int2str(code, "%3d"); s += ' '; s += host; if (port > 0) s += int2str(port, ":%d"); s += ' '; s += '"'; s += text; s += '"'; return s; } t_hdr_warning::t_hdr_warning() : t_header("Warning") {} void t_hdr_warning::add_warning(const t_warning &w) { populated = true; warnings.push_back(w); } string t_hdr_warning::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = warnings.begin(); i != warnings.end(); i++) { if (i != warnings.begin()) s += ", "; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_timestamp.h0000644000175000001440000000215711127714050015207 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Timestamp header #ifndef _H_HDR_TIMESTAMP #define _H_HDR_TIMESTAMP #include #include "header.h" using namespace std; class t_hdr_timestamp : public t_header { public: float timestamp; float delay; t_hdr_timestamp(); void set_timestamp(float t); void set_delay(float d); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_auth_info.h0000644000175000001440000000254711127714050015163 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Authentication-Info header #ifndef _HDR_AUTH_INFO_H #define _HDR_AUTH_INFO_H #include #include "header.h" using namespace std; class t_hdr_auth_info : public t_header { public: string next_nonce; string message_qop; string response_auth; string cnonce; unsigned long nonce_count; t_hdr_auth_info(); void set_next_nonce(const string &nn); void set_message_qop(const string &mq); void set_response_auth(const string &ra); void set_cnonce(const string &cn); void set_nonce_count(const unsigned long &nc); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_date.h0000644000175000001440000000222111127714050014111 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Date header #ifndef _HDR_DATE_H #define _HDR_DATE_H #include #include #include "header.h" class t_hdr_date : public t_header { public: time_t date; t_hdr_date(); void set_date_gm(struct tm *tm); // set date, tm is GMT void set_now(void); // Set date/time to current date/time string encode_value(void) const; }; using namespace std; #endif twinkle-1.4.2/src/parser/hdr_subject.h0000644000175000001440000000210111127714050014630 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Subject header #ifndef _H_HDR_SUBJECT #define _H_HDR_SUBJECT #include #include "header.h" using namespace std; class t_hdr_subject : public t_header { public: string subject; t_hdr_subject(); void set_subject(const string &s); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_contact.h0000644000175000001440000000565311127714050014643 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Contact header #ifndef _HDR_CONTACT #define _HDR_CONTACT #include #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_contact_param { private: bool expires_present; unsigned long expires; bool qvalue_present; float qvalue; public: string display; // display name t_url uri; list extensions; t_contact_param(); void add_extension(const t_parameter &p); string encode(void) const; bool is_expires_present(void) const; unsigned long get_expires(void) const; void set_expires(unsigned long e); float get_qvalue(void) const; void set_qvalue(float q); // Compare contacts on q-value. // The contacts with the highest q-value comes first in the order bool operator<(const t_contact_param &c) const; }; class t_hdr_contact : public t_header { public: bool any_flag; // true if Contact: * list contact_list; t_hdr_contact(); void add_contact(const t_contact_param &contact); void add_contacts(const list &l); void set_contacts(const list &l); /** * Set the contact list to a sequence of URI's with display names. * The URI's are give a descending q-value starting at 0.9 * Each subsequent URI gets a q-value 0.1 less than the previous * URI. If more than 9 URI's are passed then the tail of URI's all * get a q-value of 0.1. * * @param l [in] The list of URI's to be put in the contact list. */ void set_contacts(const list &l); /** * Set the contact list to a sequence of URI's with display names. * The URI's are give a descending q-value starting at 0.9 * Each subsequent URI gets a q-value 0.1 less than the previous * URI. If more than 9 URI's are passed then the tail of URI's all * get a q-value of 0.1. * * @param l [in] The list of URI's to be put in the contact list. */ void set_contacts(const list &l); // Set contact to any, eg. Contact: * void set_any(void); // Find contact with uri u. If no contact is found, then // NULL is returned. t_contact_param *find_contact(const t_url &u); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_cseq.h0000644000175000001440000000243611127714050014137 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // CSeq header #ifndef _HDR_CSEQ #define _HDR_CSEQ #include #include "header.h" #include "definitions.h" using namespace std; class t_hdr_cseq : public t_header { public: unsigned long seqnr; t_method method; string unknown_method; // set if method is UNKNOWN t_hdr_cseq(); void set_seqnr(unsigned long l); void set_method(t_method m, const string &unknown = ""); void set_method(const string &s); string encode_value(void) const; bool operator==(const t_hdr_cseq &h) const; }; #endif twinkle-1.4.2/src/parser/hdr_content_type.h0000644000175000001440000000211111127714050015705 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Content-Type header #ifndef _HDR_CONTENT_TYPE_H #define _HDR_CONTENT_TYPE_H #include "header.h" #include "media_type.h" class t_hdr_content_type : public t_header { public: t_media media; t_hdr_content_type(); void set_media(const t_media &m); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_accept_encoding.cpp0000644000175000001440000000246611127714057016656 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_accept_encoding.h" #include "definitions.h" t_hdr_accept_encoding::t_hdr_accept_encoding() : t_header("Accept-Encoding") {}; void t_hdr_accept_encoding::add_coding(const t_coding &coding) { populated = true; coding_list.push_back(coding); } string t_hdr_accept_encoding::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = coding_list.begin(); i != coding_list.end(); i++) { if (i != coding_list.begin()) s += ","; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/hdr_service_route.cpp0000644000175000001440000000335411127714057016424 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_service_route.h" #include "parse_ctrl.h" #include "util.h" t_hdr_service_route::t_hdr_service_route() : t_header("Service-Route") {} void t_hdr_service_route::add_route(const t_route &r) { populated = true; route_list.push_back(r); } string t_hdr_service_route::encode(void) const { return (t_parser::multi_values_as_list ? t_header::encode() : encode_multi_header()); } string t_hdr_service_route::encode_multi_header(void) const { string s; if (!populated) return s; for (list::const_iterator i = route_list.begin(); i != route_list.end(); i++) { s += header_name; s += ": "; s += i->encode(); s += CRLF; } return s; } string t_hdr_service_route::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = route_list.begin(); i != route_list.end(); i++) { if (i != route_list.begin()) s += ","; s += i->encode(); } return s; } twinkle-1.4.2/src/parser/header.h0000644000175000001440000000365311127714050013601 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Base class for message and response headers #ifndef _HEADER_H #define _HEADER_H #include using namespace std; class t_header { private: t_header(); protected: bool populated; // true = header is populated string header_name; // Full name of header in SIP messages string compact_name; // Compact name of header in SIP messages public: virtual ~t_header() {} t_header(const string &_header_name, const string &_compact_name = ""); // Return the text encoded header (CRLF at end of string) virtual string encode(void) const; // Return the text encoded value part (no CRLF at end of string) virtual string encode_value(void) const = 0; // Return a environemnt variable setting // The format of the setting is: // // SIP_
= // // The header name is in capitals. Dashes are replaced by underscores. virtual string encode_env(void) const; // Get the header name string get_name(void) const; // Get text encoding of the header value only. // I.e. without header name and no trailing CRLF string get_value(void) const; // Return true if the header is populated bool is_populated(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_retry_after.cpp0000644000175000001440000000315411127714057016072 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_retry_after.h" #include "util.h" t_hdr_retry_after::t_hdr_retry_after() : t_header("Retry-After") { time = 0; duration = 0; } void t_hdr_retry_after::set_time(unsigned long t) { populated = true; time = t; } void t_hdr_retry_after::set_comment(const string &c) { populated = true; comment = c; } void t_hdr_retry_after::set_duration(unsigned long d) { populated = true; duration = d; } void t_hdr_retry_after::add_param(const t_parameter &p) { populated = true; params.push_back(p); } string t_hdr_retry_after::encode_value(void) const { string s; if (!populated) return s; s = ulong2str(time); if (comment.size() > 0) { s += " ("; s += comment; s += ')'; } if (duration > 0) { s += ";duration="; s += ulong2str(duration); } s += param_list2str(params); return s; } twinkle-1.4.2/src/parser/hdr_allow_events.h0000644000175000001440000000220111127714050015674 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Allow-Events header // RFC 3265 #ifndef _HDR_ALLOW_EVENTS #define _HDR_ALLOW_EVENTS #include #include #include "header.h" using namespace std; class t_hdr_allow_events : public t_header { public: list event_types; t_hdr_allow_events(); void add_event_type(const string &t); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_require.cpp0000644000175000001440000000350611127714057015221 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "hdr_require.h" t_hdr_require::t_hdr_require() : t_header("Require") {}; void t_hdr_require::add_feature(const string &f) { populated = true; if (!contains(f)) { features.push_back(f); } } void t_hdr_require::add_features(const list &l) { if (l.empty()) return; for (list::const_iterator i = l.begin(); i != l.end(); i++) { add_feature(*i); } populated = true; } void t_hdr_require::del_feature(const string &f) { features.remove(f); } bool t_hdr_require::contains(const string &f) const { if (!populated) return false; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (*i == f) return true; } return false; } string t_hdr_require::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = features.begin(); i != features.end(); i++) { if (i != features.begin()) s += ", "; s += *i; } return s; } void t_hdr_require::unpopulate(void) { populated = false; features.clear(); } twinkle-1.4.2/src/parser/hdr_from.h0000644000175000001440000000330311127714050014141 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // From header #ifndef _H_HDR_FROM #define _H_HDR_FROM #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_from : public t_header { public: string display; // display name // The display_override may be set by the UA to display another // name to the user, then the display name received in the // signalling, e.g. a lookup from an address book. This value // does NOT appear in the SIP message. string display_override; t_url uri; string tag; list params; t_hdr_from(); void set_display(const string &d); void set_uri(const string &u); void set_uri(const t_url &u); void set_tag(const string &t); void set_params(const list &l); void add_param(const t_parameter &p); string encode_value(void) const; // Get the display name to show to the user. string get_display_presentation(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_event.cpp0000644000175000001440000000255011127714057014664 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_event.h" #include "parse_ctrl.h" t_hdr_event::t_hdr_event() : t_header("Event", "o") {} void t_hdr_event::set_event_type(const string &t) { populated = true; event_type = t; } void t_hdr_event::set_id(const string &s) { populated = true; id = s; } void t_hdr_event::add_event_param(const t_parameter &p) { populated = true; event_params.push_back(p); } string t_hdr_event::encode_value(void) const { string s; if (!populated) return s; s += event_type; if (id.size() > 0) { s += ";id="; s += id; } s += param_list2str(event_params); return s; } twinkle-1.4.2/src/parser/milenage.cpp0000644000175000001440000001613511127714057014473 00000000000000/*------------------------------------------------------------------- * Example algorithms f1, f1*, f2, f3, f4, f5, f5* *------------------------------------------------------------------- * * A sample implementation of the example 3GPP authentication and * key agreement functions f1, f1*, f2, f3, f4, f5 and f5*. This is * a byte-oriented implementation of the functions, and of the block * cipher kernel function Rijndael. * * This has been coded for clarity, not necessarily for efficiency. * * The functions f2, f3, f4 and f5 share the same inputs and have * been coded together as a single function. f1, f1* and f5* are * all coded separately. * *-----------------------------------------------------------------*/ #include "milenage.h" #include "rijndael.h" /*--------------------------- prototypes --------------------------*/ /*------------------------------------------------------------------- * Algorithm f1 *------------------------------------------------------------------- * * Computes network authentication code MAC-A from key K, random * challenge RAND, sequence number SQN and authentication management * field AMF. * *-----------------------------------------------------------------*/ void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], u8 mac_a[8], u8 op[16] ) { u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); ComputeOPc( op_c, op ); for (i=0; i<16; i++) rijndaelInput[i] = rand[i] ^ op_c[i]; RijndaelEncrypt( rijndaelInput, temp ); for (i=0; i<6; i++) { in1[i] = sqn[i]; in1[i+8] = sqn[i]; } for (i=0; i<2; i++) { in1[i+6] = amf[i]; in1[i+14] = amf[i]; } /* XOR op_c and in1, rotate by r1=64, and XOR * * on the constant c1 (which is all zeroes) */ for (i=0; i<16; i++) rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i]; /* XOR on the value temp computed before */ for (i=0; i<16; i++) rijndaelInput[i] ^= temp[i]; RijndaelEncrypt( rijndaelInput, out1 ); for (i=0; i<16; i++) out1[i] ^= op_c[i]; for (i=0; i<8; i++) mac_a[i] = out1[i]; return; } /* end of function f1 */ /*------------------------------------------------------------------- * Algorithms f2-f5 *------------------------------------------------------------------- * * Takes key K and random challenge RAND, and returns response RES, * confidentiality key CK, integrity key IK and anonymity key AK. * *-----------------------------------------------------------------*/ void f2345 ( u8 k[16], u8 rand[16], u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] ) { u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); ComputeOPc( op_c, op ); for (i=0; i<16; i++) rijndaelInput[i] = rand[i] ^ op_c[i]; RijndaelEncrypt( rijndaelInput, temp ); /* To obtain output block OUT2: XOR OPc and TEMP, * * rotate by r2=0, and XOR on the constant c2 (which * * is all zeroes except that the last bit is 1). */ for (i=0; i<16; i++) rijndaelInput[i] = temp[i] ^ op_c[i]; rijndaelInput[15] ^= 1; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) out[i] ^= op_c[i]; for (i=0; i<8; i++) res[i] = out[i+8]; for (i=0; i<6; i++) ak[i] = out[i]; /* To obtain output block OUT3: XOR OPc and TEMP, * * rotate by r3=32, and XOR on the constant c3 (which * * is all zeroes except that the next to last bit is 1). */ for (i=0; i<16; i++) rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i]; rijndaelInput[15] ^= 2; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) out[i] ^= op_c[i]; for (i=0; i<16; i++) ck[i] = out[i]; /* To obtain output block OUT4: XOR OPc and TEMP, * * rotate by r4=64, and XOR on the constant c4 (which * * is all zeroes except that the 2nd from last bit is 1). */ for (i=0; i<16; i++) rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i]; rijndaelInput[15] ^= 4; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) out[i] ^= op_c[i]; for (i=0; i<16; i++) ik[i] = out[i]; return; } /* end of function f2345 */ /*------------------------------------------------------------------- * Algorithm f1* *------------------------------------------------------------------- * * Computes resynch authentication code MAC-S from key K, random * challenge RAND, sequence number SQN and authentication management * field AMF. * *-----------------------------------------------------------------*/ void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], u8 mac_s[8], u8 op[16] ) { u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); ComputeOPc( op_c, op ); for (i=0; i<16; i++) rijndaelInput[i] = rand[i] ^ op_c[i]; RijndaelEncrypt( rijndaelInput, temp ); for (i=0; i<6; i++) { in1[i] = sqn[i]; in1[i+8] = sqn[i]; } for (i=0; i<2; i++) { in1[i+6] = amf[i]; in1[i+14] = amf[i]; } /* XOR op_c and in1, rotate by r1=64, and XOR * * on the constant c1 (which is all zeroes) */ for (i=0; i<16; i++) rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i]; /* XOR on the value temp computed before */ for (i=0; i<16; i++) rijndaelInput[i] ^= temp[i]; RijndaelEncrypt( rijndaelInput, out1 ); for (i=0; i<16; i++) out1[i] ^= op_c[i]; for (i=0; i<8; i++) mac_s[i] = out1[i+8]; return; } /* end of function f1star */ /*------------------------------------------------------------------- * Algorithm f5* *------------------------------------------------------------------- * * Takes key K and random challenge RAND, and returns resynch * anonymity key AK. * *-----------------------------------------------------------------*/ void f5star( u8 k[16], u8 rand[16], u8 ak[6], u8 op[16] ) { u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); ComputeOPc( op_c, op ); for (i=0; i<16; i++) rijndaelInput[i] = rand[i] ^ op_c[i]; RijndaelEncrypt( rijndaelInput, temp ); /* To obtain output block OUT5: XOR OPc and TEMP, * * rotate by r5=96, and XOR on the constant c5 (which * * is all zeroes except that the 3rd from last bit is 1). */ for (i=0; i<16; i++) rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i]; rijndaelInput[15] ^= 8; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) out[i] ^= op_c[i]; for (i=0; i<6; i++) ak[i] = out[i]; return; } /* end of function f5star */ /*------------------------------------------------------------------- * Function to compute OPc from OP and K. Assumes key schedule has already been performed. *-----------------------------------------------------------------*/ void ComputeOPc( u8 op_c[16], u8 op[16] ) { u8 i; RijndaelEncrypt( op, op_c ); for (i=0; i<16; i++) op_c[i] ^= op[i]; return; } /* end of function ComputeOPc */ twinkle-1.4.2/src/parser/hdr_authorization.cpp0000644000175000001440000000451711127714057016450 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_authorization.h" #include "definitions.h" t_hdr_authorization::t_hdr_authorization() : t_header("Authorization") {} void t_hdr_authorization::add_credentials(const t_credentials &c) { populated = true; credentials_list.push_back(c); } string t_hdr_authorization::encode(void) const { string s; if (!populated) return s; // RFC 3261 20.7 // Each authorization should appear as a separate header for (list::const_iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { s += header_name; s += ": "; s += i->encode(); s += CRLF; } return s; } string t_hdr_authorization::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { if (i != credentials_list.begin()) s += ", "; s += i->encode(); } return s; } bool t_hdr_authorization::contains(const string &realm, const t_url &uri) const { for (list::const_iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { if (i->digest_response.realm == realm && i->digest_response.digest_uri == uri) { return true; } } return false; } void t_hdr_authorization::remove_credentials(const string &realm, const t_url &uri) { for (list::iterator i = credentials_list.begin(); i != credentials_list.end(); i++) { if (i->digest_response.realm == realm && i->digest_response.digest_uri == uri) { credentials_list.erase(i); return; } } } twinkle-1.4.2/src/parser/hdr_date.cpp0000644000175000001440000000315611127714057014463 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // NOTE: the date functions are not thread safe #include #include "hdr_date.h" #include "definitions.h" #include "util.h" t_hdr_date::t_hdr_date() : t_header("Date") {} void t_hdr_date::set_date_gm(struct tm *tm) { populated = true; date = timegm(tm); } void t_hdr_date::set_now(void) { struct timeval t; populated = true; gettimeofday(&t, NULL); date = t.tv_sec; } string t_hdr_date::encode_value(void) const { string s; struct tm tm; if (!populated) return s; gmtime_r(&date, &tm); s = weekday2str(tm.tm_wday); s += ", "; s += int2str(tm.tm_mday, "%02d"); s += ' '; s += month2str(tm.tm_mon); s += ' '; s += int2str(tm.tm_year + 1900, "%04d"); s += ' '; s += int2str(tm.tm_hour, "%02d"); s += ':'; s += int2str(tm.tm_min, "%02d"); s += ':'; s += int2str(tm.tm_sec, "%02d"); s += " GMT"; return s; } twinkle-1.4.2/src/parser/hdr_www_authenticate.h0000644000175000001440000000224611127714050016565 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // WWW-Authenticate header #ifndef _HDR_WWW_AUTHENTICATE_H #define _HDR_WWW_AUTHENTICATE_H #include #include #include "challenge.h" #include "header.h" using namespace std; class t_hdr_www_authenticate : public t_header { public: t_challenge challenge; t_hdr_www_authenticate(); void set_challenge(const t_challenge &c); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_accept_language.h0000644000175000001440000000257611127714050016313 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Accept_Language header #ifndef _HDR_ACCEPT_LANGUAGE_H #define _HDR_ACCEPT_LANGUAGE_H #include #include #include "header.h" using namespace std; class t_language { public: string language; float q; // quality factor t_language(); t_language(const string &l); string encode(void) const; }; class t_hdr_accept_language : public t_header { public: list language_list; // list of accepted languages t_hdr_accept_language(); // Add a language to the list of accepted media void add_language(const t_language &language); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/header.cpp0000644000175000001440000000361211134633313014127 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "header.h" #include "parse_ctrl.h" #include "protocol.h" #include "util.h" t_header::t_header() : populated(false) {} t_header::t_header(const string &_header_name, const string &_compact_name) : populated(false), header_name(_header_name), compact_name(_compact_name) {} string t_header::encode(void) const { string s; if (!populated) return s; s = (t_parser::compact_headers && !compact_name.empty() ? compact_name : header_name); s += ": "; s += encode_value(); s += CRLF; return s; } string t_header::encode_env(void) const { string s("SIP_"); s += toupper(replace_char(header_name, '-', '_')); s += '='; s += encode_value(); return s; } bool t_header::is_populated() const { return populated; } string t_header::get_name(void) const { return header_name; } string t_header::get_value(void) const { string s; string::size_type i; if (!populated) return s; s = encode(); i = s.find(':'); // The colon cannot be the first or last character if (i == string::npos || i == s.size()-1) return ""; s = s.substr(i+1); i = s.find(CRLF); s = s.substr(0, i); return (trim(s)); } twinkle-1.4.2/src/parser/hdr_in_reply_to.cpp0000644000175000001440000000237711127714057016075 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_in_reply_to.h" #include "definitions.h" t_hdr_in_reply_to::t_hdr_in_reply_to() : t_header("In-Reply-To") {}; void t_hdr_in_reply_to::add_call_id(const string &id) { populated = true; call_ids.push_back(id); } string t_hdr_in_reply_to::encode_value(void) const { string s; if (!populated) return s; for (list::const_iterator i = call_ids.begin(); i != call_ids.end(); i++) { if (i != call_ids.begin()) s += ", "; s += *i; } return s; } twinkle-1.4.2/src/parser/challenge.cpp0000644000175000001440000000750111127714057014631 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "challenge.h" #include "definitions.h" #include "log.h" #include "util.h" t_digest_challenge::t_digest_challenge() { stale = false; // The default algorithm is MD5. algorithm = ALG_MD5; } string t_digest_challenge::encode(void) const { string s; if (realm.size() > 0) { if (s.size() > 0) s += ','; s += "realm="; s += '"'; s += realm; s += '"'; } if (domain.size() > 0) { if (s.size() > 0) s += ','; s += "domain="; s += '"'; for (list::const_iterator i = domain.begin(); i != domain.end(); i++) { if (i != domain.begin()) s += ' '; s += i->encode(); } s += '"'; } if (nonce.size() > 0) { if (s.size() > 0) s += ','; s += "nonce="; s += '"'; s += nonce; s += '"'; } if (opaque.size() > 0) { if (s.size() > 0) s += ','; s += "opaque="; s += '"'; s += opaque; s += '"'; } // RFC 2617 3.2.1 // If the stale flag is absent it means stale=false. if (stale) { if (s.size() > 0) s += ','; s += "stale=true"; } if (algorithm.size() > 0) { if (s.size() > 0) s += ','; s += "algorithm="; s += algorithm; } if (qop_options.size() > 0) { if (s.size() > 0) s += ','; s += "qop="; s += '"'; for (list::const_iterator i = qop_options.begin(); i != qop_options.end(); i++) { if (i != qop_options.begin()) s += ','; s += *i; } s += '"'; } for (list::const_iterator i = auth_params.begin(); i != auth_params.end(); i++) { if (s.size() > 0) s += ','; s += i->encode(); } return s; } bool t_digest_challenge::set_attr(const t_parameter &p) { if (p.name == "realm") realm = p.value; else if (p.name == "nonce") nonce = p.value; else if (p.name == "opaque") opaque = p.value; else if (p.name == "algorithm") algorithm = p.value; else if (p.name == "domain") { vector l = split_ws(p.value); for (vector::iterator i = l.begin(); i != l.end(); i++) { t_url u(*i); if (u.is_valid()) { domain.push_back(u); } else { log_file->write_header("t_digest_challenge::set_attr", LOG_SIP, LOG_WARNING); log_file->write_raw("Invalid domain in digest challenge: "); log_file->write_raw(*i); log_file->write_endl(); log_file->write_footer(); } } } else if (p.name == "qop") { vector l = split(p.value, ','); for (vector::iterator i = l.begin(); i != l.end(); i++) { qop_options.push_back(trim(*i)); } } else if (p.name == "stale") { if (cmp_nocase(p.value, "true") == 0) stale = true; else // RFC 2617 3.2.1 // Any value other than false should be interpreted // as false. stale = false; } else auth_params.push_back(p); return true; } string t_challenge::encode(void) const { string s = auth_scheme; s += ' '; if (auth_scheme == AUTH_DIGEST) { s += digest_challenge.encode(); } else { for (list::const_iterator i = auth_params.begin(); i != auth_params.end(); i++) { if (i != auth_params.begin()) s += ','; s += i->encode(); } } return s; } twinkle-1.4.2/src/parser/hdr_sip_if_match.cpp0000644000175000001440000000222311127714057016165 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_sip_if_match.h" t_hdr_sip_if_match::t_hdr_sip_if_match() : t_header("SIP-If-Match") {}; void t_hdr_sip_if_match::set_etag(const string &_etag) { populated = true; etag = _etag; } string t_hdr_sip_if_match::encode_value(void) const { if (!populated) return ""; return etag; } void t_hdr_sip_if_match::clear(void) { etag.clear(); populated = false; } twinkle-1.4.2/src/parser/hdr_accept_encoding.h0000644000175000001440000000235611127714050016312 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Accept-Encoding header #ifndef _HDR_ACCEPT_ENCODING_H #define _HDR_ACCEPT_ENCODING_H #include #include #include "coding.h" #include "header.h" using namespace std; class t_hdr_accept_encoding : public t_header { public: list coding_list; // list of content codings; t_hdr_accept_encoding(); // Add a coding to the list of content codings void add_coding(const t_coding &coding); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_to.h0000644000175000001440000000252711127714050013627 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // To header #ifndef _H_HDR_TO #define _H_HDR_TO #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_hdr_to : public t_header { public: string display; // display name t_url uri; string tag; list params; t_hdr_to(); void set_display(const string &d); void set_uri(const string &u); void set_uri(const t_url &u); void set_tag(const string &t); void set_params(const list &l); void add_param(const t_parameter &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_sip_etag.h0000644000175000001440000000237111127714050014775 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * SIP-ETag header (RFC 3903) */ #ifndef _HDR_SIP_ETAG_H #define _HDR_SIP_ETAG_H #include #include "header.h" using namespace std; /** SIP-ETag header (RFC 3903) */ class t_hdr_sip_etag : public t_header { public: string etag; /**< Entity tag. */ /** Constructor. */ t_hdr_sip_etag(); /** * Set entity tag. * @param _etag [in] Entity tag to set. */ void set_etag(const string &_etag); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_require.h0000644000175000001440000000232111127714050014651 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Require header #ifndef _H_HDR_REQUIRE #define _H_HDR_REQUIRE #include #include #include "header.h" class t_hdr_require : public t_header { public: list features; t_hdr_require(); void add_feature(const string &f); void add_features(const list &l); void del_feature(const string &f); bool contains(const string &f) const; string encode_value(void) const; void unpopulate(void); }; #endif twinkle-1.4.2/src/parser/hdr_refer_sub.h0000644000175000001440000000241011127714050015150 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Refer-Sub header // RFC 4488 #ifndef _H_HDR_REFER_SUB #define _H_HDR_REFER_SUB #include #include #include "header.h" #include "parameter.h" using namespace std; class t_hdr_refer_sub : public t_header { public: bool create_refer_sub; list extensions; t_hdr_refer_sub(); void set_create_refer_sub(bool on); void add_extension(const t_parameter &p); void set_extensions(const list &l); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_call_id.cpp0000644000175000001440000000214111127714057015126 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_call_id.h" #include "definitions.h" #include "parse_ctrl.h" t_hdr_call_id::t_hdr_call_id() : t_header("Call-ID", "i") {}; void t_hdr_call_id::set_call_id(const string &id) { populated = true; call_id = id; } string t_hdr_call_id::encode_value(void) const { if (!populated) return ""; return call_id; } twinkle-1.4.2/src/parser/coding.cpp0000644000175000001440000000210211127714057014142 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "coding.h" #include "util.h" t_coding::t_coding() { q = 1.0; } t_coding::t_coding(const string &s) { q = 1.0; content_coding = s; } string t_coding::encode(void) const { string s; s = content_coding; if (q != 1.0) { s += ";q="; s += float2str(q, 1); } return s; } twinkle-1.4.2/src/parser/hdr_sip_if_match.h0000644000175000001440000000250011127714050015621 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * SIP-If-Match header (RFC 3903) */ #ifndef _HDR_SIP_IF_MATCH_H #define _HDR_SIP_IF_MATCH_H #include #include "header.h" using namespace std; /** SIP-If-Match header (RFC 3903) */ class t_hdr_sip_if_match : public t_header { public: string etag; /**< Entity tag. */ /** Constructor. */ t_hdr_sip_if_match(); /** * Set entity tag. * @param _etag [in] Entity tag to set. */ void set_etag(const string &_etag); /** Clear the header. */ void clear(void); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_organization.h0000644000175000001440000000212411127714050015702 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Organization header #ifndef _H_HDR_ORGANIZATION #define _H_HDR_ORGANIZATION #include #include "header.h" using namespace std; class t_hdr_organization : public t_header { public: string name; t_hdr_organization(); void set_name(const string &n); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_call_info.h0000644000175000001440000000255511127714050015134 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Call-Info header #ifndef _HDR_CALL_INFO_H #define _HDR_CALL_INFO_H #include #include #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; class t_info_param { public: t_url uri; list parameter_list; void add_param(const t_parameter &p); string encode(void) const; }; class t_hdr_call_info : public t_header { public: list info_param_list; t_hdr_call_info(); // Add a paramter to the list of alert parameters void add_param(const t_info_param &p); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_www_authenticate.cpp0000644000175000001440000000221411127714057017122 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hdr_www_authenticate.h" #include "definitions.h" t_hdr_www_authenticate::t_hdr_www_authenticate() : t_header("WWW-Authenticate") {} void t_hdr_www_authenticate::set_challenge(const t_challenge &c) { populated = true; challenge = c; } string t_hdr_www_authenticate::encode_value(void) const { if (!populated) return ""; return challenge.encode(); } twinkle-1.4.2/src/parser/hdr_content_language.h0000644000175000001440000000237711127714050016525 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Content_Language header #ifndef _HDR_CONTENT_LANGUAGE_H #define _HDR_CONTENT_LANGUAGE_H #include #include #include "header.h" #include "hdr_accept_language.h" using namespace std; class t_hdr_content_language : public t_header { public: list language_list; // list of languages t_hdr_content_language(); // Add a language to the list of languages void add_language(const t_language &language); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/sip_message.h0000644000175000001440000002025711142375773014663 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // SIP message #ifndef _H_SIP_MESSAGE #define _H_SIP_MESSAGE #include #include #include "definitions.h" #include "hdr_accept.h" #include "hdr_accept_encoding.h" #include "hdr_accept_language.h" #include "hdr_alert_info.h" #include "hdr_allow.h" #include "hdr_allow_events.h" #include "hdr_auth_info.h" #include "hdr_authorization.h" #include "hdr_call_id.h" #include "hdr_call_info.h" #include "hdr_contact.h" #include "hdr_content_disp.h" #include "hdr_content_encoding.h" #include "hdr_content_language.h" #include "hdr_content_length.h" #include "hdr_content_type.h" #include "hdr_cseq.h" #include "hdr_date.h" #include "hdr_error_info.h" #include "hdr_event.h" #include "hdr_expires.h" #include "hdr_from.h" #include "hdr_in_reply_to.h" #include "hdr_max_forwards.h" #include "hdr_min_expires.h" #include "hdr_mime_version.h" #include "hdr_organization.h" #include "hdr_p_asserted_identity.h" #include "hdr_p_preferred_identity.h" #include "hdr_priority.h" #include "hdr_privacy.h" #include "hdr_proxy_authenticate.h" #include "hdr_proxy_authorization.h" #include "hdr_proxy_require.h" #include "hdr_rack.h" #include "hdr_record_route.h" #include "hdr_refer_sub.h" #include "hdr_refer_to.h" #include "hdr_referred_by.h" #include "hdr_replaces.h" #include "hdr_reply_to.h" #include "hdr_require.h" #include "hdr_request_disposition.h" #include "hdr_retry_after.h" #include "hdr_route.h" #include "hdr_rseq.h" #include "hdr_server.h" #include "hdr_service_route.h" #include "hdr_sip_etag.h" #include "hdr_sip_if_match.h" #include "hdr_subject.h" #include "hdr_subscription_state.h" #include "hdr_supported.h" #include "hdr_timestamp.h" #include "hdr_to.h" #include "hdr_unsupported.h" #include "hdr_user_agent.h" #include "hdr_via.h" #include "hdr_warning.h" #include "hdr_www_authenticate.h" #include "parameter.h" #include "sip_body.h" // Macro's to access the body of a message, eg msg.sdp_body #define SDP_BODY ((t_sdp *)body) #define OPAQUE_BODY ((t_sip_body_opaque)*body) using namespace std; enum t_msg_type { MSG_REQUEST, MSG_RESPONSE, MSG_SIPFRAG, // Only a sequence of headers (RFC 3420) }; class t_sip_message { protected: /** * Local IP address that will be uses for this SIP message. * The local IP address can only be determined when the destination * of a SIP message is known (because of multi homing). */ unsigned long local_ip_; public: // The source IP address and port are only set for messages // received from the network. So the transaction user knows // where a message comes from. t_ip_port src_ip_port; // SIP version string version; // All possible headers t_hdr_accept hdr_accept; t_hdr_accept_encoding hdr_accept_encoding; t_hdr_accept_language hdr_accept_language; t_hdr_alert_info hdr_alert_info; t_hdr_allow hdr_allow; t_hdr_allow_events hdr_allow_events; t_hdr_auth_info hdr_auth_info; t_hdr_authorization hdr_authorization; t_hdr_call_id hdr_call_id; t_hdr_call_info hdr_call_info; t_hdr_contact hdr_contact; t_hdr_content_disp hdr_content_disp; t_hdr_content_encoding hdr_content_encoding; t_hdr_content_language hdr_content_language; t_hdr_content_length hdr_content_length; t_hdr_content_type hdr_content_type; t_hdr_cseq hdr_cseq; t_hdr_date hdr_date; t_hdr_error_info hdr_error_info; t_hdr_event hdr_event; t_hdr_expires hdr_expires; t_hdr_from hdr_from; t_hdr_in_reply_to hdr_in_reply_to; t_hdr_max_forwards hdr_max_forwards; t_hdr_min_expires hdr_min_expires; t_hdr_mime_version hdr_mime_version; t_hdr_organization hdr_organization; t_hdr_p_asserted_identity hdr_p_asserted_identity; t_hdr_p_preferred_identity hdr_p_preferred_identity; t_hdr_priority hdr_priority; t_hdr_privacy hdr_privacy; t_hdr_proxy_authenticate hdr_proxy_authenticate; t_hdr_proxy_authorization hdr_proxy_authorization; t_hdr_proxy_require hdr_proxy_require; t_hdr_rack hdr_rack; t_hdr_record_route hdr_record_route; t_hdr_refer_sub hdr_refer_sub; t_hdr_refer_to hdr_refer_to; t_hdr_referred_by hdr_referred_by; t_hdr_replaces hdr_replaces; t_hdr_reply_to hdr_reply_to; t_hdr_require hdr_require; t_hdr_request_disposition hdr_request_disposition; t_hdr_retry_after hdr_retry_after; t_hdr_route hdr_route; t_hdr_rseq hdr_rseq; t_hdr_server hdr_server; t_hdr_service_route hdr_service_route; t_hdr_sip_etag hdr_sip_etag; t_hdr_sip_if_match hdr_sip_if_match; t_hdr_subject hdr_subject; t_hdr_subscription_state hdr_subscription_state; t_hdr_supported hdr_supported; t_hdr_timestamp hdr_timestamp; t_hdr_to hdr_to; t_hdr_unsupported hdr_unsupported; t_hdr_user_agent hdr_user_agent; t_hdr_via hdr_via; t_hdr_warning hdr_warning; t_hdr_www_authenticate hdr_www_authenticate; // Unknown headers are represented by parameters. // Parameter.name = header name // Parameter.value = header value list unknown_headers; // A SIP message can carry a body t_sip_body *body; t_sip_message(); t_sip_message(const t_sip_message& m); virtual ~t_sip_message(); virtual t_msg_type get_type(void) const; void add_unknown_header(const string &name, const string &value); // Check if the message is valid. At this class the // general rules applying to both requests and responses // is checked. // fatal is true if one of the headers mandatory for all // messages is missing (to, from, cseq, call-id, via). // reason contains a reason string if the message is invalid. virtual bool is_valid(bool &fatal, string &reason) const; // Return encoded headers // The version should be encode by the subclasses. // Parameter add_content_length indicates if a Content-Length // header must be added. Usually it must, only for sipfrag bodies // it may be omitted. virtual string encode(bool add_content_length = true); // Return list of environment variable settings for all headers // (see header.h for the format) // Besides the header variables the following variables will be // returned as well: // // SIP_REQUEST_METHOD, for a request // SIP_REQUEST_URI, for a request // SIP_STATUS_CODE, for a response // SIP_STATUS_REASON, for a response virtual list encode_env(void); // Create a copy of the message virtual t_sip_message *copy(void) const; /** * Set a plain text body in the message. * @param text [in] The text. * @param charset [in] The character set used for encoding. * @post The Content-Type header is set to "text/plain". * @post If a body was already present then it is deleted. */ void set_body_plain_text(const string &text, const string &charset); /** * Set a body with the contents of a file. * @param filename [in] The name of the file. * @param media [in] The mime type of the contents. * @return True of body is set, false if file could not be read. */ bool set_body_from_file(const string &filename, const t_media &media); /** * Get the size of an encoded SIP message. * @return Size in bytes. */ size_t get_encoded_size(void); /** * Check if all local IP address are correctly filled in. This * check is an integrity check to help debugging the auto IP * discover feature. */ bool local_ip_check(void) const; /** Determine the local IP address for this SIP message. */ virtual void calc_local_ip(void); /** * Get the local IP address for this SIP message. * The local IP address can be used as source address for sending * the message. * @return The local IP address. * @return 0, if the local IP address is not determined yet. */ unsigned long get_local_ip(void); }; #endif twinkle-1.4.2/src/parser/hdr_max_forwards.h0000644000175000001440000000214311127714050015673 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Max-Forwards header #ifndef _HDR_MAX_FORWARDS_LENGTH #define _HDR_MAX_FORWARDS_LENGTH #include #include "header.h" using namespace std; class t_hdr_max_forwards : public t_header { public: int max_forwards; t_hdr_max_forwards(); void set_max_forwards(int m); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_supported.h0000644000175000001440000000265411127714050015233 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Supported header #ifndef _H_HDR_SUPPORTED #define _H_HDR_SUPPORTED #include #include #include "header.h" #define EXT_100REL "100rel" // RFC 3262 #define EXT_REPLACES "replaces" // RFC 3891 #define EXT_NOREFERSUB "norefersub" // RFC 4488 class t_hdr_supported : public t_header { public: list features; t_hdr_supported(); void add_feature(const string &f); void add_features(const list &l); // Clear the list of features, but make the header 'populated'. // An empty header will be in the message. void set_empty(void); bool contains(const string &f) const; string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_rack.h0000644000175000001440000000247411127714050014126 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // RAck header // RFC 3262 #ifndef _HDR_RACK #define _HDR_RACK #include #include "header.h" #include "definitions.h" using namespace std; class t_hdr_rack : public t_header { public: unsigned long cseq_nr; unsigned long resp_nr; t_method method; string unknown_method; // set if method is UNKNOWN t_hdr_rack(); void set_cseq_nr(unsigned long l); void set_resp_nr(unsigned long l); void set_method(t_method m, const string &unknown = ""); void set_method(const string &s); string encode_value(void) const; }; #endif twinkle-1.4.2/src/parser/hdr_content_encoding.h0000644000175000001440000000236311127714050016523 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Content-Encoding header #ifndef _HDR_CONTENT_ENCODING_H #define _HDR_CONTENT_ENCODING_H #include #include #include "coding.h" #include "header.h" using namespace std; class t_hdr_content_encoding : public t_header { public: list coding_list; // list of content codings; t_hdr_content_encoding(); // Add a coding to the list of content codings void add_coding(const t_coding &coding); string encode_value(void) const; }; #endif twinkle-1.4.2/src/sender.h0000644000175000001440000000201611127714050012325 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Network sender threads. */ #ifndef _H_SENDER #define _H_SENDER /** Thread sending SIP messages */ void *sender_loop(void *arg); /** Thread for sending asynchronously over TCP */ void *tcp_sender_loop(void *arg); #endif twinkle-1.4.2/src/abstract_dialog.h0000644000175000001440000002507011127714051014175 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Abstract class for all types of SIP dialogs. */ #ifndef _ABSTRACT_DIALOG_H #define _ABSTRACT_DIALOG_H #include #include #include #include #include "client_request.h" #include "id_object.h" #include "protocol.h" #include "sockets/url.h" #include "parser/request.h" using namespace std; // Forward declaration class t_phone_user; /** * Abstract class for all types of SIP dialogs. * Concrete classes for all SIP dialogs inherit from this class. */ class t_abstract_dialog : public t_id_object { protected: /** * Phone user for which this dialog is created. * This pointer should never be deleted. */ t_phone_user *phone_user; string call_id; /**< SIP call id. */ bool call_id_owner; /**< Indicates if the call id is generated locally. */ string local_tag; /**< Local tag value. */ string remote_tag; /**< Remote tag value. */ unsigned long local_seqnr; /**< Last local sequence number issued. */ unsigned long remote_seqnr; /**< Last remote sequence number received. */ /** * The remote_seqnr_set indicates if the remote_seqnr is set by the far-end. * RFC 3261 allows the CSeq sequence number to be 0. So there is no * invalid sequence number. */ bool remote_seqnr_set; t_url local_uri; /**< URI of the local party (From/To headers). */ string local_display; /**< Display name of the local party. */ t_url remote_uri; /**< URI of the remote party (From/To headers). */ string remote_display; /**< Display name of the remote party. */ /** URI of the remote target (Contact header). This is the destination for a request. */ t_url remote_target_uri; string remote_target_display; /**< Display name of the remote target. */ list route_set; /**< The route set. */ unsigned long local_resp_nr; /**< Last local response number (for 100rel) issued. */ unsigned long remote_resp_nr; /**< Last remote response number (for 100rel) received. */ set remote_extensions; /**< SIP extensions supported by the remote party. */ /** The IP transport/address/port from which the last SIP message was received. */ t_ip_port remote_ip_port; /** * Remove a client request. Pass one of the client request * pointers to this member. The reference count of the * request will be decremented. If it becomes zero, then * the request object is deleted. * In all cases the passed pointer will be set to NULL. * @param cr [in] The client request. */ void remove_client_request(t_client_request **cr); /** * Create route set from the Record-Route header of a response. * If the response does not have a Record-Route header, then the route * set is cleared. * @param r [in] The response. */ void create_route_set(t_response *r); /** * Create remote target uri and display from the Contact header of a response. * @param r [in] The response. */ void create_remote_target(t_response *r); /** * Send a request within the dialog. * Sending a request will create a SIP transaction. * @param r [in] The request. * @param tuid [in] The transaction user id to be assigend to the transaction. */ virtual void send_request(t_request *r, t_tuid tuid) = 0; /** * Resend an existing client request. * A new Via and CSeq header will be put in the request. * Resending is different from retransmitting. Requests are automatically * retransmitted by the transaction layer. Resending creates a new SIP * transaction. Resending is f.i. done when a request must be redirected. * @param cr [in] The client request. */ virtual void resend_request(t_client_request *cr); /** * Resend mid-dialog request with an authorization header containing * credentials for the challenge in the response. * @param cr [in] The request. * @param resp [in] The 401 or 407 response. * @return true, if resending succeeded. * @return false, if credentials could not be determined. * * @pre The response must be a 401 or 407. */ bool resend_request_auth(t_client_request *cr, t_response *resp); /** * Redirect mid-dialog request to the next destination. * There are multiple reasons for redirection: * - A 3XX response was received. * - The request failed with a non-3XX response. A next contact should be tried. * * @param cr [in] The request. * @param resp [in] The failure response that was received on the request. * @param contact [out] Contains on succesful return the contact to which the request is sent. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ bool redirect_request(t_client_request *cr, t_response *resp, t_contact_param &contact); /** * Failover request to the next destination from DNS lookup. * @param cr [in] The request. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ bool failover_request(t_client_request *cr); public: /** * Constructor. * @param pu [in] Phone user for which the dialog must be created. */ t_abstract_dialog(t_phone_user *pu); /** * Destructor. */ virtual ~t_abstract_dialog(); /** * Create a request using the stored dialog state information. * @param m [in] Request method. * @return The request. */ virtual t_request *create_request(t_method m); /** * Copy a dialog. * @return A copy of the dialog. */ virtual t_abstract_dialog *copy(void) = 0; /** * Get a pointer to the user profile of the user for whom this dialog * was created. * @return The user profile. */ t_user *get_user(void) const; /** * Resend mid-dialog request with an authorization header containing * credentials for the challenge in the response. * @param resp [in] The 401 or 407 response to the request that must be resent. * @return true, if resending succeeded. * @return false, if credentials could not be determined. * * @pre The response must be a 401 or 407. */ virtual bool resend_request_auth(t_response *resp) = 0; /** * Redirect mid-dialog request to the next destination. * @param resp [in] The response to the request that must be resent. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ virtual bool redirect_request(t_response *resp) = 0; /** * Failover request to the next destination from DNS lookup. * @param resp [in] The response to the request that must be resent. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ virtual bool failover_request(t_response *resp) = 0; /** * Process a received response. * @param r [in] The received response. * @param tuid [in] The transaction user id of the transaction for the response. * @param tid [in] The transaction id of the transaction for the response. */ virtual void recvd_response(t_response *r, t_tuid tuid, t_tid tid); /** * Process a received request. * @param r [in] The received request. * @param tuid [in] The transaction user id of the transaction for the request. * @param tid [in] The transaction id of the transaction for the request. */ virtual void recvd_request(t_request *r, t_tuid tuid, t_tid tid); /** * Match a response with the dialog. * @param r [in] The response. * @param tuid [in] The transaction user id of the transaction for the response. * @return true, if the response matches the dialog. * @return false, otherwise. */ virtual bool match_response(t_response *r, t_tuid tuid); /** * Match a request with the dialog. * @param r [in] The request. * @return true, if the request matches the dialog. * @return false, otherwise. */ virtual bool match_request(t_request *r); /** * Partially match a request with the dialog, i.e. do not match remote tag. * @param r [in] The request. * @return true, if the request partially matches the dialog. * @return false, otherwise. */ virtual bool match_partial_request(t_request *r); /** * Match call-id and tags with the dialog. * @param _call_id [in] SIP call-id. * @param to_tag [in] SIP to-tag. * @param from_tag [in] SIP from-tag. * @return true, if call-id and tags match the dialog. * @return false, otherwise. */ virtual bool match(const string &_call_id, const string &to_tag, const string &from_tag) const; /** * Get the URI of the remote target. * @return remote target URI. * @see remote_target_uri */ t_url get_remote_target_uri(void) const; /** * Get the display name of the remote target. * @return display name of remote target. * @see remote_target_display */ string get_remote_target_display(void) const; /** * Get the URI of the remote party. * @return URI of remote party. * @see remote_uri */ t_url get_remote_uri(void) const; /** * Get the display name of the remote party. * @return display name of the remote party. * @see remote_display */ string get_remote_display(void) const; /** * Get the IP transport/address/port from which the last SIP message was received. * @return transport/address/port */ t_ip_port get_remote_ip_port(void) const; /** * Get the SIP call id. * @return SIP call id. */ string get_call_id(void) const; /** * Get the local tag. * @return local tag. */ string get_local_tag(void) const; /** * Get the remote tag. * @return remote tag. */ string get_remote_tag(void) const; /** * Check if the remote party supports a particular SIP exentsion. * @param extension [in] Name of the SIP extension. * @return true, if remote party supports the extension. * @return false, otherwise. */ virtual bool remote_extension_supported(const string &extension) const; /** * Check if this dialog is the owner of the call id. * @return true, if this dialog is the owner. * @return false, otherwise. * @see call_id_owner */ bool is_call_id_owner(void) const; }; #endif twinkle-1.4.2/src/presence/0000777000175000001440000000000011151327746012576 500000000000000twinkle-1.4.2/src/presence/presence_state.cpp0000644000175000001440000000514011127714057016220 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "presence_state.h" #include #include "buddy.h" #include "pidf_body.h" #include "log.h" string t_presence_state::basic_state2str(t_presence_state::t_basic_state state) { switch (state) { case ST_BASIC_UNKNOWN: return "unknown"; case ST_BASIC_CLOSED: return "closed"; case ST_BASIC_OPEN: return "open"; case ST_BASIC_FAILED: return "failed"; case ST_BASIC_REJECTED: return "rejeceted"; default: return "UNKNOWN"; } } string t_presence_state::basic_state2pidf_str(t_presence_state::t_basic_state state) { if (state == ST_BASIC_OPEN) { return PIDF_STATUS_BASIC_OPEN; } // Convert all other states to "closed". return PIDF_STATUS_BASIC_CLOSED; } t_presence_state::t_presence_state() { assert(false); } t_presence_state::t_presence_state(t_buddy *_buddy) : buddy(_buddy), basic_state(ST_BASIC_UNKNOWN) { } t_presence_state::t_basic_state t_presence_state::get_basic_state(void) const { t_basic_state result; mtx_state.lock(); result = basic_state; mtx_state.unlock(); return result; } string t_presence_state::get_failure_msg(void) const { string result; mtx_state.lock(); result = failure_msg; mtx_state.unlock(); return result; } void t_presence_state::set_basic_state(t_presence_state::t_basic_state state) { mtx_state.lock(); basic_state = state; log_file->write_header("t_presence_state::set_basic_state", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Presence state changed to: "); log_file->write_raw(basic_state2str(basic_state)); log_file->write_endl(); log_file->write_raw(buddy->get_sip_address()); log_file->write_endl(); log_file->write_footer(); mtx_state.unlock(); // Notify the stat change to all observers of the buddy. buddy->notify(); } void t_presence_state::set_failure_msg(const string &msg) { mtx_state.lock(); failure_msg = msg; mtx_state.unlock(); } twinkle-1.4.2/src/presence/presence_dialog.cpp0000644000175000001440000000233311127714057016340 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "presence_dialog.h" #include "presence_subscription.h" #include "phone_user.h" #include "audits/memman.h" t_presence_dialog::t_presence_dialog(t_phone_user *_phone_user, t_presence_state *presence_state) : t_subscription_dialog(_phone_user) { subscription = new t_presence_subscription(this, presence_state); MEMMAN_NEW(subscription); } t_presence_dialog *t_presence_dialog::copy(void) { // Copy is not needed. assert(false); } twinkle-1.4.2/src/presence/presence_epa.cpp0000644000175000001440000000442211137414767015655 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "presence_epa.h" #include "pidf_body.h" #include "audits/memman.h" #include "parser/hdr_event.h" t_presence_epa::t_presence_epa(t_phone_user *pu) : t_epa(pu, SIP_EVENT_PRESENCE, t_url(pu->get_user_profile()->create_user_uri(false))), basic_state(t_presence_state::ST_BASIC_CLOSED), tuple_id(NEW_PIDF_TUPLE_ID) {} t_presence_state::t_basic_state t_presence_epa::get_basic_state(void) const { return basic_state; } bool t_presence_epa::recv_response(t_response *r, t_tuid tuid, t_tid tid) { t_epa::recv_response(r, tuid, tid); // Notify observers so they can get the latest publication state. notify(); return true; } void t_presence_epa::publish_presence(t_presence_state::t_basic_state _basic_state) { if (_basic_state != t_presence_state::ST_BASIC_CLOSED && _basic_state != t_presence_state::ST_BASIC_OPEN) { // Cannot publish internal states. return; } t_user *user_config = phone_user->get_user_profile(); basic_state = _basic_state; // Create PIDF document t_pidf_xml_body *pidf = new t_pidf_xml_body(); MEMMAN_NEW(pidf); pidf->set_pres_entity(user_config->create_user_uri(false)); pidf->set_tuple_id(tuple_id); pidf->set_basic_status(t_presence_state::basic_state2pidf_str(_basic_state)); publish(user_config->get_pres_publication_time(), pidf); // NOTE: the observers will be notified of the state change, when the // PUBLISH response is received. } void t_presence_epa::clear(void) { t_epa::clear(); basic_state = t_presence_state::ST_BASIC_CLOSED; } twinkle-1.4.2/src/presence/presence_subscription.cpp0000644000175000001440000001143311127714057017626 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "presence_subscription.h" #include #include "pidf_body.h" #include "log.h" #include "util.h" #include "parser/hdr_event.h" #include "audits/memman.h" t_request *t_presence_subscription::create_subscribe(unsigned long expires) const { t_request *r = t_subscription::create_subscribe(expires); SET_PRESENCE_HDR_ACCEPT(r->hdr_accept); return r; } t_presence_subscription::t_presence_subscription(t_presence_dialog *_dialog, t_presence_state *_state) : t_subscription(_dialog, SR_SUBSCRIBER, SIP_EVENT_PRESENCE), presence_state(_state) { } bool t_presence_subscription::recv_notify(t_request *r, t_tuid tuid, t_tid tid) { if (t_subscription::recv_notify(r, tuid, tid)) return true; bool unsupported_body = false; // NOTE: if the subscription is still pending (RFC 3265 3.2.4), then the // information in the body has no meaning. // NOTE: a NOTIFY request may have no body (RFC 3856 6.6.2) if (r->body && r->body->get_type() == BODY_PIDF_XML && !is_pending()) { t_pidf_xml_body *body = dynamic_cast(r->body); assert(body); string basic = body->get_basic_status(); if (basic == PIDF_STATUS_BASIC_OPEN) { presence_state->set_basic_state(t_presence_state::ST_BASIC_OPEN); } else if (basic == PIDF_STATUS_BASIC_CLOSED) { presence_state->set_basic_state(t_presence_state::ST_BASIC_CLOSED); } else { log_file->write_header("t_presence_subscription::recv_notify", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unknown basic status in pidf: "); log_file->write_raw(basic); log_file->write_endl(); log_file->write_footer(); presence_state->set_basic_state(t_presence_state::ST_BASIC_UNKNOWN); } } // Verify if there is an usupported body. if (r->body && r->body->get_type() != BODY_PIDF_XML) { unsupported_body = true; } if (state == SS_TERMINATED) { if (may_resubscribe) { presence_state->set_basic_state(t_presence_state::ST_BASIC_UNKNOWN); log_file->write_report("Presence subscription terminated.", "t_presence_subscription::recv_notify"); } else { if (reason_termination == EV_REASON_REJECTED) { presence_state->set_basic_state(t_presence_state::ST_BASIC_REJECTED); log_file->write_report("Presence agent rejected the subscription.", "t_presence_subscription::recv_notify"); } else { // The PA ended the subscription and indicated // that resubscription is not possible. So no presence status // can be retrieved anymore. This should not happen. // Show it as a failure to the user. presence_state->set_failure_msg(reason_termination); presence_state->set_basic_state(t_presence_state::ST_BASIC_FAILED); log_file->write_report( "Presence agent permanently terminated the subscription.", "t_presence_subscription::recv_notify"); } } } t_response *resp; if (unsupported_body) { resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE); SET_PRESENCE_HDR_ACCEPT(r->hdr_accept); } else { resp = r->create_response(R_200_OK); } send_response(user_config, resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return true; } bool t_presence_subscription::recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid) { // Parent handles the SUBSCRIBE response (void)t_subscription::recv_subscribe_response(r, tuid, tid); // If the subscription is terminated after the SUBSCRIBE response, it means // that subscription failed. if (state == SS_TERMINATED) { if (r->code == R_403_FORBIDDEN || r->code == R_603_DECLINE) { presence_state->set_basic_state(t_presence_state::ST_BASIC_REJECTED); log_file->write_report("Presence subscription rejected.", "t_presence_subscription::recv_subscribe_response"); } else { string failure = int2str(r->code); failure += ' '; failure += r->reason; presence_state->set_failure_msg(failure); presence_state->set_basic_state(t_presence_state::ST_BASIC_FAILED); log_file->write_report("Presence subscription failed.", "t_presence_subscription::recv_subscribe_response"); } } return true; } twinkle-1.4.2/src/presence/presence_state.h0000644000175000001440000000475511127714051015672 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Presence state (RFC 3863) */ #ifndef _PRESENCE_STATE_H #define _PRESENCE_STATE_H #include #include "threads/mutex.h" using namespace std; // Forward declaration class t_buddy; /** Presence state */ class t_presence_state { public: /** Basic state (RFC 3863 4.1.4) */ enum t_basic_state { ST_BASIC_UNKNOWN, /**< Presence state is unknown. */ ST_BASIC_CLOSED, /**< Unable to accept communication. */ ST_BASIC_OPEN, /**< Ready to accept communication. */ ST_BASIC_FAILED, /**< Failed to determine basic state. */ ST_BASIC_REJECTED,/**< Subscription has been rejected. */ }; /** * Convert a basic state to a string representation for internal usage. * @param state [in] A basic state value. * @return String representation of the basic state. */ static string basic_state2str(t_basic_state state); /** * Convert a basic state to a PIDF string representation. * @param state [in] A basic state value. * @return PIDF representation of the basic state. */ static string basic_state2pidf_str(t_basic_state state); private: /** Mutex for concurrent access to the presence state. */ mutable t_mutex mtx_state; /** Buddy owning this state. */ t_buddy *buddy; /** Basic presence state. */ t_basic_state basic_state; /** Detailed failure message */ string failure_msg; /** Protect the default constructor from being used. */ t_presence_state(); public: /** Constructor. */ t_presence_state(t_buddy *_buddy); /** @name Getters */ //@{ t_basic_state get_basic_state(void) const; string get_failure_msg(void) const; //@} /** @name Setters */ //@{ void set_basic_state(t_basic_state state); void set_failure_msg(const string &msg); //@} }; #endif twinkle-1.4.2/src/presence/pidf_body.h0000644000175000001440000000550411127714051014616 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * RFC 3863 pidf+xml body */ #ifndef _PIDF_BODY_H #define _PIDF_BODY_H #include #include #include "parser/sip_body.h" #define PIDF_STATUS_BASIC_OPEN "open" #define PIDF_STATUS_BASIC_CLOSED "closed" /** RFC 3863 pidf+xml body */ class t_pidf_xml_body : public t_sip_body_xml { private: string pres_entity; /**< Presence entity */ string tuple_id; /**< Id of tuple containing the basic status. */ string basic_status; /**< Value of basic-tag */ /** * Extract the status information from a PIDF document. * This will populate the state attributes. * @return True if PIDF document is valid, otherwise false. * @pre The @ref pidf_doc should contain a valid PIDF document. */ bool extract_status(void); /** * Process tuple element. * @param tuple [in] tuple element. */ void process_pidf_tuple(xmlNode *tuple); /** * Process status element. * @param status [in] status element. */ void process_pidf_status(xmlNode *status); /** * Process basic element. * @param basic [in] basic element. */ void process_pidf_basic(xmlNode *basic); protected: /** * Create a pidf document from the values stored in the attributes. */ virtual void create_xml_doc(const string &xml_version = "1.0", const string &charset = "UTF-8"); public: /** Constructor */ t_pidf_xml_body(); virtual t_sip_body *copy(void) const; virtual t_body_type get_type(void) const; virtual t_media get_media(void) const; /** @name Getters */ //@{ string get_pres_entity(void) const; string get_tuple_id(void) const; string get_basic_status(void) const; //@} /** @name Setters */ //@{ void set_pres_entity(const string &_pres_entity); void set_tuple_id(const string &_tuple_id); void set_basic_status(const string &_basic_status);; //@} /** * Parse a text representation of the body. * If parsing succeeds, then the state is extracted. * @param s [in] Text to parse. * @return True if parsing and state extracting succeeded, false otherwise. */ virtual bool parse(const string &s); }; #endif twinkle-1.4.2/src/presence/Makefile.am0000644000175000001440000000054211134651156014543 00000000000000AM_CPPFLAGS = -Wall $(CCRTP_CFLAGS) $(XML2_CFLAGS) -I$(top_srcdir)/src noinst_LIBRARIES = libpresence.a libpresence_a_SOURCES =\ buddy.cpp\ pidf_body.cpp\ presence_dialog.cpp\ presence_epa.cpp\ presence_state.cpp\ presence_subscription.cpp\ buddy.h\ pidf_body.h\ presence_dialog.h\ presence_epa.h\ presence_state.h\ presence_subscription.h twinkle-1.4.2/src/presence/Makefile.in0000644000175000001440000004054011151323410014542 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/presence DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libpresence_a_AR = $(AR) $(ARFLAGS) libpresence_a_LIBADD = am_libpresence_a_OBJECTS = buddy.$(OBJEXT) pidf_body.$(OBJEXT) \ presence_dialog.$(OBJEXT) presence_epa.$(OBJEXT) \ presence_state.$(OBJEXT) presence_subscription.$(OBJEXT) libpresence_a_OBJECTS = $(am_libpresence_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libpresence_a_SOURCES) DIST_SOURCES = $(libpresence_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ AM_CPPFLAGS = -Wall $(CCRTP_CFLAGS) $(XML2_CFLAGS) -I$(top_srcdir)/src noinst_LIBRARIES = libpresence.a libpresence_a_SOURCES = \ buddy.cpp\ pidf_body.cpp\ presence_dialog.cpp\ presence_epa.cpp\ presence_state.cpp\ presence_subscription.cpp\ buddy.h\ pidf_body.h\ presence_dialog.h\ presence_epa.h\ presence_state.h\ presence_subscription.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/presence/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/presence/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libpresence.a: $(libpresence_a_OBJECTS) $(libpresence_a_DEPENDENCIES) -rm -f libpresence.a $(libpresence_a_AR) libpresence.a $(libpresence_a_OBJECTS) $(libpresence_a_LIBADD) $(RANLIB) libpresence.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buddy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pidf_body.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/presence_dialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/presence_epa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/presence_state.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/presence_subscription.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/src/presence/presence_dialog.h0000644000175000001440000000266011127714051016002 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Dialog for presence subscription (RFC 3856) */ #ifndef _PRESENCE_DIALOG_H #define _PRESENCE_DIALOG_H #include "subscription_dialog.h" #include "presence_state.h" // Forward declaration class t_phone_user; /** Dialog for presence subscription (RFC 3856) */ class t_presence_dialog : public t_subscription_dialog { public: /** * Constructor. * @param _phone_user [in] Phone user owning the dialog. * @param presence_state [in] Presence state that is updated by notification * on this dialog */ t_presence_dialog(t_phone_user *_phone_user, t_presence_state *presence_state); virtual t_presence_dialog *copy(void); }; #endif twinkle-1.4.2/src/presence/presence_subscription.h0000644000175000001440000000312111127714051017260 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Presence subscription (RFC 3856) */ #ifndef _PRESENCE_SUBSCRIPTION_H #define _PRESENCE_SUBSCRIPTION_H #include "presence_state.h" #include "presence_dialog.h" #include "subscription.h" /** Subscription to the presence event (RFC 3856) */ class t_presence_subscription : public t_subscription { private: t_presence_state *presence_state; protected: virtual t_request *create_subscribe(unsigned long expires) const; public: /** * Constructor. * @param _dialog [in] Dialog for the presence subscription. * @param _state [in] Current presence state. */ t_presence_subscription(t_presence_dialog *_dialog, t_presence_state *_state); virtual bool recv_notify(t_request *r, t_tuid tuid, t_tid tid); virtual bool recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid); }; #endif twinkle-1.4.2/src/presence/pidf_body.cpp0000644000175000001440000001330011134635317015147 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "pidf_body.h" #include #include #include "log.h" #include "util.h" #include "audits/memman.h" #define PIDF_XML_VERSION "1.0" #define PIDF_NAMESPACE "urn:ietf:params:xml:ns:pidf" #define IS_PIDF_TAG(node, tag) IS_XML_TAG(node, tag, PIDF_NAMESPACE) #define IS_PIDF_ATTR(attr, attr_name) IS_XML_ATTR(attr, attr_name, PIDF_NAMESPACE) bool t_pidf_xml_body::extract_status(void) { assert(xml_doc); xmlNode *root_element = NULL; // Get root root_element = xmlDocGetRootElement(xml_doc); if (!root_element) { log_file->write_report("PIDF document has no root element.", "t_pidf_xml_body::extract_status", LOG_NORMAL, LOG_WARNING); return false; } // Check if root is if (!IS_PIDF_TAG(root_element, "presence")) { log_file->write_report("PIDF document has invalid root element.", "t_pidf_xml_body::extract_status", LOG_NORMAL, LOG_WARNING); return false; } pres_entity.clear(); tuple_id.clear(); basic_status.clear(); // Get presence entity xmlChar *prop_entity = xmlGetProp(root_element, BAD_CAST "entity"); if (prop_entity) { pres_entity = (char *)prop_entity; } else { log_file->write_report("Presence entity is missing.", "t_pidf_xml_body::extract_status", LOG_NORMAL, LOG_WARNING); } xmlNode *child = root_element->children; // Process children of root. for (xmlNode *cur_node = child; cur_node; cur_node = cur_node->next) { // Process tuple if (IS_PIDF_TAG(cur_node, "tuple")) { process_pidf_tuple(cur_node); // Process the first tuple and then stop. // Currently there is no support for multiple tuples // or additional elements. break; } } return true; } void t_pidf_xml_body::process_pidf_tuple(xmlNode *tuple) { assert(tuple); // Get tuple id. xmlChar *id = xmlGetProp(tuple, BAD_CAST "id"); if (id) { tuple_id = (char *)id; } else { log_file->write_report("Tuple id is missing.", "t_pidf_xml_body::process_pidf_tuple", LOG_NORMAL, LOG_WARNING); } // Find status element xmlNode *child = tuple->children; for (xmlNode *cur_node = child; cur_node; cur_node = cur_node->next) { // Process status if (IS_PIDF_TAG(cur_node, "status")) { process_pidf_status(cur_node); break; } } } void t_pidf_xml_body::process_pidf_status(xmlNode *status) { assert(status); xmlNode *child = status->children; for (xmlNode *cur_node = child; cur_node; cur_node = cur_node->next) { // Process status if (IS_PIDF_TAG(cur_node, "basic")) { process_pidf_basic(cur_node); break; } } } void t_pidf_xml_body::process_pidf_basic(xmlNode *basic) { assert(basic); xmlNode *child = basic->children; if (child && child->type == XML_TEXT_NODE) { basic_status = tolower((char*)child->content); } else { log_file->write_report(" element has no content.", "t_pidf_xml_body::process_pidf_basic", LOG_NORMAL, LOG_WARNING); } } void t_pidf_xml_body::create_xml_doc(const string &xml_version, const string &charset) { t_sip_body_xml::create_xml_doc(xml_version, charset); // presence xmlNode *node_presence = xmlNewNode(NULL, BAD_CAST "presence"); xmlNs *ns_pidf = xmlNewNs(node_presence, BAD_CAST PIDF_NAMESPACE, NULL); xmlNewProp(node_presence, BAD_CAST "entity", BAD_CAST pres_entity.c_str()); xmlDocSetRootElement(xml_doc, node_presence); // tuple xmlNode *node_tuple = xmlNewChild(node_presence, ns_pidf, BAD_CAST "tuple", NULL); xmlNewProp(node_tuple, BAD_CAST "id", BAD_CAST tuple_id.c_str()); // status xmlNode *node_status = xmlNewChild(node_tuple, ns_pidf, BAD_CAST "status", NULL); // basic xmlNewChild(node_status, ns_pidf, BAD_CAST "basic", BAD_CAST basic_status.c_str()); } t_pidf_xml_body::t_pidf_xml_body() : t_sip_body_xml () {} t_sip_body *t_pidf_xml_body::copy(void) const { t_pidf_xml_body *body = new t_pidf_xml_body(*this); MEMMAN_NEW(body); // Clear the xml_doc pointer in the new body, as a copy of the // XML document must be copied to the body. body->xml_doc = NULL; copy_xml_doc(body); return body; } t_body_type t_pidf_xml_body::get_type(void) const { return BODY_PIDF_XML; } t_media t_pidf_xml_body::get_media(void) const { return t_media("application", "pidf+xml"); } string t_pidf_xml_body::get_pres_entity(void) const { return pres_entity; } string t_pidf_xml_body::get_tuple_id(void) const { return tuple_id; } string t_pidf_xml_body::get_basic_status(void) const { return basic_status; } void t_pidf_xml_body::set_pres_entity(const string &_pres_entity) { clear_xml_doc(); pres_entity = _pres_entity; } void t_pidf_xml_body::set_tuple_id(const string &_tuple_id) { clear_xml_doc(); tuple_id = _tuple_id; } void t_pidf_xml_body::set_basic_status(const string &_basic_status) { clear_xml_doc(); basic_status = _basic_status; } bool t_pidf_xml_body::parse(const string &s) { if (t_sip_body_xml::parse(s)) { if (!extract_status()) { MEMMAN_DELETE(xml_doc); xmlFreeDoc(xml_doc); xml_doc = NULL; } } return (xml_doc != NULL); } twinkle-1.4.2/src/presence/presence_epa.h0000644000175000001440000000350511127714051015307 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Presence Event Publication Agent (EPA) [RFC 3903] */ #ifndef _PRESENCE_EPA_H #define _PRESENCE_EPA_H #include #include "epa.h" #include "presence_state.h" #include "patterns/observer.h" using namespace std; /** Presence Event Publication Agent (EPA) [RFC 3903] */ class t_presence_epa : public t_epa, public patterns::t_subject { private: /** Basic presence state. */ t_presence_state::t_basic_state basic_state; /** Tuple id to be put in the PIDF documents. */ string tuple_id; public: /** Constructor */ t_presence_epa(t_phone_user *pu); /** @name Getters */ //@{ t_presence_state::t_basic_state get_basic_state(void) const; //@} virtual bool recv_response(t_response *r, t_tuid tuid, t_tid tid); /** * Publish presence state. * @param _basic_state [in] The basic presence state. * @pre _basic_state must be one of the following values: * - @ref ST_BASIC_CLOSED * - @ref ST_BASIC_OPEN */ void publish_presence(t_presence_state::t_basic_state _basic_state); virtual void clear(void); }; #endif twinkle-1.4.2/src/presence/buddy.cpp0000644000175000001440000003346011127714057014331 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "buddy.h" #include #include "log.h" #include "phone.h" #include "phone_user.h" #include "userintf.h" #include "audits/memman.h" extern t_phone *phone; extern t_event_queue *evq_timekeeper; /** Buddy */ void t_buddy::cleanup_presence_dialog(void) { assert(phone_user); if (presence_dialog && presence_dialog->get_subscription_state() == SS_TERMINATED) { string reason_termination = presence_dialog->get_reason_termination(); bool may_resubscribe = presence_dialog->get_may_resubscribe(); unsigned long dur_resubscribe = presence_dialog->get_resubscribe_after(); MEMMAN_DELETE(presence_dialog); delete presence_dialog; presence_dialog = NULL; phone_user->stun_binding_inuse_presence--; phone_user->cleanup_stun_data(); phone_user->cleanup_nat_keepalive(); if (presence_auto_resubscribe) { if (may_resubscribe) { if (dur_resubscribe > 0) { start_resubscribe_presence_timer(dur_resubscribe * 1000); } else { subscribe_presence(); } } else if (reason_termination.empty()) { start_resubscribe_presence_timer(DUR_PRESENCE_FAILURE * 1000); } } } } t_buddy::t_buddy() : phone_user(NULL), may_subscribe_presence(false), presence_state(this), presence_dialog(NULL), subscribe_after_stun(false), presence_auto_resubscribe(false), delete_after_presence_terminated(false), id_resubscribe_presence(0) { } t_buddy::t_buddy(t_phone_user *_phone_user) : phone_user(_phone_user), may_subscribe_presence(false), presence_state(this), presence_dialog(NULL), subscribe_after_stun(false), presence_auto_resubscribe(false), delete_after_presence_terminated(false), id_resubscribe_presence(0) { } t_buddy::t_buddy(t_phone_user *_phone_user, const string _name, const string &_sip_address) : phone_user(_phone_user), name(_name), sip_address(_sip_address), may_subscribe_presence(false), presence_state(this), presence_dialog(NULL), subscribe_after_stun(false), presence_auto_resubscribe(false), delete_after_presence_terminated(false), id_resubscribe_presence(0) { } t_buddy::t_buddy(const t_buddy &other) : phone_user(other.phone_user), name(other.name), sip_address(other.sip_address), may_subscribe_presence(other.may_subscribe_presence), presence_state(this), presence_dialog(NULL), subscribe_after_stun(false), presence_auto_resubscribe(false), delete_after_presence_terminated(false), id_resubscribe_presence(0) {} t_buddy::~t_buddy() { if (presence_dialog) { MEMMAN_DELETE(presence_dialog); delete presence_dialog; } } string t_buddy::get_name(void) const { return name; } string t_buddy::get_sip_address(void) const { return sip_address; } bool t_buddy::get_may_subscribe_presence(void) const { return may_subscribe_presence; } const t_presence_state *t_buddy::get_presence_state(void) const { return &presence_state; } t_user *t_buddy::get_user_profile(void) { assert(phone_user); return phone_user->get_user_profile(); } t_buddy_list *t_buddy::get_buddy_list(void) { assert(phone_user); return phone_user->get_buddy_list(); } void t_buddy::set_phone_user(t_phone_user *_phone_user) { phone_user = _phone_user; } void t_buddy::set_name(const string &_name) { name = _name; notify(); } void t_buddy::set_sip_address(const string &_sip_address) { sip_address = _sip_address; notify(); } void t_buddy::set_may_subscribe_presence(bool _may_subscribe_presence) { may_subscribe_presence = _may_subscribe_presence; notify(); } bool t_buddy::match_response(t_response *r, t_tuid tuid) const { return (presence_dialog && presence_dialog->match_response(r, tuid)); } bool t_buddy::match_request(t_request *r) const { if (!presence_dialog) return false; bool partial_match = false; bool match = presence_dialog->match_request(r, partial_match); if (match) return true; if (partial_match && presence_dialog->get_remote_tag().empty()) { // A NOTIFY may be received before a 2XX on SUBSCRIBE. // In this case the NOTIFY will establish the dialog. return true; } return false; } bool t_buddy::match_timer(t_subscribe_timer timer, t_object_id id_timer) const { if (presence_dialog && presence_dialog->match_timer(timer, id_timer)) { return true; } return id_timer == id_resubscribe_presence; } void t_buddy::timeout(t_subscribe_timer timer, t_object_id id_timer) { switch (timer) { case STMR_SUBSCRIPTION: if (presence_dialog && presence_dialog->match_timer(timer, id_timer)) { (void)presence_dialog->timeout(timer); cleanup_presence_dialog(); } else if (id_timer == id_resubscribe_presence) { // Try to subscribe to presence id_resubscribe_presence = 0; subscribe_presence(); } break; default: assert(false); } } void t_buddy::recvd_response(t_response *r, t_tuid tuid, t_tid tid) { if (presence_dialog) { presence_dialog->recvd_response(r, tuid, tid); cleanup_presence_dialog(); } } void t_buddy::recvd_request(t_request *r, t_tuid tuid, t_tid tid) { if (presence_dialog) { presence_dialog->recvd_request(r, tuid, tid); cleanup_presence_dialog(); } } void t_buddy::start_resubscribe_presence_timer(unsigned long duration) { t_tmr_subscribe *t; t = new t_tmr_subscribe(duration, STMR_SUBSCRIPTION, 0, 0, SIP_EVENT_PRESENCE, ""); MEMMAN_NEW(t); id_resubscribe_presence = t->get_object_id(); evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_buddy::stop_resubscribe_presence_timer(void) { if (id_resubscribe_presence != 0) { evq_timekeeper->push_stop_timer(id_resubscribe_presence); id_resubscribe_presence = 0; } } void t_buddy::stun_completed(void) { if (subscribe_after_stun) { subscribe_after_stun = false; subscribe_presence(); } } void t_buddy::stun_failed(void) { if (subscribe_after_stun) { subscribe_after_stun = false; start_resubscribe_presence_timer(DUR_PRESENCE_FAILURE * 1000); } } void t_buddy::subscribe_presence(void) { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); if (!may_subscribe_presence) return; presence_auto_resubscribe = true; if (presence_dialog) { // Already subscribed. log_file->write_header("t_buddy::subscribe_presence", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Already subscribed to presence: "); log_file->write_raw(name); log_file->write_raw(", "); log_file->write_raw(sip_address); log_file->write_endl(); log_file->write_footer(); return; } // If STUN is enabled, then do a STUN query before registering to // determine the public IP address. if (phone_user->use_stun) { if (phone_user->stun_public_ip_sip == 0) { phone_user->send_stun_request(); phone_user->presence_subscribe_after_stun = true; subscribe_after_stun = true; return; } phone_user->stun_binding_inuse_presence++; } presence_dialog = new t_presence_dialog(phone_user, &presence_state); MEMMAN_NEW(presence_dialog); string dest = ui->expand_destination(user_config, sip_address); t_url dest_url(dest); if (!dest_url.is_valid()) { log_file->write_header("t_buddy::subscribe_presence", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Invalid SIP address: "); log_file->write_raw(sip_address); log_file->write_endl(); log_file->write_footer(); return; } presence_dialog->subscribe(DUR_PRESENCE(user_config), dest_url, dest_url, ""); // Start sending NAT keepalive packets when STUN is used // (or in case of symmetric firewall) if (phone_user->use_nat_keepalive && phone_user->id_nat_keepalive == 0) { // Just start the NAT keepalive timer. The SUBSCRIBE // message will create the NAT binding. So there is // no need to send a NAT keep alive packet now. phone->start_timer(PTMR_NAT_KEEPALIVE, phone_user); } cleanup_presence_dialog(); } void t_buddy::unsubscribe_presence(bool remove) { presence_auto_resubscribe = false; stop_resubscribe_presence_timer(); presence_state.set_basic_state(t_presence_state::ST_BASIC_UNKNOWN); delete_after_presence_terminated = remove; if (presence_dialog) { presence_dialog->unsubscribe(); cleanup_presence_dialog(); } } bool t_buddy::create_file_record(vector &v) const { if (delete_after_presence_terminated) return false; v.clear(); v.push_back(name); v.push_back(sip_address); v.push_back((may_subscribe_presence ? "y" : "n")); return true; } bool t_buddy::populate_from_file_record(const vector &v) { if (v.size() !=3 ) return false; name = v[0]; sip_address = v[1]; may_subscribe_presence = (v[2] == "y"); return true; } bool t_buddy::operator==(const t_buddy &other) const { return (name == other.name && sip_address == other.sip_address); } void t_buddy::clear_presence(void) { if (id_resubscribe_presence) stop_resubscribe_presence_timer(); if (presence_dialog) { MEMMAN_DELETE(presence_dialog); delete presence_dialog; presence_dialog = NULL; } presence_state.set_basic_state(t_presence_state::ST_BASIC_UNKNOWN); } bool t_buddy::is_presence_terminated(void) const { return presence_dialog == NULL; } bool t_buddy::must_delete_now(void) const { return delete_after_presence_terminated && is_presence_terminated(); } /** Buddy list */ void t_buddy_list::add_record(const t_buddy &record) { t_buddy r(record); r.set_phone_user(phone_user); utils::t_record_file::add_record(r); } t_buddy_list::t_buddy_list(t_phone_user *_phone_user) : phone_user(_phone_user), is_subscribed(false) { t_user *user_config = phone_user->get_user_profile(); set_header("name|sip_address|subscribe"); set_separator('|'); string filename = user_config->get_profile_name() + BUDDY_FILE_EXT; string f = user_config->expand_filename(filename); set_filename(f); } t_user *t_buddy_list::get_user_profile(void) { return phone_user->get_user_profile(); } t_buddy *t_buddy_list::add_buddy(const t_buddy &buddy) { t_buddy *b = NULL; mtx_records.lock(); add_record(buddy); // KLUDGE: this code assumes that the buddy is added at the end. b = &records.back(); mtx_records.unlock(); log_file->write_header("t_buddy_list::add_buddy"); log_file->write_raw("Added buddy: "); log_file->write_raw(b->get_name()); log_file->write_raw(", "); log_file->write_raw(b->get_sip_address()); log_file->write_endl(); log_file->write_footer(); return b; } void t_buddy_list::del_buddy(const t_buddy &buddy) { mtx_records.lock(); list::iterator it = find(records.begin(), records.end(), buddy); if (it == records.end()) { mtx_records.unlock(); return; } log_file->write_header("t_buddy_list::del_buddy"); log_file->write_raw("Delete buddy: "); log_file->write_raw(buddy.get_name()); log_file->write_raw(", "); log_file->write_raw(buddy.get_sip_address()); log_file->write_endl(); log_file->write_footer(); records.erase(it); mtx_records.unlock(); } bool t_buddy_list::match_response(t_response *r, t_tuid tuid, t_buddy **buddy) { *buddy = NULL; mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { if (it->match_response(r, tuid)) { *buddy = &(*it); break; } } mtx_records.unlock(); return *buddy != NULL; } bool t_buddy_list::match_request(t_request *r, t_buddy **buddy) { *buddy = NULL; mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { if (it->match_request(r)) { *buddy = &(*it); break; } } mtx_records.unlock(); return *buddy != NULL; } bool t_buddy_list::match_timer(t_subscribe_timer timer, t_object_id id_timer, t_buddy **buddy) { *buddy = NULL; mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { if (it->match_timer(timer, id_timer)) { *buddy = &(*it); break; } } mtx_records.unlock(); return *buddy != NULL; } void t_buddy_list::stun_completed(void) { mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { it->stun_completed(); } mtx_records.unlock(); } void t_buddy_list::stun_failed(void) { mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { it->stun_failed(); } mtx_records.unlock(); } void t_buddy_list::subscribe_presence(void) { mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { it->subscribe_presence(); } is_subscribed = true; mtx_records.unlock(); } void t_buddy_list::unsubscribe_presence(void) { mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { it->unsubscribe_presence(); } is_subscribed = false; mtx_records.unlock(); } bool t_buddy_list::get_is_subscribed() const { bool result; mtx_records.lock(); result = is_subscribed; mtx_records.unlock(); return result; } void t_buddy_list::clear_presence(void) { mtx_records.lock(); for (list::iterator it = records.begin(); it != records.end(); ++it) { it->clear_presence(); } is_subscribed = false; mtx_records.unlock(); } bool t_buddy_list::is_presence_terminated(void) const { bool result = true; mtx_records.lock(); for (list::const_iterator it = records.begin(); it != records.end(); ++it) { if (!it->is_presence_terminated()) { result = false; break; } } mtx_records.unlock(); return result; } twinkle-1.4.2/src/presence/buddy.h0000644000175000001440000002264511127714051013773 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Buddy list */ #ifndef _BUDDY_H #define _BUDDY_H #include #include #include "presence_state.h" #include "presence_dialog.h" #include "sockets/url.h" #include "utils/record_file.h" #include "patterns/observer.h" // Forward declaration class t_phone_user; class t_buddy_list; #define BUDDY_FILE_EXT ".bud" using namespace std; /** Buddy */ class t_buddy : public utils::t_record, public patterns::t_subject { private: /** Phone user owning this buddy. */ t_phone_user *phone_user; /** Name of buddy (for display only) */ string name; /** SIP address of the buddy. */ string sip_address; /** Indicates if the user may subscribe to the presence state of the buddy. */ bool may_subscribe_presence; /** Presence state. */ t_presence_state presence_state; /** Presence subscription dialog. */ t_presence_dialog *presence_dialog; /** Subscribe to presence after STUN transaction completed. */ bool subscribe_after_stun; /** * Indicates if presence must be automatically resubscribed to, if the * subscription terminates with a reason telling that resubscription * is possible. */ bool presence_auto_resubscribe; /** * Indicates if the buddy must be deleted after the presence subscription * has been terminated. */ bool delete_after_presence_terminated; /** Handle presence dialog termination. */ void cleanup_presence_dialog(void); public: /** Interval before trying to resubscribe to presence after a failure. */ t_object_id id_resubscribe_presence; /** Constructor. */ t_buddy(); /** Constructor. */ t_buddy(t_phone_user *_phone_user); /** Constructor. */ t_buddy(t_phone_user *_phone_user, const string _name, const string &_sip_address); /** Copy constructor. */ t_buddy(const t_buddy &other); /** Destructor. */ virtual ~t_buddy(); /** @name Getters */ //@{ string get_name(void) const; string get_sip_address(void) const; bool get_may_subscribe_presence(void) const; const t_presence_state *get_presence_state(void) const; //@} /** * Get user profile for the user owning this buddy. * @return User profile. */ t_user *get_user_profile(void); /** * Get the buddy list containing this buddy. * @return Buddy list */ t_buddy_list *get_buddy_list(void); /** @name Setters */ //@{ void set_phone_user(t_phone_user *_phone_user); void set_name(const string &_name); void set_sip_address(const string &_sip_address); void set_may_subscribe_presence(bool _may_subscribe_presence); //@} /** * Match response with a buddy. It matches if the buddy * has a presence dialog that matches with the response. * @param r [in] The response. * @param tuid [in] Transaction user id. * @return True if the response matches, otherwise false. */ bool match_response(t_response *r, t_tuid tuid) const; /** * Match request with buddy list. It matches if a buddy in the list * has a presence dialog that matches with the request. * @param r [in] The request. * @return True if the request matches, otherwise false. */ bool match_request(t_request *r) const; /** * Match a timer id with a running timer. * @param timer [in] The running timer. * @param id_timer [in] The timer id. * @return true, if timer id matches with timer. * @return false, otherwise. */ bool match_timer(t_subscribe_timer timer, t_object_id id_timer) const; /** * Process timeout. * @param timer [in] The timer that expired. * @param id_timer [in] The timer id. */ void timeout(t_subscribe_timer timer, t_object_id id_timer); /** * Handle received response. * @param r [in] The response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void recvd_response(t_response *r, t_tuid tuid, t_tid tid); /** * Handle received request. * @param r [in] The request. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void recvd_request(t_request *r, t_tuid tuid, t_tid tid); /** * Start the re-subscribe timer after a presence subscription failure. * @param duration [in] Duration before trying a re-subscribe (s) */ void start_resubscribe_presence_timer(unsigned long duration); /** Stop presence re-subscribe timer. */ void stop_resubscribe_presence_timer(void); /** * By calling this method, succesful STUN completion is signalled to * the buddy. It will subscribe to presence if it was waiting for STUN. */ void stun_completed(void); /** * By calling this method, a STUN failure is signalled to * the buddy. It will reschedule a presence subscription if it is * waiting for STUN to complete. */ void stun_failed(void); /** Subscribe to presence of the buddy if we may do so. */ void subscribe_presence(void); /** Unsubscribe to presence. * @param remove [in] Indicates if the buddy must be deleted after unsubscription. */ void unsubscribe_presence(bool remove = false); virtual bool create_file_record(vector &v) const; virtual bool populate_from_file_record(const vector &v); /** Compare 2 buddies for equality (same SIP address) */ bool operator==(const t_buddy &other) const; /** Clear presence state. */ void clear_presence(void); /** * Check if presence subscription is terminated. * @return true, if presence subscriptions is terminated. * @return false, otherwise */ bool is_presence_terminated(void) const; /** * Check if buddy must be deleted. * @return true, if the buddy must be deleted immediately. * @return false, otherwise. */ bool must_delete_now(void) const; }; /** List of buddies for a particular account. */ class t_buddy_list : public utils::t_record_file { private: /** Phone user owning this buddy list. */ t_phone_user *phone_user; /** * Indicates if subscribe is done. This indicator will be set to false * when you call unsubscribe. */ bool is_subscribed; protected: virtual void add_record(const t_buddy &record); public: /** Constructor. */ t_buddy_list(t_phone_user *_phone_user); /** * Get the user profile for this buddy list. * @return User profile. */ t_user *get_user_profile(void); /** * Add a buddy. * @param buddy [in] Buddy to add. * @return Pointer to added buddy. * @note This method adds a copy of the buddy. It returns a pointer to this copy. */ t_buddy *add_buddy(const t_buddy &buddy); /** * Delete a buddy. * @param buddy [in] Buddy to delete. */ void del_buddy(const t_buddy &buddy); /** * Match response with buddy list. It matches if a buddy in the list * has a presence dialog that matches with the response. * @param r [in] The response. * @param tuid [in] Transaction user id. * @param buddy [out] On a match, this parameter contains the matching buddy. * @return True if the response matches, otherwise false. */ bool match_response(t_response *r, t_tuid tuid, t_buddy **buddy); /** * Match request with buddy list. It matches if a buddy in the list * has a presence dialog that matches with the request. * @param r [in] The request. * @param buddy [out] On a match, this parameter contains the matching buddy. * @return True if the request matches, otherwise false. */ bool match_request(t_request *r, t_buddy **buddy); /** * Match a timer id with a running timer. A timer id matches with the * buddy list if it matches with one of the buddies in the list. * @param timer [in] The running timer. * @param id_timer [in] The timer id. * @param buddy [out] On a match, this parameter contains the matching buddy. * @return true, if timer id matches with timer. * @return false, otherwise. */ bool match_timer(t_subscribe_timer timer, t_object_id id_timer, t_buddy **buddy); /** * By calling this method, succesful STUN completion is signalled to the buddy * list. The buddy list will now start presence subscriptions that were waiting * for STUN to complete. */ void stun_completed(void); /** * By calling this method, a STUN failure is signalled to the buddy list. * The buddy list will reschedule presence subscriptions that were waiting * for STUN to complete. */ void stun_failed(void); /** Subscribe to presence of all buddies in the list. */ void subscribe_presence(void); /** Unsubscribe to presence of all buddies in the list. */ void unsubscribe_presence(void); /** * Check if user is subcribed to buddy list presence. * @return True if subscribed, otherwise false. */ bool get_is_subscribed() const; /** Clear presence state of all buddies. */ void clear_presence(void); /** * Check if all presence subscriptions are terminated. * @return true, if all presence subscriptions are terminated. * @return false, otherwise */ bool is_presence_terminated(void) const; }; #endif twinkle-1.4.2/src/sys_settings.cpp0000644000175000001440000014702311144643445014156 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "twinkle_config.h" #include #include #include #include #include #include #include #include #include #include "sys_settings.h" #include "log.h" #include "translator.h" #include "user.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" #include "utils/file_utils.h" using namespace utils; // Share directory containing files applicable to all users #define DIR_SHARE DATADIR // Lock file to guarantee that a user is running the application only once #define LOCK_FILENAME "twinkle.lck" // System config file #define SYS_CONFIG_FILE "twinkle.sys" // Default location of the shared mime database #define DFLT_SHARED_MIME_DB "/usr/share/mime/globs" // Field names in the config file // AUDIO fields #define FLD_DEV_RINGTONE "dev_ringtone" #define FLD_DEV_SPEAKER "dev_speaker" #define FLD_DEV_MIC "dev_mic" #define FLD_VALIDATE_AUDIO_DEV "validate_audio_dev" #define FLD_ALSA_PLAY_PERIOD_SIZE "alsa_play_period_size" #define FLD_ALSA_CAPTURE_PERIOD_SIZE "alsa_capture_period_size" #define FLD_OSS_FRAGMENT_SIZE "oss_fragment_size" // LOG fields #define FLD_LOG_MAX_SIZE "log_max_size" #define FLD_LOG_SHOW_SIP "log_show_sip" #define FLD_LOG_SHOW_STUN "log_show_stun" #define FLD_LOG_SHOW_MEMORY "log_show_memory" #define FLD_LOG_SHOW_DEBUG "log_show_debug" // GUI settings #define FLD_GUI_USE_SYSTRAY "gui_use_systray" #define FLD_GUI_HIDE_ON_CLOSE "gui_hide_on_close" #define FLD_GUI_AUTO_SHOW_INCOMING "gui_auto_show_incoming" #define FLD_GUI_AUTO_SHOW_TIMEOUT "gui_auto_show_timeout" #define FLD_GUI_BROWSER_CMD "gui_browser_cmd" // Address book settings #define FLD_AB_SHOW_SIP_ONLY "ab_show_sip_only" #define FLD_AB_LOOKUP_NAME "ab_lookup_name" #define FLD_AB_OVERRIDE_DISPLAY "ab_override_display" #define FLD_AB_LOOKUP_PHOTO "ab_lookup_photo" // Call history fields #define FLD_CH_MAX_SIZE "ch_max_size" // Service settings #define FLD_CALL_WAITING "call_waiting" #define FLD_HANGUP_BOTH_3WAY "hangup_both_3way" // Startup settings #define FLD_START_USER_PROFILE "start_user_profile" #define FLD_START_HIDDEN "start_hidden" // Network settings #define FLD_sip_udp_port "sip_udp_port" #define FLD_sip_port "sip_port" #define FLD_RTP_PORT "rtp_port" #define FLD_SIP_MAX_UDP_SIZE "sip_max_udp_size" #define FLD_SIP_MAX_TCP_SIZE "sip_max_tcp_size" // Ring tone settings #define FLD_PLAY_RINGTONE "play_ringtone" #define FLD_RINGTONE_FILE "ringtone_file" #define FLD_PLAY_RINGBACK "play_ringback" #define FLD_RINGBACK_FILE "ringback_file" // Persistent storage for user interface state #define FLD_LAST_USED_PROFILE "last_used_profile" #define FLD_REDIAL_URL "redial_url" #define FLD_REDIAL_DISPLAY "redial_display" #define FLD_REDIAL_SUBJECT "redial_subject" #define FLD_REDIAL_PROFILE "redial_profile" #define FLD_REDIAL_HIDE_USER "redial_hide_user" #define FLD_DIAL_HISTORY "dial_history" #define FLD_SHOW_DISPLAY "show_display" #define FLD_COMPACT_LINE_STATUS "compact_line_status" #define FLD_SHOW_BUDDY_LIST "show_buddy_list" #define FLD_WARN_HIDE_USER "warn_hide_user" // Settings to restore session after shutdown #define FLD_UI_SESSION_ID "ui_session_id" #define FLD_UI_SESSION_ACTIVE_PROFILE "ui_session_active_profile" #define FLD_UI_SESSION_MAIN_GEOMETRY "ui_session_main_geometry" #define FLD_UI_SESSION_MAIN_HIDDEN "ui_session_main_hidden" #define FLD_UI_SESSION_MAIN_STATE "ui_session_main_state" // Mime settings #define FLD_MIME_SHARED_DATABASE "mime_shared_database" ///////////////////////// // class t_audio_device ///////////////////////// string t_audio_device::get_description(void) const { string s = device; if (type == OSS) { s = "OSS: " + s; if (sym_link.size() > 0) { s += " -> "; s += sym_link; } if (name.size() > 0) { s += ": "; s += name; } } else if (type == ALSA) { s = "ALSA: " + s; if (!name.empty()) { s += ": "; s += name; } } else { s = "Unknown: " + s; } return s; } string t_audio_device::get_settings_value(void) const { string s; switch (type) { case OSS: s = PFX_OSS; break; case ALSA: s = PFX_ALSA; break; default: assert(false); } s += device; return s; } ///////////////////////// // class t_win_geometry ///////////////////////// t_win_geometry::t_win_geometry(int x_, int y_, int width_, int height_) : x(x_), y(y_), width(width_), height(height_) {} t_win_geometry::t_win_geometry() : x(0), y(0), width(0), height(0) {} t_win_geometry::t_win_geometry(const string &value) { vector v = split(value, ','); if (v.size() == 4) { x = atoi(v[0].c_str()); y = atoi(v[1].c_str()); width = atoi(v[2].c_str()); height = atoi(v[3].c_str()); } } string t_win_geometry::encode(void) const { string s; s = int2str(x); s += ','; s += int2str(y); s += ','; s += int2str(width); s += ','; s += int2str(height); return s; } ///////////////////////// // class t_sys_settings ///////////////////////// t_sys_settings::t_sys_settings() { fd_lock_file = -1; dir_share = DIR_SHARE; filename = string(DIR_HOME); filename += "/"; filename += USER_DIR; filename += "/"; filename += SYS_CONFIG_FILE; // Audio device default settings #ifdef HAVE_LIBASOUND dev_ringtone = audio_device(DEV_ALSA_DFLT); dev_speaker = audio_device(DEV_ALSA_DFLT); dev_mic = audio_device(DEV_ALSA_DFLT); #else dev_ringtone = audio_device(); dev_speaker = audio_device(); dev_mic = audio_device(); #endif validate_audio_dev = true; alsa_play_period_size = 128; alsa_capture_period_size = 32; oss_fragment_size = 128; log_max_size = 5; log_show_sip = true; log_show_stun = true; log_show_memory = true; log_show_debug = false; gui_use_systray = true; gui_hide_on_close = true; gui_auto_show_incoming = false; gui_auto_show_timeout = 10; ab_show_sip_only = false; ab_lookup_name = true; ab_override_display = true; ab_lookup_photo = true; ch_max_size = 50; call_waiting = true; hangup_both_3way = true; start_user_profiles.clear(); start_hidden = false; config_sip_port = 5060; active_sip_port = 0; override_sip_port = 0; rtp_port = 8000; override_rtp_port = 0; sip_max_udp_size = 65535; sip_max_tcp_size = 1000000; play_ringtone = true; ringtone_file.clear(); play_ringback = true; ringback_file.clear(); last_used_profile.clear(); redial_url.set_url(""); redial_display.clear(); redial_subject.clear(); redial_profile.clear(); redial_hide_user = false; dial_history.clear(); show_display = true; compact_line_status = false; show_buddy_list = true; warn_hide_user = true; ui_session_id.clear(); mime_shared_database = DFLT_SHARED_MIME_DB; } // Getters t_audio_device t_sys_settings::get_dev_ringtone(void) const { t_audio_device result; mtx_sys.lock(); result = dev_ringtone; mtx_sys.unlock(); return result; } t_audio_device t_sys_settings::get_dev_speaker(void) const { t_audio_device result; mtx_sys.lock(); result = dev_speaker; mtx_sys.unlock(); return result; } t_audio_device t_sys_settings::get_dev_mic(void) const { t_audio_device result; mtx_sys.lock(); result = dev_mic; mtx_sys.unlock(); return result; } bool t_sys_settings::get_validate_audio_dev(void) const { bool result; mtx_sys.lock(); result = validate_audio_dev; mtx_sys.unlock(); return result; } int t_sys_settings::get_alsa_play_period_size(void) const { int result; mtx_sys.lock(); result = alsa_play_period_size; mtx_sys.unlock(); return result; } int t_sys_settings::get_alsa_capture_period_size(void) const { int result; mtx_sys.lock(); result = alsa_capture_period_size; mtx_sys.unlock(); return result; } int t_sys_settings::get_oss_fragment_size(void) const { int result; mtx_sys.lock(); result = oss_fragment_size; mtx_sys.unlock(); return result; } unsigned short t_sys_settings::get_log_max_size(void) const { unsigned short result; mtx_sys.lock(); result = log_max_size; mtx_sys.unlock(); return result; } bool t_sys_settings::get_log_show_sip(void) const { bool result; mtx_sys.lock(); result = log_show_sip; mtx_sys.unlock(); return result; } bool t_sys_settings::get_log_show_stun(void) const { bool result; mtx_sys.lock(); result = log_show_stun; mtx_sys.unlock(); return result; } bool t_sys_settings::get_log_show_memory(void) const { bool result; mtx_sys.lock(); result = log_show_memory; mtx_sys.unlock(); return result; } bool t_sys_settings::get_log_show_debug(void) const { bool result; mtx_sys.lock(); result = log_show_debug; mtx_sys.unlock(); return result; } bool t_sys_settings::get_gui_use_systray(void) const { t_mutex_guard guard(mtx_sys); return gui_use_systray; } bool t_sys_settings::get_gui_auto_show_incoming(void) const { t_mutex_guard guard(mtx_sys); return gui_auto_show_incoming; } int t_sys_settings::get_gui_auto_show_timeout(void) const { t_mutex_guard guard(mtx_sys); return gui_auto_show_timeout; } bool t_sys_settings::get_gui_hide_on_close(void) const { t_mutex_guard guard(mtx_sys); return gui_hide_on_close; } string t_sys_settings::get_gui_browser_cmd(void) const { t_mutex_guard guard(mtx_sys); return gui_browser_cmd; } bool t_sys_settings::get_ab_show_sip_only(void) const { bool result; mtx_sys.lock(); result = ab_show_sip_only; mtx_sys.unlock(); return result; } bool t_sys_settings::get_ab_lookup_name(void) const { bool result; mtx_sys.lock(); result = ab_lookup_name; mtx_sys.unlock(); return result; } bool t_sys_settings::get_ab_override_display(void) const { bool result; mtx_sys.lock(); result = ab_override_display; mtx_sys.unlock(); return result; } bool t_sys_settings::get_ab_lookup_photo(void) const { bool result; mtx_sys.lock(); result = ab_lookup_photo; mtx_sys.unlock(); return result; } int t_sys_settings::get_ch_max_size(void) const { int result; mtx_sys.lock(); result = ch_max_size; mtx_sys.unlock(); return result; } bool t_sys_settings::get_call_waiting(void) const { bool result; mtx_sys.lock(); result = call_waiting; mtx_sys.unlock(); return result; } bool t_sys_settings::get_hangup_both_3way(void) const { bool result; mtx_sys.lock(); result = hangup_both_3way; mtx_sys.unlock(); return result; } list t_sys_settings::get_start_user_profiles(void) const { list result; mtx_sys.lock(); result = start_user_profiles; mtx_sys.unlock(); return result; } bool t_sys_settings::get_start_hidden(void) const { bool result; mtx_sys.lock(); result = start_hidden; mtx_sys.unlock(); return result; } unsigned short t_sys_settings::get_config_sip_port(void) const { unsigned short result; mtx_sys.lock(); result = config_sip_port; mtx_sys.unlock(); return result; } unsigned short t_sys_settings::get_rtp_port(void) const { unsigned short result; mtx_sys.lock(); if (override_rtp_port > 0) { result = override_rtp_port; } else { result = rtp_port; } mtx_sys.unlock(); return result; } unsigned short t_sys_settings::get_sip_max_udp_size(void) const { t_mutex_guard guard(mtx_sys); return sip_max_udp_size; } unsigned long t_sys_settings::get_sip_max_tcp_size(void) const { t_mutex_guard guard(mtx_sys); return sip_max_tcp_size; } bool t_sys_settings::get_play_ringtone(void) const { bool result; mtx_sys.lock(); result = play_ringtone; mtx_sys.unlock(); return result; } string t_sys_settings::get_ringtone_file(void) const { string result; mtx_sys.lock(); result = ringtone_file; mtx_sys.unlock(); return result; } bool t_sys_settings::get_play_ringback(void) const { bool result; mtx_sys.lock(); result = play_ringback; mtx_sys.unlock(); return result; } string t_sys_settings::get_ringback_file(void) const { string result; mtx_sys.lock(); result = ringback_file; mtx_sys.unlock(); return result; } string t_sys_settings::get_last_used_profile(void) const { string result; mtx_sys.lock(); result = last_used_profile; mtx_sys.unlock(); return result; } t_url t_sys_settings::get_redial_url(void) const { t_url result; mtx_sys.lock(); result = redial_url; mtx_sys.unlock(); return result; } string t_sys_settings::get_redial_display(void) const { string result; mtx_sys.lock(); result = redial_display; mtx_sys.unlock(); return result; } string t_sys_settings::get_redial_subject(void) const { string result; mtx_sys.lock(); result = redial_subject; mtx_sys.unlock(); return result; } string t_sys_settings::get_redial_profile(void) const { string result; mtx_sys.lock(); result = redial_profile; mtx_sys.unlock(); return result; } bool t_sys_settings::get_redial_hide_user(void) const { bool result; mtx_sys.lock(); result = redial_hide_user; mtx_sys.unlock(); return result; } list t_sys_settings::get_dial_history(void) const { list result; mtx_sys.lock(); result = dial_history; mtx_sys.unlock(); return result; } bool t_sys_settings::get_show_display(void) const { bool result; mtx_sys.lock(); result = show_display; mtx_sys.unlock(); return result; } bool t_sys_settings::get_compact_line_status(void) const { bool result; mtx_sys.lock(); result = compact_line_status; mtx_sys.unlock(); return result; } bool t_sys_settings::get_show_buddy_list(void) const { bool result; mtx_sys.lock(); result = show_buddy_list; mtx_sys.unlock(); return result; } string t_sys_settings::get_ui_session_id(void) const { t_mutex_guard guard(mtx_sys); return ui_session_id; } list t_sys_settings::get_ui_session_active_profiles(void) const { t_mutex_guard guard(mtx_sys); return ui_session_active_profiles; } t_win_geometry t_sys_settings::get_ui_session_main_geometry(void) const { t_mutex_guard guard(mtx_sys); return ui_session_main_geometry; } bool t_sys_settings::get_ui_session_main_hidden(void) const { t_mutex_guard guard(mtx_sys); return ui_session_main_hidden; } unsigned int t_sys_settings::get_ui_session_main_state(void) const { t_mutex_guard guard(mtx_sys); return ui_session_main_state; } bool t_sys_settings::get_warn_hide_user(void) const { t_mutex_guard guard(mtx_sys); return warn_hide_user; } string t_sys_settings::get_mime_shared_database(void) const { t_mutex_guard guard(mtx_sys); return mime_shared_database; } // Setters void t_sys_settings::set_dev_ringtone(const t_audio_device &dev) { mtx_sys.lock(); dev_ringtone = dev; mtx_sys.unlock(); } void t_sys_settings::set_dev_speaker(const t_audio_device &dev) { mtx_sys.lock(); dev_speaker = dev; mtx_sys.unlock(); } void t_sys_settings::set_dev_mic(const t_audio_device &dev) { mtx_sys.lock(); dev_mic = dev; mtx_sys.unlock(); } void t_sys_settings::set_validate_audio_dev(bool b) { mtx_sys.lock(); validate_audio_dev = b; mtx_sys.unlock(); } void t_sys_settings::set_alsa_play_period_size(int size) { mtx_sys.lock(); alsa_play_period_size = size; mtx_sys.unlock(); } void t_sys_settings::set_alsa_capture_period_size(int size) { mtx_sys.lock(); alsa_capture_period_size = size; mtx_sys.unlock(); } void t_sys_settings::set_oss_fragment_size(int size) { mtx_sys.lock(); oss_fragment_size = size; mtx_sys.unlock(); } void t_sys_settings::set_log_max_size(unsigned short size) { mtx_sys.lock(); log_max_size = size; mtx_sys.unlock(); } void t_sys_settings::set_log_show_sip(bool b) { mtx_sys.lock(); log_show_sip = b; mtx_sys.unlock(); } void t_sys_settings::set_log_show_stun(bool b) { mtx_sys.lock(); log_show_stun = b; mtx_sys.unlock(); } void t_sys_settings::set_log_show_memory(bool b) { t_mutex_guard guard(mtx_sys); log_show_memory = b; } void t_sys_settings::set_log_show_debug(bool b) { t_mutex_guard guard(mtx_sys); log_show_debug = b; } void t_sys_settings::set_gui_use_systray(bool b) { t_mutex_guard guard(mtx_sys); gui_use_systray = b; } void t_sys_settings::set_gui_hide_on_close(bool b) { t_mutex_guard guard(mtx_sys); gui_hide_on_close = b; } void t_sys_settings::set_gui_auto_show_incoming(bool b) { t_mutex_guard guard(mtx_sys); gui_auto_show_incoming = b; } void t_sys_settings::set_gui_auto_show_timeout(int timeout) { t_mutex_guard guard(mtx_sys); gui_auto_show_timeout = timeout; } void t_sys_settings::set_gui_browser_cmd(const string &s) { t_mutex_guard guard(mtx_sys); gui_browser_cmd = s; } void t_sys_settings::set_ab_show_sip_only(bool b) { mtx_sys.lock(); ab_show_sip_only = b; mtx_sys.unlock(); } void t_sys_settings::set_ab_lookup_name(bool b) { mtx_sys.lock(); ab_lookup_name = b; mtx_sys.unlock(); } void t_sys_settings::set_ab_override_display(bool b) { mtx_sys.lock(); ab_override_display = b; mtx_sys.unlock(); } void t_sys_settings::set_ab_lookup_photo(bool b) { mtx_sys.lock(); ab_lookup_photo = b; mtx_sys.unlock(); } void t_sys_settings::set_ch_max_size(int size) { mtx_sys.lock(); ch_max_size = size; mtx_sys.unlock(); } void t_sys_settings::set_call_waiting(bool b) { mtx_sys.lock(); call_waiting = b; mtx_sys.unlock(); } void t_sys_settings::set_hangup_both_3way(bool b) { mtx_sys.lock(); hangup_both_3way = b; mtx_sys.unlock(); } void t_sys_settings::set_start_user_profiles(const list &profiles) { mtx_sys.lock(); start_user_profiles = profiles; mtx_sys.unlock(); } void t_sys_settings::set_start_hidden(bool b) { mtx_sys.lock(); start_hidden = b; mtx_sys.unlock(); } void t_sys_settings::set_config_sip_port(unsigned short port) { mtx_sys.lock(); config_sip_port = port; mtx_sys.unlock(); } void t_sys_settings::set_override_sip_port(unsigned short port) { mtx_sys.lock(); override_sip_port = port; mtx_sys.unlock(); } void t_sys_settings::set_rtp_port(unsigned short port) { mtx_sys.lock(); rtp_port = port; mtx_sys.unlock(); } void t_sys_settings::set_override_rtp_port(unsigned short port) { mtx_sys.lock(); override_rtp_port = port; mtx_sys.unlock(); } void t_sys_settings::set_sip_max_udp_size(unsigned short size) { t_mutex_guard guard(mtx_sys); sip_max_udp_size = size; } void t_sys_settings::set_sip_max_tcp_size(unsigned long size) { t_mutex_guard guard(mtx_sys); sip_max_tcp_size = size; } void t_sys_settings::set_play_ringtone(bool b) { mtx_sys.lock(); play_ringtone = b; mtx_sys.unlock(); } void t_sys_settings::set_ringtone_file(const string &file) { mtx_sys.lock(); ringtone_file = file; mtx_sys.unlock(); } void t_sys_settings::set_play_ringback(bool b) { mtx_sys.lock(); play_ringback = b; mtx_sys.unlock(); } void t_sys_settings::set_ringback_file(const string &file) { mtx_sys.lock(); ringback_file = file; mtx_sys.unlock(); } void t_sys_settings::set_last_used_profile(const string &profile) { mtx_sys.lock(); last_used_profile = profile; mtx_sys.unlock(); } void t_sys_settings::set_redial_url(const t_url &url) { mtx_sys.lock(); redial_url = url; mtx_sys.unlock(); } void t_sys_settings::set_redial_display(const string &display) { mtx_sys.lock(); redial_display = display; mtx_sys.unlock(); } void t_sys_settings::set_redial_subject(const string &subject) { mtx_sys.lock(); redial_subject = subject; mtx_sys.unlock(); } void t_sys_settings::set_redial_profile(const string &profile) { mtx_sys.lock(); redial_profile = profile; mtx_sys.unlock(); } void t_sys_settings::set_redial_hide_user(const bool b) { mtx_sys.lock(); redial_hide_user = b; mtx_sys.unlock(); } void t_sys_settings::set_dial_history(const list &history) { mtx_sys.lock(); dial_history = history; mtx_sys.unlock(); } void t_sys_settings::set_show_display(bool b) { mtx_sys.lock(); show_display = b; mtx_sys.unlock(); } void t_sys_settings::set_compact_line_status(bool b) { mtx_sys.lock(); compact_line_status = b; mtx_sys.unlock(); } void t_sys_settings::set_show_buddy_list(bool b) { mtx_sys.lock(); show_buddy_list = b; mtx_sys.unlock(); } void t_sys_settings::set_ui_session_id(const string &id) { t_mutex_guard guard(mtx_sys); ui_session_id = id; } void t_sys_settings::set_ui_session_active_profiles(const list &profiles) { t_mutex_guard guard(mtx_sys); ui_session_active_profiles = profiles; } void t_sys_settings::set_ui_session_main_geometry(const t_win_geometry &geometry) { t_mutex_guard guard(mtx_sys); ui_session_main_geometry = geometry; } void t_sys_settings::set_ui_session_main_hidden(bool hidden) { t_mutex_guard guard(mtx_sys); ui_session_main_hidden = hidden; } void t_sys_settings::set_ui_session_main_state(unsigned int state) { t_mutex_guard guard(mtx_sys); ui_session_main_state = state; } void t_sys_settings::set_warn_hide_user(bool b) { t_mutex_guard guard(mtx_sys); warn_hide_user = b; } void t_sys_settings::set_mime_shared_database(const string &filename) { t_mutex_guard guard(mtx_sys); mime_shared_database = filename; } string t_sys_settings::about(bool html) const { string s = PRODUCT_NAME; s += ' '; s += PRODUCT_VERSION; s += " - "; s += get_product_date(); if (html) s += "
"; s += "\n"; s += "Copyright (C) 2005-2009 "; s += PRODUCT_AUTHOR; if (html) s += "
"; s += "\n"; s += "http://www.twinklephone.com"; if (html) s += "

"; s += "\n\n"; string options_built = get_options_built(); if (!options_built.empty()) { s += TRANSLATE("Built with support for:"); s += " "; s += options_built; if (html) s += "

"; s += "\n\n"; } s += TRANSLATE("Contributions:"); if (html) s += "
"; s += "\n"; s += "* Werner Dittmann (ZRTP/SRTP)\n"; if (html) s += "
"; s += "* Bogdan Harjoc (AKAv1-MD5, Service-Route)\n"; if (html) s += "
"; s += "* Roman Imankulov (command line editing)\n"; if (html) s += "
"; if (html) { s += "* Ondrej Moriš (codec preprocessing)
\n"; } else { s += "* Ondrej Moris (codec preprocessing)\n"; } if (html) { s += "* Rickard Petzäll (ALSA)
\n"; } else { s += "* Rickard Petzall (ALSA)\n"; } if (html) s += "
"; s += "\n"; s += TRANSLATE("This software contains the following software from 3rd parties:"); if (html) s += "
"; s += "\n"; s += TRANSLATE("* GSM codec from Jutta Degener and Carsten Bormann, University of Berlin"); if (html) s += "
"; s += "\n"; s += TRANSLATE("* G.711/G.726 codecs from Sun Microsystems (public domain)"); if (html) s += "
"; s += "\n"; #ifdef HAVE_ILBC s += TRANSLATE("* iLBC implementation from RFC 3951 (www.ilbcfreeware.org)"); if (html) s += "
"; s += "\n"; #endif s += TRANSLATE("* Parts of the STUN project at http://sourceforge.net/projects/stun"); if (html) s += "
"; s += "\n"; s += TRANSLATE("* Parts of libsrv at http://libsrv.sourceforge.net/"); if (html) s += "
"; s += "\n"; if (html) s += "
"; s += "\n"; s += TRANSLATE("For RTP the following dynamic libraries are linked:"); if (html) s += "
"; s += "\n"; s += "* GNU ccRTP - http://www.gnu.org/software/ccrtp"; if (html) s += "
"; s += "\n"; s += "* GNU CommonC++ - http://www.gnu.org/software/commoncpp"; if (html) s += "

"; s += "\n\n"; // Display information about translator only on non-english version. string translated_by = TRANSLATE("Translated to english by "); if (translated_by != "Translated to english by ") { s += translated_by; if (html) s += "

"; s += "\n\n"; } s += PRODUCT_NAME; s += " comes with ABSOLUTELY NO WARRANTY."; if (html) s += "
"; s += "\n"; s += "This program is free software; you can redistribute it and/or modify"; if (html) s += "
"; s += "\n"; s += "it under the terms of the GNU General Public License as published by"; if (html) s += "
"; s += "\n"; s += "the Free Software Foundation; either version 2 of the License, or"; if (html) s += "
"; s += "\n"; s += "(at your option) any later version."; if (html) s += "
"; s += "\n"; return s; } string t_sys_settings::get_product_date(void) const { struct tm t; t.tm_sec = 0; t.tm_min = 0; t.tm_hour = 0; vector l = split(PRODUCT_DATE, ' '); assert(l.size() == 3); t.tm_mon = str2month_full(l[0]); t.tm_mday = atoi(l[1].c_str()); t.tm_year = atoi(l[2].c_str()) - 1900; char buf[64]; strftime(buf, 64, "%d %B %Y", &t); return string(buf); } string t_sys_settings::get_options_built(void) const { string options_built; #ifdef HAVE_LIBASOUND if (!options_built.empty()) options_built += ", "; options_built += "ALSA"; #endif #ifdef HAVE_KDE if (!options_built.empty()) options_built += ", "; options_built += "KDE"; #endif #ifdef HAVE_SPEEX if (!options_built.empty()) options_built += ", "; options_built += "Speex"; #endif #ifdef HAVE_ILBC if (!options_built.empty()) options_built += ", "; options_built += "iLBC"; #endif #ifdef HAVE_ZRTP if (!options_built.empty()) options_built += ", "; options_built += "ZRTP"; #endif return options_built; } bool t_sys_settings::check_environment(string &error_msg) const { struct stat stat_buf; string filename, dirname; mtx_sys.lock(); // Check if share directory exists if (stat(dir_share.c_str(), &stat_buf) != 0) { error_msg = TRANSLATE("Directory %1 does not exist."); error_msg = replace_first(error_msg, "%1", dir_share); mtx_sys.unlock(); return false; } // Check if audio file for ring tone exist filename = dir_share; filename += '/'; filename += FILE_RINGTONE; ifstream f_ringtone(filename.c_str()); if (!f_ringtone) { error_msg = TRANSLATE("Cannot open file %1 ."); error_msg = replace_first(error_msg, "%1", filename); mtx_sys.unlock(); return false; } // Check if audio file for ring back exist filename = dir_share; filename += '/'; filename += FILE_RINGBACK; ifstream f_ringback(filename.c_str()); if (!f_ringback) { error_msg = TRANSLATE("Cannot open file %1 ."); error_msg = replace_first(error_msg, "%1", filename); mtx_sys.unlock(); return false; } // Check if $HOME is set correctly if (string(DIR_HOME) == "") { error_msg = TRANSLATE("%1 is not set to your home directory."); error_msg = replace_first(error_msg, "%1", "$HOME"); mtx_sys.unlock(); return false; } if (stat(DIR_HOME, &stat_buf) != 0) { error_msg = TRANSLATE("Directory %1 (%2) does not exist."); error_msg = replace_first(error_msg, "%1", DIR_HOME); error_msg = replace_first(error_msg, "%2", "$HOME"); mtx_sys.unlock(); return false; } // Check if user directory exists dirname = get_dir_user(); if (stat(dirname.c_str(), &stat_buf) != 0) { // User directory does not exist. Create it now. if (mkdir(dirname.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) { // Failed to create the user directory error_msg = TRANSLATE("Cannot create directory %1 ."); error_msg = replace_first(error_msg, "%1", dirname); mtx_sys.unlock(); return false; } } // Check if tmp file directory exists dirname = get_dir_tmpfile(); if (stat(dirname.c_str(), &stat_buf) != 0) { // Tmp file directory does not exist. Create it now. if (mkdir(dirname.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) { // Failed to create the tmp file directory error_msg = TRANSLATE("Cannot create directory %1 ."); error_msg = replace_first(error_msg, "%1", dirname); mtx_sys.unlock(); return false; } } mtx_sys.unlock(); return true; } void t_sys_settings::set_dir_share(const string &dir) { mtx_sys.lock(); dir_share = dir; mtx_sys.unlock(); } string t_sys_settings::get_dir_share(void) const { string result; mtx_sys.lock(); result = dir_share; mtx_sys.unlock(); return result; } string t_sys_settings::get_dir_lang(void) const { string result = get_dir_share(); result += "/lang"; return result; } string t_sys_settings::get_dir_user(void) const { string dir = DIR_HOME; dir += "/"; dir += DIR_USER; return dir; } string t_sys_settings::get_history_file(void) const { string dir = get_dir_user(); dir += "/"; dir += FILE_CLI_HISTORY; return dir; } string t_sys_settings::get_dir_tmpfile(void) const { string dir = get_dir_user(); dir += "/"; dir += DIR_TMPFILE; return dir; } bool t_sys_settings::is_tmpfile(const string &filename) const { string tmpdir = get_dir_tmpfile(); return filename.substr(0, tmpdir.size()) == tmpdir; } bool t_sys_settings::save_tmp_file(const string &data, const string &file_extension, string &filename, string &error_msg) { string fname = get_dir_tmpfile(); fname += "/XXXXXX"; char *tmpfile = strdup(fname.c_str()); MEMMAN_NEW(tmpfile); int fd = mkstemp(tmpfile); if (fd < 0) { error_msg = get_error_str(errno); MEMMAN_DELETE(tmpfile); free(tmpfile); return false; } close(fd); ofstream f(tmpfile); if (!f) { error_msg = TRANSLATE("Failed to create file %1"); error_msg = replace_first(error_msg, "%1", tmpfile); MEMMAN_DELETE(tmpfile); free(tmpfile); return false; } f.write(data.c_str(), data.size()); if (!f.good()) { error_msg = TRANSLATE("Failed to write data to file %1"); error_msg = replace_first(error_msg, "%1", tmpfile); f.close(); MEMMAN_DELETE(tmpfile); free(tmpfile); return false; } f.close(); // Rename to name with extension filename = apply_glob_to_filename(tmpfile, file_extension); if (rename(tmpfile, filename.c_str()) < 0) { error_msg = get_error_str(errno); MEMMAN_DELETE(tmpfile); free(tmpfile); return false; } MEMMAN_DELETE(tmpfile); free(tmpfile); return true; } bool t_sys_settings::save_sip_body(const t_sip_message &sip_msg, const string &suggested_file_extension, string &tmpname, string &save_as_name, string &error_msg) { bool retval = true; if (!sip_msg.body) { error_msg = "Missing body"; return false; } // Determine file extension and save-as name // The algorithm to get the file extension (glob expression) is: // 1) If the a file name is supplied in the Content-Disposition header, then // take the file extension from that file name. // 2) If no extension is found, then take the suggested_file_extension // 3) If still no file extension is found, then retrieve the file extension // from the t_media object in the Content-Type header. string file_ext = suggested_file_extension; save_as_name.clear(); if (sip_msg.hdr_content_disp.is_populated() && sip_msg.hdr_content_disp.type == DISPOSITION_ATTACHMENT && !sip_msg.hdr_content_disp.filename.empty()) { string x = get_extension_from_filename(sip_msg.hdr_content_disp.filename); if (!x.empty()) file_ext = string("*." + x); save_as_name = strip_path_from_filename(sip_msg.hdr_content_disp.filename); } if (file_ext.empty()) { file_ext = sip_msg.hdr_content_type.media.get_file_glob(); if (file_ext.empty()) { file_ext = "*"; } } // Avoid copy of opaque data if (sip_msg.body->get_type() == BODY_OPAQUE) { t_sip_body_opaque *body_opaque = dynamic_cast(sip_msg.body); retval = save_tmp_file(body_opaque->opaque, file_ext, tmpname, error_msg); } else { retval = save_tmp_file(sip_msg.body->encode(), file_ext, tmpname, error_msg); } return retval; } void t_sys_settings::remove_all_tmp_files(void) const { DIR *tmpdir = opendir(get_dir_tmpfile().c_str()); if (!tmpdir) { log_file->write_report(get_error_str(errno), "t_sys_settings::remove_all_tmp_files"); return; } struct dirent *entry = readdir(tmpdir); while (entry) { if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { string fname = get_dir_tmpfile(); fname += PATH_SEPARATOR; fname += entry->d_name; log_file->write_header("t_sys_settings::remove_all_tmp_files"); log_file->write_raw("Remove tmp file "); log_file->write_raw(fname); log_file->write_endl(); log_file->write_footer(); unlink(fname.c_str()); } entry = readdir(tmpdir); } closedir(tmpdir); } bool t_sys_settings::create_lock_file(bool shared_lock, string &error_msg, bool &already_running) { string lck_filename; already_running = false; lck_filename = DIR_HOME; lck_filename += "/"; lck_filename += DIR_USER; lck_filename += "/"; lck_filename += LOCK_FILENAME; fd_lock_file = open(lck_filename.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd_lock_file < 0) { error_msg = TRANSLATE("Cannot create %1 ."); error_msg = replace_first(error_msg, "%1", lck_filename); error_msg += "\n"; error_msg += get_error_str(errno); return false; } struct flock lock_options; // Try to acquire an exclusive lock if (!shared_lock) { memset(&lock_options, 0, sizeof(struct flock)); lock_options.l_type = F_WRLCK; lock_options.l_whence = SEEK_SET; if (fcntl(fd_lock_file, F_SETLK, &lock_options) < 0) { already_running = true; error_msg = TRANSLATE("%1 is already running.\nLock file %2 already exists."); error_msg = replace_first(error_msg, "%1", PRODUCT_NAME); error_msg = replace_first(error_msg, "%2", lck_filename); return false; } } // Convert the lock to a shared lock. If the user forces multiple // instances of Twinkle to run, then each will have a shared lock. memset(&lock_options, 0, sizeof(struct flock)); lock_options.l_type = F_RDLCK; lock_options.l_whence = SEEK_SET; if (fcntl(fd_lock_file, F_SETLK, &lock_options) < 0) { error_msg = TRANSLATE("Cannot lock %1 ."); error_msg = replace_first(error_msg, "%1", lck_filename); return false; } return true; } void t_sys_settings::delete_lock_file(void) { if (fd_lock_file >= 0) { struct flock lock_options; lock_options.l_type = F_UNLCK; lock_options.l_whence = SEEK_SET; fcntl(fd_lock_file, F_SETLK, &lock_options); close(fd_lock_file); fd_lock_file = -1; } } bool t_sys_settings::read_config(string &error_msg) { struct stat stat_buf; mtx_sys.lock(); // Check if config file exists if (stat(filename.c_str(), &stat_buf) != 0) { mtx_sys.unlock(); return true; } // Open config file ifstream config(filename.c_str()); if (!config) { error_msg = TRANSLATE("Cannot open file for reading: %1"); error_msg = replace_first(error_msg, "%1", filename); mtx_sys.unlock(); return false; } // Read and parse config file. while (!config.eof()) { string line; getline(config, line); // Check if read operation succeeded if (!config.good() && !config.eof()) { error_msg = TRANSLATE("File system error while reading file %1 ."); error_msg = replace_first(error_msg, "%1", filename); mtx_sys.unlock(); return false; } line = trim(line); // Skip empty lines if (line.size() == 0) continue; // Skip comment lines if (line[0] == '#') continue; vector l = split_on_first(line, '='); if (l.size() != 2) { error_msg = TRANSLATE("Syntax error in file %1 ."); error_msg = replace_first(error_msg, "%1", filename); error_msg += "\n"; error_msg += line; mtx_sys.unlock(); return false; } string parameter = trim(l[0]); string value = trim(l[1]); if (parameter == FLD_DEV_RINGTONE) { dev_ringtone = audio_device(value); } else if (parameter == FLD_DEV_SPEAKER) { dev_speaker = audio_device(value); } else if (parameter == FLD_DEV_MIC) { dev_mic = audio_device(value); } else if (parameter == FLD_VALIDATE_AUDIO_DEV) { validate_audio_dev = yesno2bool(value); } else if (parameter == FLD_ALSA_PLAY_PERIOD_SIZE) { alsa_play_period_size = atoi(value.c_str()); } else if (parameter == FLD_ALSA_CAPTURE_PERIOD_SIZE) { alsa_capture_period_size = atoi(value.c_str()); } else if (parameter == FLD_OSS_FRAGMENT_SIZE) { oss_fragment_size = atoi(value.c_str()); } else if (parameter == FLD_LOG_MAX_SIZE) { log_max_size = atoi(value.c_str()); } else if (parameter == FLD_LOG_SHOW_SIP) { log_show_sip = yesno2bool(value); } else if (parameter == FLD_LOG_SHOW_STUN) { log_show_stun = yesno2bool(value); } else if (parameter == FLD_LOG_SHOW_MEMORY) { log_show_memory = yesno2bool(value); } else if (parameter == FLD_LOG_SHOW_DEBUG) { log_show_debug = yesno2bool(value); } else if (parameter == FLD_GUI_USE_SYSTRAY) { gui_use_systray = yesno2bool(value); } else if (parameter == FLD_GUI_HIDE_ON_CLOSE) { gui_hide_on_close = yesno2bool(value); } else if (parameter == FLD_GUI_AUTO_SHOW_INCOMING) { gui_auto_show_incoming = yesno2bool(value); } else if (parameter == FLD_GUI_AUTO_SHOW_TIMEOUT) { gui_auto_show_timeout = atoi(value.c_str()); } else if (parameter == FLD_GUI_BROWSER_CMD) { gui_browser_cmd = value; } else if (parameter == FLD_AB_SHOW_SIP_ONLY) { ab_show_sip_only = yesno2bool(value); } else if (parameter == FLD_AB_LOOKUP_NAME) { ab_lookup_name = yesno2bool(value); } else if (parameter == FLD_AB_OVERRIDE_DISPLAY) { ab_override_display = yesno2bool(value); } else if (parameter == FLD_AB_LOOKUP_PHOTO) { ab_lookup_photo = yesno2bool(value); } else if (parameter == FLD_CH_MAX_SIZE) { ch_max_size = atoi(value.c_str()); } else if (parameter == FLD_CALL_WAITING) { call_waiting = yesno2bool(value); } else if (parameter == FLD_HANGUP_BOTH_3WAY) { hangup_both_3way = yesno2bool(value); } else if (parameter == FLD_START_USER_PROFILE) { if (!value.empty()) start_user_profiles.push_back(value); } else if (parameter == FLD_START_HIDDEN) { start_hidden = yesno2bool(value); } else if (parameter == FLD_sip_udp_port) { // Deprecated parameter config_sip_port = atoi(value.c_str()); } else if (parameter == FLD_sip_port) { config_sip_port = atoi(value.c_str()); } else if (parameter == FLD_RTP_PORT) { rtp_port = atoi(value.c_str()); } else if (parameter == FLD_SIP_MAX_UDP_SIZE) { sip_max_udp_size = atoi(value.c_str()); } else if (parameter == FLD_SIP_MAX_TCP_SIZE) { sip_max_tcp_size = atoi(value.c_str()); } else if (parameter == FLD_PLAY_RINGTONE) { play_ringtone = yesno2bool(value); } else if (parameter == FLD_RINGTONE_FILE) { ringtone_file = value; } else if (parameter == FLD_PLAY_RINGBACK) { play_ringback = yesno2bool(value); } else if (parameter == FLD_RINGBACK_FILE) { ringback_file = value; } else if (parameter == FLD_LAST_USED_PROFILE) { last_used_profile = value; } else if (parameter == FLD_REDIAL_URL) { redial_url.set_url(value); if (!redial_url.is_valid()) { redial_url.set_url(""); } } else if (parameter == FLD_REDIAL_DISPLAY) { redial_display = value; } else if (parameter == FLD_REDIAL_SUBJECT) { redial_subject = value; } else if (parameter == FLD_REDIAL_PROFILE) { redial_profile = value; } else if (parameter == FLD_REDIAL_HIDE_USER) { redial_hide_user = yesno2bool(value); } else if (parameter == FLD_DIAL_HISTORY) { dial_history.push_back(value); } else if (parameter == FLD_SHOW_DISPLAY) { show_display = yesno2bool(value); } else if (parameter == FLD_COMPACT_LINE_STATUS) { //compact_line_status = yesno2bool(value); } else if (parameter == FLD_SHOW_BUDDY_LIST) { show_buddy_list = yesno2bool(value); } else if (parameter == FLD_UI_SESSION_ID) { ui_session_id = value; } else if (parameter == FLD_UI_SESSION_ACTIVE_PROFILE) { ui_session_active_profiles.push_back(value); } else if (parameter == FLD_UI_SESSION_MAIN_GEOMETRY) { ui_session_main_geometry = value; } else if (parameter == FLD_UI_SESSION_MAIN_HIDDEN) { ui_session_main_hidden = yesno2bool(value); } else if (parameter == FLD_UI_SESSION_MAIN_STATE) { ui_session_main_state = atoi(value.c_str()); } else if (parameter == FLD_WARN_HIDE_USER) { warn_hide_user = yesno2bool(value); } else if (parameter == FLD_MIME_SHARED_DATABASE) { mime_shared_database = value; } // Unknown field names are skipped. } mtx_sys.unlock(); return true; } bool t_sys_settings::write_config(string &error_msg) { struct stat stat_buf; mtx_sys.lock(); // Make a backup of the file if we are editing an existing file, so // that can be restored when writing fails. string f_backup = filename + '~'; if (stat(filename.c_str(), &stat_buf) == 0) { if (rename(filename.c_str(), f_backup.c_str()) != 0) { string err = get_error_str(errno); error_msg = TRANSLATE("Failed to backup %1 to %2"); error_msg = replace_first(error_msg, "%1", filename); error_msg = replace_first(error_msg, "%2", f_backup); error_msg += "\n"; error_msg += err; mtx_sys.unlock(); return false; } } // Open file ofstream config(filename.c_str()); if (!config) { error_msg = TRANSLATE("Cannot open file for writing: %1"); error_msg = replace_first(error_msg, "%1", filename); mtx_sys.unlock(); return false; } // Write AUDIO settings config << "# AUDIO\n"; config << FLD_DEV_RINGTONE << '=' << dev_ringtone.get_settings_value() << endl; config << FLD_DEV_SPEAKER << '=' << dev_speaker.get_settings_value() << endl; config << FLD_DEV_MIC << '=' << dev_mic.get_settings_value() << endl; config << FLD_VALIDATE_AUDIO_DEV << '=' << bool2yesno(validate_audio_dev) << endl; config << FLD_ALSA_PLAY_PERIOD_SIZE << '=' << alsa_play_period_size << endl; config << FLD_ALSA_CAPTURE_PERIOD_SIZE << '=' << alsa_capture_period_size << endl; config << FLD_OSS_FRAGMENT_SIZE << '=' << oss_fragment_size << endl; config << endl; // Write LOG settings config << "# LOG\n"; config << FLD_LOG_MAX_SIZE << '=' << log_max_size << endl; config << FLD_LOG_SHOW_SIP << '=' << bool2yesno(log_show_sip) << endl; config << FLD_LOG_SHOW_STUN << '=' << bool2yesno(log_show_stun) << endl; config << FLD_LOG_SHOW_MEMORY << '=' << bool2yesno(log_show_memory) << endl; config << FLD_LOG_SHOW_DEBUG << '=' << bool2yesno(log_show_debug) << endl; config << endl; // Write GUI settings config << "# GUI\n"; config << FLD_GUI_USE_SYSTRAY << '=' << bool2yesno(gui_use_systray) << endl; config << FLD_GUI_HIDE_ON_CLOSE << '=' << bool2yesno(gui_hide_on_close) << endl; config << FLD_GUI_AUTO_SHOW_INCOMING << '=' << bool2yesno(gui_auto_show_incoming) << endl; config << FLD_GUI_AUTO_SHOW_TIMEOUT << '=' << gui_auto_show_timeout << endl; config << FLD_GUI_BROWSER_CMD << '=' << gui_browser_cmd << endl; config << endl; // Write address book settings config << "# Address book\n"; config << FLD_AB_SHOW_SIP_ONLY << '=' << bool2yesno(ab_show_sip_only) << endl; config << FLD_AB_LOOKUP_NAME << '=' << bool2yesno(ab_lookup_name) << endl; config << FLD_AB_OVERRIDE_DISPLAY << '=' << bool2yesno(ab_override_display) << endl; config << FLD_AB_LOOKUP_PHOTO << '=' << bool2yesno(ab_lookup_photo) << endl; config << endl; // Write call history settings config << "# Call history\n"; config << FLD_CH_MAX_SIZE << '=' << ch_max_size << endl; config << endl; // Write service settings config << "# Services\n"; config << FLD_CALL_WAITING << '=' << bool2yesno(call_waiting) << endl; config << FLD_HANGUP_BOTH_3WAY << '=' << bool2yesno(hangup_both_3way) << endl; config << endl; // Write startup settings config << "# Startup\n"; for (list::iterator i = start_user_profiles.begin(); i != start_user_profiles.end(); i++) { config << FLD_START_USER_PROFILE << '=' << *i << endl; } config << FLD_START_HIDDEN << '=' << bool2yesno(start_hidden) << endl; config << endl; // Write network settings config << "# Network\n"; config << FLD_sip_port << '=' << config_sip_port << endl; config << FLD_RTP_PORT << '=' << rtp_port << endl; config << FLD_SIP_MAX_UDP_SIZE << '=' << sip_max_udp_size << endl; config << FLD_SIP_MAX_TCP_SIZE << '=' << sip_max_tcp_size << endl; config << endl; // Write ring tone settings config << "# Ring tones\n"; config << FLD_PLAY_RINGTONE << '=' << bool2yesno(play_ringtone) << endl; config << FLD_RINGTONE_FILE << '=' << ringtone_file << endl; config << FLD_PLAY_RINGBACK << '=' << bool2yesno(play_ringback) << endl; config << FLD_RINGBACK_FILE << '=' << ringback_file << endl; config << endl; // Write MIME settings config << "# MIME settings\n"; config << FLD_MIME_SHARED_DATABASE << '=' << mime_shared_database << endl; config << endl; // Write persistent user interface state config << "# Persistent user interface state\n"; config << FLD_LAST_USED_PROFILE << '=' << last_used_profile << endl; config << FLD_REDIAL_URL << '=' << redial_url.encode() << endl; config << FLD_REDIAL_DISPLAY << '=' << redial_display << endl; config << FLD_REDIAL_SUBJECT << '=' << redial_subject << endl; config << FLD_REDIAL_PROFILE << '=' << redial_profile << endl; config << FLD_REDIAL_HIDE_USER << '=' << bool2yesno(redial_hide_user) << endl; config << FLD_SHOW_DISPLAY << '=' << bool2yesno(show_display) << endl; //config << FLD_COMPACT_LINE_STATUS << '=' << bool2yesno(compact_line_status) << endl; config << FLD_SHOW_BUDDY_LIST << '=' << bool2yesno(show_buddy_list) << endl; config << FLD_WARN_HIDE_USER << '=' << bool2yesno(warn_hide_user) << endl; for (list::iterator i = dial_history.begin(); i != dial_history.end(); i++) { config << FLD_DIAL_HISTORY << '=' << *i << endl; } config << endl; // Write session settins config << "# UI session settings\n"; config << FLD_UI_SESSION_ID << '=' << ui_session_id << endl; for (list::iterator i = ui_session_active_profiles.begin(); i != ui_session_active_profiles.end(); i++) { config << FLD_UI_SESSION_ACTIVE_PROFILE << '=' << *i << endl; } config << FLD_UI_SESSION_MAIN_GEOMETRY << '=' << ui_session_main_geometry.encode() << endl; config << FLD_UI_SESSION_MAIN_HIDDEN << '=' << bool2yesno(ui_session_main_hidden) << endl; config << FLD_UI_SESSION_MAIN_STATE << '=' << ui_session_main_state << endl; config << endl; // Check if writing succeeded if (!config.good()) { // Restore backup config.close(); rename(f_backup.c_str(), filename.c_str()); error_msg = TRANSLATE("File system error while writing file %1 ."); error_msg = replace_first(error_msg, "%1", filename); mtx_sys.unlock(); return false; } mtx_sys.unlock(); return true; } list t_sys_settings::get_oss_devices(bool playback) const { struct stat stat_buf; list l; for (int i = -1; i <= 15; i ++) { string dev = "/dev/dsp"; if (i >= 0) dev += int2str(i); t_audio_device oss_dev; oss_dev.type = t_audio_device::OSS; // Check if device exists if (stat(dev.c_str(), &stat_buf) != 0) continue; oss_dev.device = dev; // Get sound card name int fd; if (playback) { fd = open(dev.c_str(), O_WRONLY | O_NONBLOCK); } else { fd = open(dev.c_str(), O_RDONLY | O_NONBLOCK); } if (fd >= 0) { struct mixer_info soundcard_info; if (ioctl(fd, SOUND_MIXER_INFO, &soundcard_info) != -1) { oss_dev.name = ""; oss_dev.name += soundcard_info.name; oss_dev.name += " ("; oss_dev.name += soundcard_info.id; oss_dev.name += ")"; } close(fd); } else { if (errno == EBUSY) { oss_dev.name = TRANSLATE("unknown name (device is busy)"); } else { // Device is not available. continue; } } // Check if the device is a symbolic link char buf[32]; int len_link; if ((len_link = readlink(dev.c_str(), buf, 31)) != -1) { buf[len_link] = 0; oss_dev.sym_link = buf; } oss_dev.type = t_audio_device::OSS; l.push_back(oss_dev); } // If no OSS devices can be found (this should not happen), then // just add /dev/dsp as the default device. if (l.empty()) { t_audio_device oss_dev; oss_dev.device = "/dev/dsp"; oss_dev.type = t_audio_device::OSS; l.push_back(oss_dev); } // Add other device option t_audio_device other_dev; other_dev.device = DEV_OTHER; other_dev.type = t_audio_device::OSS; l.push_back(other_dev); return l; } #ifdef HAVE_LIBASOUND // Defined in audio_device.cpp void alsa_fill_soundcards(list& l, bool playback); list t_sys_settings::get_alsa_devices(bool playback) const { t_audio_device defaultDevice; defaultDevice.device = "default"; defaultDevice.name = TRANSLATE("Default device"); defaultDevice.type = t_audio_device::ALSA; list l; l.push_back(defaultDevice); alsa_fill_soundcards(l, playback); // Add other device option t_audio_device other_dev; other_dev.device = DEV_OTHER; other_dev.type = t_audio_device::ALSA; l.push_back(other_dev); return l; } #endif list t_sys_settings::get_audio_devices(bool playback) const { list d, d0; #ifdef HAVE_LIBASOUND d = get_alsa_devices(playback); #endif d0 = get_oss_devices(playback); d.insert(d.end(), d0.begin(), d0.end()); return d; } bool t_sys_settings::equal_audio_dev(const t_audio_device &dev1, const t_audio_device &dev2) const { if (dev1.type == t_audio_device::OSS) { if (dev2.type != t_audio_device::OSS) return false; if (dev1.device == dev2.device) return true; char symlink1[32], symlink2[32]; int len_link1, len_link2; len_link1 = readlink(dev1.device.c_str(), symlink1, 31); len_link2 = readlink(dev2.device.c_str(), symlink2, 31); if (len_link1 > 0) { symlink1[len_link1] = 0; string symdev1 = "/dev/"; symdev1 += symlink1; if (len_link2 > 0) { symlink2[len_link2] = 0; string symdev2 = "/dev/"; symdev2 += symlink2; return symdev1 == symdev2; } else { return dev2.device == symdev1; } } else { if (len_link2 > 0) { symlink2[len_link2] = 0; string symdev2 = "/dev/"; symdev2 += symlink2; return dev1.device == symdev2; } } } else if (dev1.type == t_audio_device::ALSA) { if (dev2.type != t_audio_device::ALSA) return false; return dev1.device == dev2.device; } return false; } t_audio_device t_sys_settings::audio_device(string device) { t_audio_device d; if (device.empty()) device = DEV_DSP; //This is the default device if (device.substr(0, strlen(PFX_OSS)) == PFX_OSS) { // OSS device d.device = device.substr(strlen(PFX_OSS)); d.type = t_audio_device::OSS; d.name = ""; char symlink[32]; int len_link = readlink(device.c_str(), symlink, 31); if(len_link > 0) { d.sym_link = symlink; } } else if (device.substr(0, strlen(PFX_ALSA)) == PFX_ALSA) { // ALSA device d.device = device.substr(strlen(PFX_ALSA)); d.type = t_audio_device::ALSA; d.name = ""; d.sym_link = ""; } else { // Assume it is an OSS device. Version 0.2.1 and lower // only supported OSS and the value only consisted of // the device name without "oss:" d.device = device; d.type = t_audio_device::OSS; d.name = ""; char symlink[32]; int len_link = readlink(device.c_str(), symlink, 31); if(len_link > 0) { d.sym_link = symlink; } } return d; } bool t_sys_settings::exec_audio_validation(bool ringtone, bool speaker, bool mic, string &error_msg) const { error_msg.clear(); if (!validate_audio_dev) return true; bool valid = true; bool full_duplex = speaker && mic && equal_audio_dev(dev_speaker, dev_mic); if (ringtone && !t_audio_io::validate(dev_ringtone, true, false)) { string msg = TRANSLATE("Cannot access the ring tone device (%1)."); error_msg += replace_first(msg, "%1", dev_ringtone.get_description()); error_msg += "\n"; valid = false; } if (speaker && !t_audio_io::validate(dev_speaker, true, full_duplex)) { string msg = TRANSLATE("Cannot access the speaker (%1)."); error_msg += replace_first(msg, "%1", dev_speaker.get_description()); error_msg += "\n"; valid = false; } if (mic && !t_audio_io::validate(dev_mic, full_duplex, true)) { string msg = TRANSLATE("Cannot access the microphone (%1)."); error_msg += replace_first(msg, "%1", dev_mic.get_description()); error_msg += "\n"; valid = false; } return valid; } unsigned short t_sys_settings::get_sip_port(bool force_active) { mtx_sys.lock(); // The configured port becomes the active port after first // usage of the port. if (!active_sip_port || force_active) { if (override_sip_port > 0) { // The port provided on the command line overrides // the configured port. active_sip_port = override_sip_port; } else { active_sip_port = config_sip_port; } } mtx_sys.unlock(); return active_sip_port; } twinkle-1.4.2/src/listener.cpp0000644000175000001440000004422611134614733013243 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "events.h" #include "listener.h" #include "log.h" #include "sys_settings.h" #include "translator.h" #include "user.h" #include "userintf.h" #include "util.h" #include "im/im_iscomposing_body.h" #include "sockets/connection_table.h" #include "sockets/socket.h" #include "parser/parse_ctrl.h" #include "parser/sip_message.h" #include "sdp/sdp_parse_ctrl.h" #include "stun/stun.h" #include "audits/memman.h" #include "presence/pidf_body.h" extern t_phone *phone; extern t_socket_udp *sip_socket; extern t_socket_tcp *sip_socket_tcp; extern t_connection_table *connection_table; extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_trans_layer; // Minimal size of a message. Messages below this size will // be silently discarded. #define MIN_MESSAGE_SIZE 10 // Maximum number of pending TCP connections. #define TCP_BACKLOG 5 void recvd_stun_msg(char *datagram, int datagram_size, unsigned long src_addr, unsigned short src_port) { StunMessage m; if (!stunParseMessage(datagram, datagram_size, m, false)) { log_file->write_report("Received faulty STUN message", "::recvd_stun_msg", LOG_STUN, LOG_DEBUG); return; } log_file->write_header("::recvd_stun_msg", LOG_STUN); log_file->write_raw("Received from: "); log_file->write_raw(h_ip2str(src_addr)); log_file->write_raw(":"); log_file->write_raw(src_port); log_file->write_endl(); log_file->write_raw(stunMsg2Str(m)); log_file->write_footer(); evq_trans_mgr->push_stun_response(&m, 0, 0); } t_sip_body *parse_body(const string &data, const t_sip_message *msg) { if (!msg->hdr_content_type.is_populated()) { // Content-Type header is missing. Pass body // unparsed. The upper application layer will // decide what to do. t_sip_body_opaque *p = new t_sip_body_opaque(data); MEMMAN_NEW(p); return p; } if (msg->hdr_content_type.media.type == "application" && msg->hdr_content_type.media.subtype == "sdp") { // Parse SDP body return t_sdp_parser::parse(data); } else if (msg->hdr_content_type.media.type == "message" && msg->hdr_content_type.media.subtype == "sipfrag") { t_sip_body_sipfrag *b; // Parse sipfrag body (RFC 3420) try { // If the sipfrag does not contain a body itself, // then the CRLF at the end of the headers is optional! // Add an additional CRLF such that the SIP parser will // parse a sipfrag if the CRLF is not present. The SIP // parser will stop after it finds the double CRLF. So // a 3rd CRLF will not be detected by the parser (yuck). list parse_errors; t_sip_message *m = t_parser::parse(data + CRLF, parse_errors); b = new t_sip_body_sipfrag(m); MEMMAN_NEW(b); MEMMAN_DELETE(m); delete m; return b; } catch (int) { // Parsing failed, maybe because a request or status // line is not present, which is not mandatory for a // sipfrag body. Add a fake status line and try to parse // again. string tmp = "SIP/2.0 100 Trying"; tmp += CRLF; tmp += data; tmp += CRLF; list parse_errors; t_sip_message *resp = t_parser::parse(tmp, parse_errors); // Parsing succeeded. Now strip the fake header t_sip_message *m = new t_sip_message(*resp); MEMMAN_NEW(m); MEMMAN_DELETE(resp); delete (resp); b = new t_sip_body_sipfrag(m); MEMMAN_NEW(b); MEMMAN_DELETE(m); delete m; return b; } } else if (msg->hdr_content_type.media.type == "application" && msg->hdr_content_type.media.subtype == "dtmf-relay") { t_sip_body_dtmf_relay *b = new t_sip_body_dtmf_relay(); MEMMAN_NEW(b); if (b->parse(data)) return b; MEMMAN_DELETE(b); delete b; throw -1; } else if (msg->hdr_content_type.media.type == "application" && msg->hdr_content_type.media.subtype == "simple-message-summary") { t_simple_msg_sum_body *b = new t_simple_msg_sum_body(); MEMMAN_NEW(b); if (b->parse(data)) return b; MEMMAN_DELETE(b); delete b; throw -1; } else if (msg->hdr_content_type.media.type == "text" && msg->hdr_content_type.media.subtype == "plain") { t_sip_body_plain_text *b = new t_sip_body_plain_text(data); MEMMAN_NEW(b); return b; } else if (msg->hdr_content_type.media.type == "text" && msg->hdr_content_type.media.subtype == "html") { t_sip_body_html_text *b = new t_sip_body_html_text(data); MEMMAN_NEW(b); return b; } else if (msg->hdr_content_type.media.type == "application" && msg->hdr_content_type.media.subtype == "pidf+xml") { t_pidf_xml_body *b = new t_pidf_xml_body(); MEMMAN_NEW(b); if (b->parse(data)) return b; MEMMAN_DELETE(b); delete b; throw -1; } else if (msg->hdr_content_type.media.type == "application" && msg->hdr_content_type.media.subtype == "im-iscomposing+xml") { t_im_iscomposing_xml_body *b = new t_im_iscomposing_xml_body(); MEMMAN_NEW(b); if (b->parse(data)) return b; MEMMAN_DELETE(b); delete b; throw -1; } else { // Pass other bodies unparsed. The upper application // layer will decide what to do. t_sip_body_opaque *p = new t_sip_body_opaque(data); MEMMAN_NEW(p); return p; } } static void process_sip_msg(t_sip_message *msg, const string &raw_headers, const string &raw_body) { t_event_network *ev_network; string log_msg; // SIP message received log_msg = "Received from: "; log_msg += msg->src_ip_port.tostring(); log_msg += "\n"; // Parse body if (!raw_body.empty()) { // The body should only be parsed if it is complete. // NOTE: The Content-length header may be absent (UDP) if (!msg->hdr_content_length.is_populated() || msg->hdr_content_length.length == raw_body.size()) { try { msg->body = parse_body(raw_body, msg); } catch (int) { if (msg->get_type() == MSG_RESPONSE) { // Discard a SIP response if the body is malformed. log_msg += "Invalid SIP message.\n"; log_msg += "Parse error in body.\n"; log_msg += to_printable(raw_headers); log_msg += to_printable(raw_body); log_file->write_report(log_msg, "::process_sip_msg", LOG_SIP, LOG_DEBUG); return; } else { // For a SIP request with a malformed body, the // transaction layer will give an error response. // Set the invalid body indication for the transaction // layer. msg->body = new t_sip_body_opaque(); MEMMAN_NEW(msg->body); msg->body->invalid = true; } } } else { log_file->write_report("Received incomplete body", "::process_sip_msg", LOG_NORMAL, LOG_WARNING); } } log_msg += to_printable(raw_headers); log_msg += to_printable(raw_body); log_file->write_report(log_msg, "::process_sip_msg", LOG_SIP); // If the message does not satisfy the mandatory // requirements from RFC 3261, then discard. // If the error is non-fatal, then the transaction layer // will send a proper error response. // If the message is an invalid response message then // discard the message. The transaction layer cannot // handle an invalid response as it cannot send an // error message back on an answer. bool fatal; string reason; if (!msg->is_valid(fatal, reason) && (fatal || msg->get_type() == MSG_RESPONSE)) { log_file->write_header("::process_sip_msg", LOG_SIP); log_file->write_raw("Discard invalid message.\n"); log_file->write_raw(reason); log_file->write_endl(); log_file->write_footer(); return; } if (msg->get_type() == MSG_REQUEST) { // RFC 3261 18.2.1 // When the server transport receives a request over any transport, it // MUST examine the value of the "sent-by" parameter in the top Via // header field value. If the host portion of the "sent-by" parameter // contains a domain name, or if it contains an IP address that differs // from the packet source address, the server MUST add a "received" // parameter to that Via header field value. This parameter MUST // contain the source address from which the packet was received. string src_ip = h_ip2str(msg->src_ip_port.ipaddr); t_via &top_via = msg->hdr_via.via_list.front(); if (top_via.host != src_ip) { top_via.received = src_ip; log_file->write_header("::process_sip_msg", LOG_SIP); log_file->write_raw("Added via-parameter received="); log_file->write_raw(src_ip); log_file->write_endl(); log_file->write_footer(); } // RFC 3581 4 // Add rport value if requested // Add received parameter if (top_via.rport_present && top_via.rport == 0) { top_via.rport = msg->src_ip_port.port; top_via.received = src_ip; } } ev_network = new t_event_network(msg); MEMMAN_NEW(ev_network); ev_network->src_addr = msg->src_ip_port.ipaddr; ev_network->src_port = msg->src_ip_port.port; ev_network->transport = msg->src_ip_port.transport; evq_trans_mgr->push(ev_network); } void *listen_udp(void *arg) { char buf[sys_config->get_sip_max_udp_size() + 1]; int data_size; unsigned long src_addr; unsigned short src_port; t_sip_message *msg; t_event_icmp *ev_icmp; string::size_type pos_body; // position of body in msg string log_msg; // Number of consecutive non-icmp errors received int num_non_icmp_errors = 0; while(true) { try { data_size = sip_socket->recvfrom(src_addr, src_port, buf, sys_config->get_sip_max_udp_size() + 1); num_non_icmp_errors = 0; } catch (int err) { // Check if an ICMP error has been received t_icmp_msg icmp; if (sip_socket->get_icmp(icmp)) { log_msg = "Received ICMP from: "; log_msg += h_ip2str(icmp.icmp_src_ipaddr); log_msg += "\nICMP type: "; log_msg += int2str(icmp.type); log_msg += "\nICMP code: "; log_msg += int2str(icmp.code); log_msg += "\nDestination of packet causing ICMP: "; log_msg += h_ip2str(icmp.ipaddr); log_msg += ":"; log_msg += int2str(icmp.port); log_msg += "\nSocket error: "; log_msg += int2str(err); log_msg += " "; log_msg += get_error_str(err); log_file->write_report(log_msg, "::listen_udp", LOG_NORMAL); ev_icmp = new t_event_icmp(icmp); MEMMAN_NEW(ev_icmp); evq_trans_mgr->push(ev_icmp); num_non_icmp_errors = 0; } else { // Even if an ICMP message is received this code can get // executed. Sometimes the error is already present on // the socket, but the ICMP message is not yet queued. log_msg = "Failed to receive from SIP UDP socket.\n"; log_msg += "Error code: "; log_msg += int2str(err); log_msg += "\n"; log_msg += get_error_str(err); log_file->write_report(log_msg, "::listen_udp"); num_non_icmp_errors++; /* * non-ICMP errors occur when a destination on the same * subnet cannot be reached. So this code seems to be * harmful. if (num_non_icmp_errors > 100) { log_msg = "Excessive number of socket errors."; log_file->write_report(log_msg, "::listen_udp", LOG_NORMAL, LOG_CRITICAL); log_msg = TRANSLATE("Excessive number of socket errors."); ui->cb_show_msg(log_msg, MSG_CRITICAL); exit(1); } */ } continue; } // Some SIP proxies send small keep alive packets to keep // NAT bindings open. Discard such small packets as these // are not SIP or STUN messages. if (data_size < MIN_MESSAGE_SIZE) continue; // Check if this is a STUN message // The first byte of a STUN message is 0x00 or 0x01. // A SIP message is ASCII so the first byte for SIP is // never 0x00 or 0x01 if (buf[0] <= 1) { recvd_stun_msg(buf, data_size, src_addr, src_port); continue; } // A SIP message may contain a NULL character (binary body), // do not handle the buffer as a C string. string datagram(buf, data_size); // Split body from header string seperator = string(CRLF) + string(CRLF); pos_body = datagram.find(seperator); // According to RFC 3261 syntax an empty line at // the end of the headers is mandatory in all SIP messages. // Here a missing empty line is accepted, but maybe // the message should be discarded. if (pos_body != string::npos) { pos_body += seperator.size(); if (pos_body >= datagram.size()) { // No body is present pos_body = string::npos; } } // Parse SIP headers string raw_headers = datagram.substr(0, pos_body); list parse_errors; try { msg = t_parser::parse(raw_headers, parse_errors); msg->src_ip_port.ipaddr = src_addr; msg->src_ip_port.port = src_port; msg->src_ip_port.transport = "udp"; } catch (int) { // Discard malformed SIP messages. log_msg = "Invalid SIP message.\n"; log_msg += "Fatal parse error in headers.\n\n"; log_msg += to_printable(datagram); log_msg += "\n"; log_file->write_report(log_msg, "::listen_udp", LOG_SIP, LOG_DEBUG); continue; } // Log non-fatal parse errors. if (!parse_errors.empty()) { log_msg = "Parse errors:\n"; log_msg += "\n"; for (list::iterator i = parse_errors.begin(); i != parse_errors.end(); i++) { log_msg += *i; log_msg += "\n"; } log_msg += "\n"; log_file->write_report(log_msg, "::listen_udp", LOG_SIP, LOG_DEBUG); } // Get raw body string raw_body; if (pos_body != string::npos) { raw_body = datagram.substr(pos_body); } process_sip_msg(msg, raw_headers, raw_body); MEMMAN_DELETE(msg); delete msg; } log_file->write_report("UDP listener terminated.", "::listen_udp"); return NULL; } void *listen_for_data_tcp(void *arg) { string log_msg; list readable_connections; while(true) { readable_connections.clear(); readable_connections = connection_table->select_read(NULL); if (readable_connections.empty()) { // Another thread cancelled the select command. // Stop listening. break; } // NOTE: The connection table is now locked. for (list::iterator it = readable_connections.begin(); it != readable_connections.end(); ++it) { string raw_headers; string raw_body; unsigned long remote_addr; unsigned short remote_port; (*it)->get_remote_address(remote_addr, remote_port); try { bool connection_closed; (*it)->read(connection_closed); if (connection_closed) { log_msg = "Connection to "; log_msg += h_ip2str(remote_addr); log_msg += ":"; log_msg += int2str(remote_port); log_msg += " closed."; log_file->write_report(log_msg, "::listen_for_data_tcp", LOG_SIP, LOG_DEBUG); connection_table->remove_connection(*it); MEMMAN_DELETE(*it); delete *it; continue; } } catch (int err) { if (err == EAGAIN || err == EINTR) { continue; } log_msg = "Got error on socket to "; log_msg += h_ip2str(remote_addr); log_msg += ":"; log_msg += int2str(remote_port); log_msg += " - "; log_msg += get_error_str(err); log_file->write_report(log_msg, "::listen_for_data_tcp", LOG_SIP, LOG_WARNING); // Connection is broken. // Signal the transaction layer that the connection is broken for // all associated registered URI's. const list &uris = (*it)->get_registered_uri_set(); for (list::const_iterator it_uri = uris.begin(); it_uri != uris.end(); ++it_uri) { evq_trans_layer->push_broken_connection(*it_uri); } // Remove the broken connection. connection_table->remove_connection(*it); MEMMAN_DELETE(*it); delete *it; continue; } // Multiple messages may have been read in one action. // Get all SIP messages from the connection. while (true) { bool error = false; bool msg_too_large = false; t_sip_message *msg = (*it)->get_sip_msg(raw_headers, raw_body, error, msg_too_large); if (error) { // The data on the connection could not be interpreted. // Close the connection to a faulty remote end. connection_table->remove_connection(*it); MEMMAN_DELETE(*it); delete *it; break; } if (msg_too_large) { // Close the connection. The message was too long, we don't want // to receive more data. Now we have an incomplete message, // but as we most likely have all headers we can still // send an error response, so the message is processed. connection_table->remove_connection(*it); MEMMAN_DELETE(*it); delete *it; } if (!msg) { // There are no complete messages on the connection. // Stop reading from this connection. break; } process_sip_msg(msg, raw_headers, raw_body); MEMMAN_DELETE(msg); delete msg; if (msg_too_large) { // The connection is closed already. Stop reading. break; } } } connection_table->unlock(); } log_file->write_report("TCP data listener terminated.", "::listen_for_data_tcp"); return NULL; } void *listen_for_conn_requests_tcp(void *arg) { unsigned long dst_addr; unsigned short dst_port; string log_msg; while (true) { try { sip_socket_tcp->listen(TCP_BACKLOG); t_socket_tcp *tcp = sip_socket_tcp->accept(dst_addr, dst_port); t_connection *conn = new t_connection(tcp); MEMMAN_NEW(conn); connection_table->add_connection(conn); } catch (int err) { if (err == EAGAIN || err == EINTR) continue; log_file->write_header("::listen_for_conn_requests_tcp", LOG_SIP, LOG_CRITICAL); log_file->write_raw("Error on accept on TCP socket: "); log_file->write_raw(get_error_str(err)); log_file->write_endl(); log_file->write_footer(); log_msg = TRANSLATE("Cannot receive incoming TCP connections."); ui->cb_show_msg(log_msg, MSG_CRITICAL); break; } } log_file->write_report("TCP connection listener terminated.", "::listen_for_conn_requests_tcp"); return NULL; } twinkle-1.4.2/src/transaction_mgr.cpp0000644000175000001440000004547011134640315014605 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "log.h" #include "transaction_mgr.h" #include "sockets/url.h" #include "util.h" #include "audits/memman.h" extern t_event_queue *evq_trans_mgr; extern t_event_queue *evq_trans_layer; extern t_event_queue *evq_timekeeper; extern t_transaction_mgr *transaction_mgr; t_trans_client *t_transaction_mgr::find_trans_client(t_response *r) const { map::const_iterator i; for (i = map_trans_client.begin(); i != map_trans_client.end(); ++i) { if (i->second->match(r)) return i->second; } return NULL; } t_trans_client *t_transaction_mgr::find_trans_client(t_tid tid) const { map::const_iterator i; i = map_trans_client.find(tid); if (i == map_trans_client.end()) return NULL; return i->second; } t_trans_client *t_transaction_mgr::find_trans_client(const string &branch, const t_method &cseq_method) const { map::const_iterator i; for (i = map_trans_client.begin(); i != map_trans_client.end(); ++i) { if (i->second->match(branch, cseq_method)) return i->second; } return NULL; } t_trans_client *t_transaction_mgr::find_trans_client(const t_icmp_msg &icmp) const { map::const_iterator i; for (i = map_trans_client.begin(); i != map_trans_client.end(); ++i) { if (i->second->match(icmp)) return i->second; } return NULL; } t_trans_server *t_transaction_mgr::find_trans_server(t_request *r) const { map::const_iterator i; for (i = map_trans_server.begin(); i != map_trans_server.end(); i++) { if (i->second->match(r)) return i->second; } return NULL; } t_trans_server *t_transaction_mgr::find_trans_server(t_tid tid) const { map::const_iterator i; i = map_trans_server.find(tid); if (i == map_trans_server.end()) return NULL; return i->second; } t_stun_transaction *t_transaction_mgr::find_stun_trans(StunMessage *r) const { map::const_iterator i; for (i = map_stun_trans.begin(); i != map_stun_trans.end(); ++i) { if (i->second->match(r)) return i->second; } return NULL; } t_stun_transaction *t_transaction_mgr::find_stun_trans(t_tid tid) const { map::const_iterator i; i = map_stun_trans.find(tid); if (i == map_stun_trans.end()) return NULL; return i->second; } t_stun_transaction *t_transaction_mgr::find_stun_trans(const t_icmp_msg &icmp) const { map::const_iterator i; for (i = map_stun_trans.begin(); i != map_stun_trans.end(); ++i) { if (i->second->match(icmp)) return i->second; } return NULL; } t_trans_server *t_transaction_mgr::find_cancel_target(t_request *r) const { map::const_iterator i; for (i = map_trans_server.begin(); i != map_trans_server.end(); ++i) { if (i->second->match_cancel(r)) return i->second; } return NULL; } t_tc_invite *t_transaction_mgr::create_tc_invite(t_user *user_config, t_request *r, unsigned short tuid) { t_ip_port ip_port; r->get_destination(ip_port, *user_config); if (ip_port.ipaddr == 0 || ip_port.port == 0) return NULL; t_tc_invite *t = new t_tc_invite(r, ip_port, tuid); MEMMAN_NEW(t); map_trans_client[t->get_id()] = (t_trans_client *)t; return t; } t_tc_non_invite *t_transaction_mgr::create_tc_non_invite(t_user *user_config, t_request *r, unsigned short tuid) { t_ip_port ip_port; r->get_destination(ip_port, *user_config); if (ip_port.ipaddr == 0 || ip_port.port == 0) return NULL; t_tc_non_invite *t = new t_tc_non_invite(r, ip_port, tuid); MEMMAN_NEW(t); map_trans_client[t->get_id()] = (t_trans_client *)t; return t; } t_ts_invite *t_transaction_mgr::create_ts_invite(t_request *r) { t_ts_invite *t = new t_ts_invite(r, 0); MEMMAN_NEW(t); map_trans_server[t->get_id()] = (t_trans_server *)t; return t; } t_ts_non_invite *t_transaction_mgr::create_ts_non_invite(t_request *r) { t_ts_non_invite *t = new t_ts_non_invite(r, 0); MEMMAN_NEW(t); map_trans_server[t->get_id()] = (t_trans_server *)t; return t; } t_sip_stun_trans *t_transaction_mgr::create_sip_stun_trans(t_user *user_config, StunMessage *r, unsigned short tuid) { list destinations = user_config->get_stun_server().get_h_ip_srv("udp"); if (destinations.empty()) return NULL; t_sip_stun_trans *t = new t_sip_stun_trans(user_config, r, tuid, destinations); MEMMAN_NEW(t); map_stun_trans[t->get_id()] = (t_stun_transaction *)t; return t; } t_media_stun_trans *t_transaction_mgr::create_media_stun_trans(t_user *user_config, StunMessage *r, unsigned short tuid, unsigned short src_port) { list destinations = user_config->get_stun_server().get_h_ip_srv("udp"); if (destinations.empty()) return NULL; t_media_stun_trans *t = new t_media_stun_trans(user_config, r, tuid, destinations, src_port); MEMMAN_NEW(t); map_stun_trans[t->get_id()] = (t_stun_transaction *)t; return t; } void t_transaction_mgr::delete_trans_client(t_trans_client *tc) { map_trans_client.erase(tc->get_id()); MEMMAN_DELETE(tc); delete tc; } void t_transaction_mgr::delete_trans_server(t_trans_server *ts) { map_trans_server.erase(ts->get_id()); MEMMAN_DELETE(ts); delete ts; } void t_transaction_mgr::delete_stun_trans(t_stun_transaction *st) { map_stun_trans.erase(st->get_id()); MEMMAN_DELETE(st); delete st; } t_transaction_mgr::~t_transaction_mgr() { log_file->write_header("t_transaction_mgr::~t_transaction_mgr", LOG_NORMAL, LOG_INFO); log_file->write_raw("Clean up transaction manager.\n"); map::iterator i; for (i = map_trans_client.begin(); i != map_trans_client.end(); i++) { log_file->write_raw("\nDeleting client transaction: \n"); log_file->write_raw("Tid: "); log_file->write_raw(i->first); log_file->write_raw(", Method: "); log_file->write_raw(method2str(i->second->get_method())); log_file->write_raw(", State: "); log_file->write_raw(trans_state2str(i->second->get_state())); log_file->write_endl(); MEMMAN_DELETE(i->second); delete i->second; } map::iterator j; for (j = map_trans_server.begin(); j != map_trans_server.end(); j++) { log_file->write_raw("\nDeleting server transaction: \n"); log_file->write_raw("Tid: "); log_file->write_raw(j->first); log_file->write_raw(", Method: "); log_file->write_raw(method2str(j->second->get_method())); log_file->write_raw(", State: "); log_file->write_raw(trans_state2str(j->second->get_state())); log_file->write_endl(); MEMMAN_DELETE(j->second); delete j->second; } map::iterator k; for (k = map_stun_trans.begin(); k != map_stun_trans.end(); k++) { log_file->write_raw("\nDeleting STUN transaction: \n"); log_file->write_raw("Tid: "); log_file->write_raw(k->first); log_file->write_raw(", State: "); log_file->write_raw(trans_state2str(k->second->get_state())); log_file->write_endl(); MEMMAN_DELETE(k->second); delete k->second; } log_file->write_footer(); } void t_transaction_mgr::handle_event_network(t_event_network *e) { t_trans_server *ts; t_ts_invite *ts_invite; t_trans_client *tc; t_sip_message *msg = e->get_msg(); t_request *request; t_response *response; switch(msg->get_type()) { case MSG_REQUEST: // Request from network is for a server transaction request = (t_request *)msg; ts = find_trans_server(request); if (ts) { switch (request->method) { case ACK: // ACK for an INVITE transaction ts_invite = (t_ts_invite *)ts; ts_invite->acknowledge(request); break; default: // A request that matches an existing // transaction is a retransmission ts->process_retransmission(); break; } if (ts->get_state() == TS_TERMINATED) { delete_trans_server(ts); } return; } // Create a new transaction switch (request->method) { case INVITE: create_ts_invite(request); break; case ACK: // ACK should be passed to TU evq_trans_layer->push_user(request, 0, 0); break; default: create_ts_non_invite(request); break; } break; case MSG_RESPONSE: // Response from network is for a client transaction response = (t_response *)msg; tc = find_trans_client(response); if (!tc) { // Only a 2XX for an INVITE transaction can be // received while no transaction exists anymore. // RFC 3261 17.1.1.2 if (response->is_success() && response->hdr_cseq.method == INVITE) { // Report to TU evq_trans_layer->push_user(response, 0, 0); } else { log_file->write_report( "Response does not match any transaction. Discard.", "t_transaction_mgr::handle_event_network"); } break; } tc->process_response(response); if (tc->get_state() == TS_TERMINATED) { delete_trans_client(tc); } break; default: assert(false); break; } } void t_transaction_mgr::handle_event_user(t_event_user *e) { t_trans_server *ts; t_sip_message *msg = e->get_msg(); t_request *request; t_response *response; switch(msg->get_type()) { case MSG_REQUEST: // A user request creates a client transaction request = (t_request *)msg; switch (request->method) { case INVITE: t_tc_invite *t1; assert(e->get_user_config()); t1 = create_tc_invite(e->get_user_config(), request, e->get_tuid()); if (t1 == NULL) { // Report 404 to TU response = request->create_response( R_404_NOT_FOUND); log_file->write_header( "t_transaction_mgr::handle_event_user", LOG_NORMAL, LOG_INFO); log_file->write_raw("Cannot resolve destination for:\n"); log_file->write_raw(request->encode()); log_file->write_endl(); log_file->write_raw("Send internal:\n"); log_file->write_raw(response->encode()); log_file->write_footer(); evq_trans_layer->push_user(response, e->get_tuid(), 0); MEMMAN_DELETE(response); delete response; } break; default: t_tc_non_invite *t2; assert(e->get_user_config()); t2 = create_tc_non_invite(e->get_user_config(), request, e->get_tuid()); if (t2 == NULL) { // Report 404 to TU response = request->create_response( R_404_NOT_FOUND); log_file->write_header( "t_transaction_mgr::handle_event_user", LOG_NORMAL, LOG_INFO); log_file->write_raw("Cannot resolve destination for:\n"); log_file->write_raw(request->encode()); log_file->write_endl(); log_file->write_raw("Send internal:\n"); log_file->write_raw(response->encode()); log_file->write_footer(); evq_trans_layer->push_user(response, e->get_tuid(), 0); MEMMAN_DELETE(response); delete response; } break; } break; case MSG_RESPONSE: // A user repsonse is for a server transaction response = (t_response *)msg; ts = find_trans_server(e->get_tid()); if (!ts) { // This is an error. A response should match a // transaction. Ignore it. log_file->write_report( "Response from user does not match any transaction. Ignore.", "t_transaction_mgr::handle_event_user", LOG_NORMAL, LOG_WARNING); return; } ts->process_response(response); if (ts->get_state() == TS_TERMINATED) { delete_trans_server(ts); } break; default: assert(false); break; } } void t_transaction_mgr::handle_event_timeout(t_event_timeout *e) { t_timer *t = e->get_timer(); t_tmr_transaction *tmr_trans; t_tmr_stun_trans *tmr_stun_trans; t_tid tid; t_trans_client *tc; t_trans_server *ts; t_stun_transaction *st; switch (t->get_type()) { case TMR_TRANSACTION: tmr_trans = (t_tmr_transaction *)t; tid = tmr_trans->get_tid(); tc = find_trans_client(tid); if (tc) { tc->timeout(tmr_trans->get_sip_timer()); if (tc->get_state() == TS_TERMINATED) { delete_trans_client(tc); } return; } ts = find_trans_server(tid); if (ts) { ts->timeout(tmr_trans->get_sip_timer()); if (ts->get_state() == TS_TERMINATED) { delete_trans_server(ts); } return; } // The transaction is already gone. Discard timeout. break; case TMR_STUN_TRANSACTION: tmr_stun_trans = (t_tmr_stun_trans *)t; tid = tmr_stun_trans->get_tid(); st = find_stun_trans(tid); if (st) { st->timeout(tmr_stun_trans->get_stun_timer()); if (st->get_state() == TS_TERMINATED) { delete_stun_trans(st); } return; } // The transaction is already gone. Discard timeout. break; default: assert(false); break; } } void t_transaction_mgr::handle_event_abort(t_event_abort_trans *e) { t_tid tid; t_trans_client *tc; // Only a client transaction can be aborted. tid = e->get_tid(); tc = find_trans_client(tid); if (tc) { tc->abort(); if (tc->get_state() == TS_TERMINATED) { delete_trans_client(tc); } } } void t_transaction_mgr::handle_event_stun_request(t_event_stun_request *e) { StunMessage *msg = e->get_msg(); unsigned short tuid = e->get_tuid(); unsigned short tid = e->get_tid(); t_sip_stun_trans *sst; t_media_stun_trans *mst; StunMessage *resp; switch(e->get_stun_event_type()) { case TYPE_STUN_SIP: assert(e->get_user_config()); sst = create_sip_stun_trans(e->get_user_config(), msg, tuid); if (!sst) { // STUN server not found log_file->write_header( "t_transaction_mgr::handle_event_stun_request", LOG_NORMAL, LOG_INFO); log_file->write_raw("Cannot resolve:\n"); log_file->write_raw(e->get_user_config()->get_stun_server().encode()); log_file->write_endl(); log_file->write_raw("Send internal: 404 Not Found\n"); log_file->write_footer(); resp = stunBuildError(*msg, 404, "Not Found"); evq_trans_layer->push_stun_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; } break; case TYPE_STUN_MEDIA: assert(e->get_user_config()); mst = create_media_stun_trans(e->get_user_config(), msg, tuid, e->src_port); if (!mst) { // STUN server not found log_file->write_header( "t_transaction_mgr::handle_event_stun_request", LOG_NORMAL, LOG_INFO); log_file->write_raw("Cannot resolve:\n"); log_file->write_raw(e->get_user_config()->get_stun_server().encode()); log_file->write_endl(); log_file->write_raw("Send internal: 404 Not Found\n"); log_file->write_footer(); resp = stunBuildError(*msg, 404, "Not Found"); evq_trans_layer->push_stun_response(resp, tuid, tid); MEMMAN_DELETE(resp); delete resp; } break; default: assert(false); break; } } void t_transaction_mgr::handle_event_stun_response(t_event_stun_response *e) { StunMessage *response = e->get_msg(); t_stun_transaction *st = find_stun_trans(response); if (!st) { // This response does not match any transaction. // Ignore it. return; } st->process_response(response); if (st->get_state() == TS_TERMINATED) { delete_stun_trans(st); } } void t_transaction_mgr::handle_event_icmp(t_event_icmp *e) { // Only a client and STUN transactions can handle ICMP errors // If both a client and STUN transaction match then send the ICMP // error to both transactions. It cannot be determined which transaction // caused the error, but as both transactions have the same destination // it is likely that both will fail. t_trans_client *tc = find_trans_client(e->get_icmp()); if (tc) { tc->process_icmp(e->get_icmp()); if (tc->get_state() == TS_TERMINATED) { delete_trans_client(tc); } } t_stun_transaction *st = find_stun_trans(e->get_icmp()); if (st) { st->process_icmp(e->get_icmp()); if (st->get_state() == TS_TERMINATED) { delete_stun_trans(st); } } } void t_transaction_mgr::handle_event_failure(t_event_failure *e) { // Only a client transaction can handle failure events. t_trans_client *tc; if (e->is_tid_populated()) { tc = find_trans_client(e->get_tid()); } else { tc = find_trans_client(e->get_branch(), e->get_cseq_method()); } if (tc) { tc->process_failure(e->get_failure()); if (tc->get_state() == TS_TERMINATED) { delete_trans_client(tc); } } } t_object_id t_transaction_mgr::start_timer(long dur, t_sip_timer tmr, unsigned short tid) { t_tmr_transaction *t = new t_tmr_transaction(dur, tmr, tid); MEMMAN_NEW(t); evq_timekeeper->push_start_timer(t); t_object_id timer_id = t->get_object_id(); MEMMAN_DELETE(t); delete t; return timer_id; } t_object_id t_transaction_mgr::start_stun_timer(long dur, t_stun_timer tmr, unsigned short tid) { t_tmr_stun_trans *t = new t_tmr_stun_trans(dur, tmr, tid); MEMMAN_NEW(t); evq_timekeeper->push_start_timer(t); t_object_id timer_id = t->get_object_id(); MEMMAN_DELETE(t); delete t; return timer_id; } void t_transaction_mgr::stop_timer(t_object_id id) { evq_timekeeper->push_stop_timer(id); } void t_transaction_mgr::run(void) { t_event *event; t_event_network *ev_network; t_event_user *ev_user; t_event_timeout *ev_timeout; t_event_abort_trans *ev_abort; t_event_stun_request *ev_stun_request; t_event_stun_response *ev_stun_response; t_event_icmp *ev_icmp; t_event_failure *ev_failure; bool quit = false; while (!quit) { event = evq_trans_mgr->pop(); switch (event->get_type()) { case EV_NETWORK: ev_network = dynamic_cast(event); handle_event_network(ev_network); break; case EV_USER: ev_user = dynamic_cast(event); handle_event_user(ev_user); break; case EV_TIMEOUT: ev_timeout = dynamic_cast(event); handle_event_timeout(ev_timeout); break; case EV_ABORT_TRANS: ev_abort = dynamic_cast(event); handle_event_abort(ev_abort); break; case EV_STUN_REQUEST: ev_stun_request = dynamic_cast(event); handle_event_stun_request(ev_stun_request); break; case EV_STUN_RESPONSE: ev_stun_response = dynamic_cast(event); handle_event_stun_response(ev_stun_response); break; case EV_ICMP: ev_icmp = dynamic_cast(event); handle_event_icmp(ev_icmp); break; case EV_FAILURE: ev_failure = dynamic_cast(event); handle_event_failure(ev_failure); break; case EV_QUIT: quit = true; break; default: assert(false); break; } MEMMAN_DELETE(event); delete event; } } // Main function to be started in a separate thread. void *transaction_mgr_main(void *arg) { transaction_mgr->run(); return NULL; } twinkle-1.4.2/src/user.h0000644000175000001440000007011211147075114012030 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // NOTE: // When adding attributes to t_user, make sure to add them to the // copy constructor too! #ifndef _H_USER #define _H_USER #include #include #include #include "protocol.h" #include "sys_settings.h" #include "audio/audio_codecs.h" #include "sockets/url.h" #include "threads/mutex.h" #include "boost/regex.hpp" // Forward declaration class t_request; // Default config file name #define USER_CONFIG_FILE "twinkle.cfg" #define USER_FILE_EXT ".cfg" #define USER_DIR DIR_USER #define USER_SCHEME "sip" #define PUBLIC_SIP_PORT(u) phone->get_public_port_sip(u) #define USER_HOST(u,local_ip) phone->get_ip_sip(u,(local_ip)) #define LOCAL_IP user_host #define LOCAL_HOSTNAME local_hostname #define SPECIAL_PHONE_SYMBOLS "-()/." using namespace std; enum t_hold_variant { HOLD_RFC2543, // set IP = 0.0.0.0 in c-line HOLD_RFC3264 // use direction attribute to put call on-hold }; /** SIP transport mode */ enum t_sip_transport { SIP_TRANS_UDP, /**< SIP over UDP */ SIP_TRANS_TCP, /**< SIP over TCP */ SIP_TRANS_AUTO /**< UDP for small messages, TCP for large messages */ }; enum t_ext_support { EXT_INVALID, EXT_DISABLED, EXT_SUPPORTED, EXT_PREFERRED, EXT_REQUIRED }; enum t_bit_rate_type { BIT_RATE_INVALID, BIT_RATE_CBR, // Constant BIT_RATE_VBR, // Variable BIT_RATE_ABR // Average }; enum t_dtmf_transport { DTMF_INBAND, DTMF_RFC2833, DTMF_AUTO, DTMF_INFO }; enum t_g726_packing { G726_PACK_RFC3551, G726_PACK_AAL2 }; struct t_number_conversion { boost::regex re; string fmt; string str(void) const { return re.str() + " --> " + fmt; } }; class t_user { private: string config_filename; // Mutex for exclusive access to the user profile mutable t_recursive_mutex mtx_user; /** @name USER */ //@{ // SIP user /** User name (public user identity). */ string name; /** Domain of the user. */ string domain; /** Display name. */ string display; /** * The organization will be put in an initial INVITE and in a * 200 OK on an INVITE. */ string organization; // SIP authentication /** Authentication realm. An empty realm matches with all realms. */ string auth_realm; /** Authentication name (private user identity). */ string auth_name; /** Authentication password (aka_k for akav1-md5 authentication) */ string auth_pass; /** Operator variant key for akav1-md5 authentication. */ uint8 auth_aka_op[AKA_OPLEN]; /** Authentication management field for akav1-md5 authentication. */ uint8 auth_aka_amf[AKA_AMFLEN]; //@} // SIP SERVER // Send all non-REGISTER requests to the outbound proxy bool use_outbound_proxy; t_url outbound_proxy; // By default only out-of-dialog requests (including the ones the // establish a dialog) are sent to the outbound proxy. // In-dialog requests go to the address established via the contact // header. // By setting this parameter to true, in-dialog requests go to the // outbound proxy as well. bool all_requests_to_proxy; // Only send the request to the proxy, if the destination cannot // be resolved to an IP address, adhearing to the previous setting // though. I.e. use_outbound_proxy must be true. And an in-dialog // request will only be sent to the proxy if all_requests_to_proxy // is true. bool non_resolvable_to_proxy; // Send REGISTER to registrar bool use_registrar; t_url registrar; // Registration time requested by the client. If set to zero, then // no specific time is requested. The registrar will set a time. unsigned long registration_time; // Automatically register at startup of the client. bool register_at_startup; // q-value for registration bool reg_add_qvalue; float reg_qvalue; // AUDIO list codecs; // in order of preference unsigned short ptime; // ptime (ms) for G.711/G.726 // For outgoing calls, obey the preference from the far-end (SDP answer), // i.e. pick the first codec from the SDP answer that we support. bool out_obey_far_end_codec_pref; // For incoming calls, obey the preference from the far-end (SDP offer), // i.e. pick the first codec from the SDP offer that we support. bool in_obey_far_end_codec_pref; // RTP dynamic payload types for speex unsigned short speex_nb_payload_type; unsigned short speex_wb_payload_type; unsigned short speex_uwb_payload_type; // Speex preprocessing options bool speex_dsp_vad; // voice activity reduction bool speex_dsp_agc; // automatic gain control bool speex_dsp_aec; // acoustic echo cancellation bool speex_dsp_nrd; // noise reduction unsigned short speex_dsp_agc_level; // gain level of AGC (1-100[%]) // Speex coding options t_bit_rate_type speex_bit_rate_type; int speex_abr_nb; int speex_abr_wb; bool speex_dtx; bool speex_penh; unsigned short speex_complexity; unsigned short speex_quality; // quality measure (worst 0-10 best) // RTP dynamic payload types for iLBC unsigned short ilbc_payload_type; // iLBC options unsigned short ilbc_mode; // 20 or 30 ms frame size // RTP dynamic payload types for G.726 unsigned short g726_16_payload_type; unsigned short g726_24_payload_type; unsigned short g726_32_payload_type; unsigned short g726_40_payload_type; // Bit packing order for G,726 t_g726_packing g726_packing; // Transport mode for DTMF t_dtmf_transport dtmf_transport; // RTP dynamic payload type for out-of-band DTMF. unsigned short dtmf_payload_type; // DTMF duration and pause between 2 tones. During the pause the last // DTMF event will be repeated so the far end can detect the end of // the event in case of packet loss. unsigned short dtmf_duration; // ms unsigned short dtmf_pause; // ms // Volume of the tone in -dBm unsigned short dtmf_volume; /** @name SIP PROTOCOL */ //@{ // SIP protocol options // hold variants: rfc2543, rfc3264 // rfc2543 - set IP address to 0.0.0.0 // rfc3264 - use direction attribute (sendrecv, sendonly, ...) t_hold_variant hold_variant; // Indicate if the mandatory Max-Forwards header should be present. // If true and the header is missing, then the request will fail. bool check_max_forwards; // RFC 3261 10.3 states that a registrar must include a contact // header in a 200 OK on a REGISTER. This contact should match the // contact that a UA puts in the REGISTER. Unfortunately many // registrars do not include the contact header or put a wrong // IP address in the host-part due to NAT. // This settings allows for a missing/non-matching contact header. // In that case Twinkle assumes that it is registered for the // requested interval. bool allow_missing_contact_reg; // Indicate the place of the requested registration time in a REGISTER. // true - expires parameter in contact header // false - Expires header bool registration_time_in_contact; // Indicate if compact header names should be used in outgoing messages. bool compact_headers; // Indicate if headers containing multiple values should be encoded // as a comma separated list or as multiple headers. bool encode_multi_values_as_list; // Indicate if a unique contact name should be created by using // the domain name: username_domain // If false then the SIP user name is used as contact name bool use_domain_in_contact; // Allow SDP to change in different INVITE responses. // According to RFC 3261 13.2.1, if SDP is received in a 1XX response, // then SDP received in subsequent responses should be ignored. // Some SIP proxies do send different SDP in 1XX and 200 though. // E.g. first SDP is to play ring tone, second SDP is to create // an end-to-end media path. bool allow_sdp_change; // Redirections // Allow redirection of a request when a 3XX is received. bool allow_redirection; // Ask user for permission to redirect a request when a 3XX is received. bool ask_user_to_redirect; // Maximum number of locations to be tried when a request is redirected. unsigned short max_redirections; // SIP extensions // 100rel extension (PRACK, RFC 3262) // Possible values: // - disabled 100rel extension is disabled // - supported 100rel is supported (it is added in the supported header of // an outgoing INVITE). A far-end can now require a PRACK on a // 1xx response. // - required 100rel is required (it is put in the require header of an // outgoing INVITE). // If an incoming INVITE indicates that it supports 100rel, then // Twinkle will require a PRACK when sending a 1xx response. // - preferred Similar to required, but if a call fails because the far-end // indicates it does not support 100rel (420 response) then the // call will be re-attempted without the 100rel requirement. t_ext_support ext_100rel; // Replaces (RFC 3891) bool ext_replaces; //@} /** @name REFER options */ //@{ /** Hold the current call when an incoming REFER is accepted. */ bool referee_hold; /** Hold the current call before sending a REFER. */ bool referrer_hold; /** Allow an incoming refer */ bool allow_refer; /** Ask user for permission when a REFER is received. */ bool ask_user_to_refer; /** Referrer automatically refreshes subscription before expiry. */ bool auto_refresh_refer_sub; /** * An attended transfer should use the contact-URI of the transfer target. * This contact-URI is not always globally routable however. As an * alternative the AoR (address of record) can be used. Disadvantage is * that the AoR may route to multiple phones in case of forking, whereas * the contact-URI routes to a particular phone. */ bool attended_refer_to_aor; /** * Allow to transfer a call while the consultation call is still * in progress. */ bool allow_transfer_consultation_inprog; //@} /** @name Privacy options */ //@{ // Send P-Preferred-Identity header in initial INVITE when hiding // user identity. bool send_p_preferred_id; //@} /** @name Transport */ //@{ /** SIP transport protocol */ t_sip_transport sip_transport; /** * Threshold to decide which transport to use in auto transport mode. * A message with a size up to this threshold is sent via UDP. Larger messages * are sent via TCP. */ unsigned short sip_transport_udp_threshold; //@} /** @name NAT */ //@{ /** * NAT traversal * You can set nat_public_ip to your public IP or FQDN if you are behind * a NAT. This will then be used inside the SIP messages instead of your * private IP. On your NAT you have to create static bindings for port 5060 * and ports 8000 - 8005 to the same ports on your private IP address. */ bool use_nat_public_ip; /** The public IP address of the NAT device. */ string nat_public_ip; /** NAT traversal via STUN. */ bool use_stun; /** URL of the STUN server. */ t_url stun_server; /** User persistent TCP connections. */ bool persistent_tcp; /** Enable sending of NAT keepalive packets for UDP. */ bool enable_nat_keepalive; //@} /** @name TIMERS */ //@{ /** * Noanswer timer is started when an initial INVITE is received. If * the user does not respond within the timer, then the call will be * released with a 480 Temporarily Unavailable response. */ unsigned short timer_noanswer; // seconds /** Duration of NAT keepalive timer (s) */ unsigned short timer_nat_keepalive; /** Duration of TCP ping timer (s) */ unsigned short timer_tcp_ping; //@} /** @name ADDRESS FORMAT */ //@{ /** * Telephone numbers * Display only the user-part of a URI if it is a telephone number * I.e. the user=phone parameter is present, or the user indicated * that the format of the user-part is a telephone number. * If the URI is a tel-URI then display the telephone number. */ bool display_useronly_phone; /** * Consider user-parts that consist of 0-9,+,-,*,# as a telephone * number. I.e. in outgoing messages the user=phone parameter will * be added to the URI. For incoming messages the URI will be considered * to be a telephone number regardless of the presence of the * user=phone parameter. */ bool numerical_user_is_phone; /** Remove special symbols from numerical dial strings */ bool remove_special_phone_symbols; /** Special symbols that must be removed from telephone numbers */ string special_phone_symbols; /** * If the user enters a telephone number as address, then complete it * to a tel-URI instead of a sip-URI. */ bool use_tel_uri_for_phone; /** Number conversion */ list number_conversions; //@} // RING TONES string ringtone_file; string ringback_file; // SCRIPTS // Script to be called on incoming call string script_incoming_call; string script_in_call_answered; string script_in_call_failed; string script_outgoing_call; string script_out_call_answered; string script_out_call_failed; string script_local_release; string script_remote_release; // SECURITY // zrtp setting bool zrtp_enabled; // Popup warning when far-end sends goclear command bool zrtp_goclear_warning; // Send a=zrtp in SDP bool zrtp_sdp; // Only negotiate zrtp if far-end signalled support for zrtp bool zrtp_send_if_supported; // MWI // Indicate if MWI is sollicited or unsollicited. // RFC 3842 specifies that MWI must be sollicited (SUBSCRIBE). // Asterisk however only supported non-standard unsollicited MWI. bool mwi_sollicited; // User name for subscribing to the mailbox string mwi_user; // The mailbox server to which the SUBSCRIBE must be sent t_url mwi_server; // Send the SUBSCRIBE via the proxy to the mailbox server bool mwi_via_proxy; // Requested MWI subscription duration unsigned long mwi_subscription_time; // The voice mail address to call to access messages string mwi_vm_address; /** @name INSTANT MESSAGE */ //@{ /** Maximum number of simultaneous IM sessions. */ unsigned short im_max_sessions; /** Flag to indicate that IM is-composing indications (RFC 3994) should be sent. */ bool im_send_iscomposing; //@} /** @name PRESENCE */ //@{ /** Requested presence subscription duration in seconds. */ unsigned long pres_subscription_time; /** Requested presence publication duration in seconds. */ unsigned long pres_publication_time; /** Publish online presence state at startup */ bool pres_publish_startup; //@} t_ext_support str2ext_support(const string &s) const; string ext_support2str(t_ext_support e) const; t_bit_rate_type str2bit_rate_type(const string &s) const; string bit_rate_type2str(t_bit_rate_type b) const; t_dtmf_transport str2dtmf_transport(const string &s) const; string dtmf_transport2str(t_dtmf_transport d) const; t_g726_packing str2g726_packing(const string &s) const; string g726_packing2str(t_g726_packing packing) const; t_sip_transport str2sip_transport(const string &s) const; string sip_transport2str(t_sip_transport transport) const; // Parse a number conversion rule // If the rule can be parsed, then c contains the conversion rule and // true is returned. Otherwise false is returned. bool parse_num_conversion(const string &value, t_number_conversion &c); // Set a server URL. // Returns false, if the passed value is not a valid URL. bool set_server_value(t_url &server, const string &scheme, const string &value); public: t_user(); t_user(const t_user &u); t_user *copy(void) const; /** @name Getters */ //@{ string get_name(void) const; string get_domain(void) const; string get_display(bool anonymous) const; string get_organization(void) const; string get_auth_realm(void) const; string get_auth_name(void) const; string get_auth_pass(void) const; void get_auth_aka_op(uint8 *aka_op) const; void get_auth_aka_amf(uint8 *aka_amf) const; bool get_use_outbound_proxy(void) const; t_url get_outbound_proxy(void) const; bool get_all_requests_to_proxy(void) const; bool get_non_resolvable_to_proxy(void) const; bool get_use_registrar(void) const; t_url get_registrar(void) const; unsigned long get_registration_time(void) const; bool get_register_at_startup(void) const; bool get_reg_add_qvalue(void) const; float get_reg_qvalue(void) const; list get_codecs(void) const; unsigned short get_ptime(void) const; bool get_out_obey_far_end_codec_pref(void) const; bool get_in_obey_far_end_codec_pref(void) const; unsigned short get_speex_nb_payload_type(void) const; unsigned short get_speex_wb_payload_type(void) const; unsigned short get_speex_uwb_payload_type(void) const; t_bit_rate_type get_speex_bit_rate_type(void) const; int get_speex_abr_nb(void) const; int get_speex_abr_wb(void) const; bool get_speex_dtx(void) const; bool get_speex_penh(void) const; unsigned short get_speex_quality(void) const; unsigned short get_speex_complexity(void) const; bool get_speex_dsp_vad(void) const; bool get_speex_dsp_agc(void) const; bool get_speex_dsp_aec(void) const; bool get_speex_dsp_nrd(void) const; unsigned short get_speex_dsp_agc_level(void) const; unsigned short get_ilbc_payload_type(void) const; unsigned short get_ilbc_mode(void) const; unsigned short get_g726_16_payload_type(void) const; unsigned short get_g726_24_payload_type(void) const; unsigned short get_g726_32_payload_type(void) const; unsigned short get_g726_40_payload_type(void) const; t_g726_packing get_g726_packing(void) const; t_dtmf_transport get_dtmf_transport(void) const; unsigned short get_dtmf_payload_type(void) const; unsigned short get_dtmf_duration(void) const; unsigned short get_dtmf_pause(void) const; unsigned short get_dtmf_volume(void) const; t_hold_variant get_hold_variant(void) const; bool get_check_max_forwards(void) const; bool get_allow_missing_contact_reg(void) const; bool get_registration_time_in_contact(void) const; bool get_compact_headers(void) const; bool get_encode_multi_values_as_list(void) const; bool get_use_domain_in_contact(void) const; bool get_allow_sdp_change(void) const; bool get_allow_redirection(void) const; bool get_ask_user_to_redirect(void) const; unsigned short get_max_redirections(void) const; t_ext_support get_ext_100rel(void) const; bool get_ext_replaces(void) const; bool get_referee_hold(void) const; bool get_referrer_hold(void) const; bool get_allow_refer(void) const; bool get_ask_user_to_refer(void) const; bool get_auto_refresh_refer_sub(void) const; bool get_attended_refer_to_aor(void) const; bool get_allow_transfer_consultation_inprog(void) const; bool get_send_p_preferred_id(void) const; t_sip_transport get_sip_transport(void) const; unsigned short get_sip_transport_udp_threshold(void) const; bool get_use_nat_public_ip(void) const; string get_nat_public_ip(void) const; bool get_use_stun(void) const; t_url get_stun_server(void) const; bool get_persistent_tcp(void) const; bool get_enable_nat_keepalive(void) const; unsigned short get_timer_noanswer(void) const; unsigned short get_timer_nat_keepalive(void) const; unsigned short get_timer_tcp_ping(void) const; bool get_display_useronly_phone(void) const; bool get_numerical_user_is_phone(void) const; bool get_remove_special_phone_symbols(void) const; string get_special_phone_symbols(void) const; bool get_use_tel_uri_for_phone(void) const; string get_ringtone_file(void) const; string get_ringback_file(void) const; string get_script_incoming_call(void) const; string get_script_in_call_answered(void) const; string get_script_in_call_failed(void) const; string get_script_outgoing_call(void) const; string get_script_out_call_answered(void) const; string get_script_out_call_failed(void) const; string get_script_local_release(void) const; string get_script_remote_release(void) const; list get_number_conversions(void) const; bool get_zrtp_enabled(void) const; bool get_zrtp_goclear_warning(void) const; bool get_zrtp_sdp(void) const; bool get_zrtp_send_if_supported(void) const; bool get_mwi_sollicited(void) const; string get_mwi_user(void) const; t_url get_mwi_server(void) const; bool get_mwi_via_proxy(void) const; unsigned long get_mwi_subscription_time(void) const; string get_mwi_vm_address(void) const; unsigned short get_im_max_sessions(void) const; bool get_im_send_iscomposing(void) const; unsigned long get_pres_subscription_time(void) const; unsigned long get_pres_publication_time(void) const; bool get_pres_publish_startup(void) const; //@} /** @name Setters */ //@{ void set_name(const string &_name); void set_domain(const string &_domain); void set_display(const string &_display); void set_organization(const string &_organization); void set_auth_realm(const string &realm); void set_auth_name(const string &name); void set_auth_pass(const string &pass); void set_auth_aka_op(const uint8 *aka_op); void set_auth_aka_amf(const uint8 *aka_amf); void set_use_outbound_proxy(bool b); void set_outbound_proxy(const t_url &url); void set_all_requests_to_proxy(bool b); void set_non_resolvable_to_proxy(bool b); void set_use_registrar(bool b); void set_registrar(const t_url &url); void set_registration_time(const unsigned long time); void set_register_at_startup(bool b); void set_reg_add_qvalue(bool b); void set_reg_qvalue(float q); void set_codecs(const list &_codecs); void set_ptime(unsigned short _ptime); void set_out_obey_far_end_codec_pref(bool b); void set_in_obey_far_end_codec_pref(bool b); void set_speex_nb_payload_type(unsigned short payload_type); void set_speex_wb_payload_type(unsigned short payload_type); void set_speex_uwb_payload_type(unsigned short payload_type); void set_speex_bit_rate_type(t_bit_rate_type bit_rate_type); void set_speex_abr_nb(int abr); void set_speex_abr_wb(int abr); void set_speex_dtx(bool b); void set_speex_penh(bool b); void set_speex_quality(unsigned short quality); void set_speex_complexity(unsigned short complexity); void set_speex_dsp_vad(bool b); void set_speex_dsp_agc(bool b); void set_speex_dsp_aec(bool b); void set_speex_dsp_nrd(bool b); void set_speex_dsp_agc_level(unsigned short level); void set_ilbc_payload_type(unsigned short payload_type); void set_g726_16_payload_type(unsigned short payload_type); void set_g726_24_payload_type(unsigned short payload_type); void set_g726_32_payload_type(unsigned short payload_type); void set_g726_40_payload_type(unsigned short payload_type); void set_g726_packing(t_g726_packing packing); void set_ilbc_mode(unsigned short mode); void set_dtmf_transport(t_dtmf_transport _dtmf_transport); void set_dtmf_payload_type(unsigned short payload_type); void set_dtmf_duration(unsigned short duration); void set_dtmf_pause(unsigned short pause); void set_dtmf_volume(unsigned short volume); void set_hold_variant(t_hold_variant _hold_variant); void set_check_max_forwards(bool b); void set_allow_missing_contact_reg(bool b); void set_registration_time_in_contact(bool b); void set_compact_headers(bool b); void set_encode_multi_values_as_list(bool b); void set_use_domain_in_contact(bool b); void set_allow_sdp_change(bool b); void set_allow_redirection(bool b); void set_ask_user_to_redirect(bool b); void set_max_redirections(unsigned short _max_redirections); void set_ext_100rel(t_ext_support ext_support); void set_ext_replaces(bool b); void set_referee_hold(bool b); void set_referrer_hold(bool b); void set_allow_refer(bool b); void set_ask_user_to_refer(bool b); void set_auto_refresh_refer_sub(bool b); void set_attended_refer_to_aor(bool b); void set_allow_transfer_consultation_inprog(bool b); void set_send_p_preferred_id(bool b); void set_sip_transport(t_sip_transport transport); void set_sip_transport_udp_threshold(unsigned short threshold); void set_use_nat_public_ip(bool b); void set_nat_public_ip(const string &public_ip); void set_use_stun(bool b); void set_stun_server(const t_url &url); void set_persistent_tcp(bool b); void set_enable_nat_keepalive(bool b); void set_timer_noanswer(unsigned short timer); void set_timer_nat_keepalive(unsigned short timer); void set_timer_tcp_ping(unsigned short timer); void set_display_useronly_phone(bool b); void set_numerical_user_is_phone(bool b); void set_remove_special_phone_symbols(bool b); void set_special_phone_symbols(const string &symbols); void set_use_tel_uri_for_phone(bool b); void set_ringtone_file(const string &file); void set_ringback_file(const string &file); void set_script_incoming_call(const string &script); void set_script_in_call_answered(const string &script); void set_script_in_call_failed(const string &script); void set_script_outgoing_call(const string &script); void set_script_out_call_answered(const string &script); void set_script_out_call_failed(const string &script); void set_script_local_release(const string &script); void set_script_remote_release(const string &script); void set_number_conversions(const list &l); void set_zrtp_enabled(bool b); void set_zrtp_goclear_warning(bool b); void set_zrtp_sdp(bool b); void set_zrtp_send_if_supported(bool b); void set_mwi_sollicited(bool b); void set_mwi_user(const string &user); void set_mwi_server(const t_url &url); void set_mwi_via_proxy(bool b); void set_mwi_subscription_time(unsigned long t); void set_mwi_vm_address(const string &address); void set_im_max_sessions(unsigned short max_sessions); void set_im_send_iscomposing(bool b); void set_pres_subscription_time(unsigned long t); void set_pres_publication_time(unsigned long t); void set_pres_publish_startup(bool b); //@} // Read and parse a config file into the user object. // Returns false if it fails. error_msg is an error message that can // be given to the user. bool read_config(const string &filename, string &error_msg); /** * Write the settings into a config file. * @param filename [in] Name of the file to write. * @param error_msg [out] Human readable error message when writing fails. * @return Returns true of writing succeeded, otherwise false. */ bool write_config(const string &filename, string &error_msg); /** Get the file name for this user profile */ string get_filename(void) const; /** * Set a config file name. * @return True if file name did not yet exist. * @return False if file name already exists. */ bool set_config(string _filename); // Get the name of the profile (filename without extension) string get_profile_name(void) const; // Expand file name to a fully qualified file name string expand_filename(const string &filename); // The contact name is created from the name and domain values. // Just the name value is not unique when multiple user profiles are // activated. string get_contact_name(void) const; // Returns "display " string get_display_uri(void) const; // Check if all required extensions are supported bool check_required_ext(t_request *r, list &unsupported) const; /** * Create contact URI. * @param anonymous [in] Indicates if an anonymous contact should be created. * @param auto_ip [in] Automatically determined local IP address that should be * used if not IP address has been determined through other means. * @return String representation of the contact URI. */ string create_user_contact(bool anonymous, const string &auto_ip); // Create user uri string create_user_uri(bool anonymous); // Convert a number by applying the number conversions. string convert_number(const string &number, const list &l) const; string convert_number(const string &number) const; // Get URI for sending a SUBSCRIBE for MWI t_url get_mwi_uri(void) const; /** Is this a user profile for a Diamondcard account? */ bool is_diamondcard_account(void) const; }; #endif twinkle-1.4.2/src/util.h0000644000175000001440000002074611134642141012033 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _UTIL_H #define _UTIL_H /** * @file * Utility functions */ #include #include #include using namespace std; string random_token(int length); string random_hexstr(int length); /** * Convert a float to a string. * @param f [in] Float to convert. * @param precision [in] Number of digits after the decimal point in output. * @return String representation of the float. */ string float2str(float f, int precision); // Convert an int to a string. format is a printf format string int2str(int i, const char *format); string int2str(int i); // Convert a ulong to a string. format is a printf format string ulong2str(unsigned long i, const char *format); string ulong2str(unsigned long i); // Convert a pointer to a string (hexadecimal) string ptr2str(void *p); // Convert a bool to a string: "false", "true" string bool2str(bool b); // Convert time/date to string // The format parameter is a strftime() format string string time2str(time_t t, const char *format); string current_time2str(const char *format); string weekday2str(int wkday); string month2str(int month); // Convert a full month name to an int (0-11) int str2month_full(const string &month); // Convert a duration in seconds to a string with hours, minutes seconds. // The hours and minutes are only present if there is at least 1 hour/minute. // E.g. 65s -> "1m 5s" // 3601s -> "1h 0m 1s" string duration2str(unsigned long seconds); // Convert a timer in seconds to a string (h:mm:ss) string timer2str(unsigned long seconds); /** * Convert a hex string to an integer. * @param h [in] A hex string. * @return The integer. */ unsigned long hex2int(const string &h); /** * Convert a hex string to a binary blob representing the hex value. * @param h [in] A hex string. * @param buf [in] A pointer to a buffer to store the binary blob. * @pre The buffer must be large enough to contain the binary blob. * @post buf contains the binary representation of the hex string. */ void hex2binary(const string &h, uint8 *buf); /** * Convert a binary blob to a hexadecimal string. * @param buf [in] Pointer to the binary blob. * @param len [in] Length of the blob. * @return The hexadecimal string. */ string binary2hex(uint8 *buf, unsigned long len); // Convert a string to lower case string tolower(const string &s); // Convert a string to upper case string toupper(const string &s); // Trim a string string rtrim(const string &s); string ltrim(const string &s); string trim(const string &s); /** * Pad a string on the left side till a certain length. * @param s [in] The string to pad. * @param c [in] The pad character. * @param len [in] The length to which the string must be padded. * @return The padded string. */ string padleft(const string &s, char c, unsigned long len); // Compare 2 strings case insensive, return // -1 --> s1 < s2 // 0 --> s1 == s2 // 1 --> s1 > s2 int cmp_nocase(const string &s1, const string &s2); // Return true if a string must be quoted in text encoding bool must_quote(const string &s); // Escape character c in string by prepending it with a backslash. // Backslashed are automatically escaped as well string escape(const string &s, char c); // Unescape a string string unescape(const string &s); // Escape reserved chars in s by there hex-notation (%HEX) // All chars that are not in unreserved are considered as reserved. string escape_hex(const string &s, const string &unreserved); // Unescape the hex-values in a string string unescape_hex(const string &s); // Replace all occurrences of 'from' char 'to' char in s string replace_char(const string &s, char from, char to); // Replace first occurrence of 'from'-string to 'to'-string in s string replace_first(const string &s, const string &from, const string &to); /** * Split a string into elements using a single character as separator. * @param s [in] The string to split. * @param c [in] The character separator. * @return Vector containing the split parts. */ vector split(const string &s, char c); /** * Split a string into elements using a string separator. * @param s [in] The string to split. * @param separator [in] The string separator. * @return Vector containing the split parts. */ vector split(const string &s, const string &separator); /** * Split a string into elements using line breaks as seperator * If the string contains a CRLF, then CRLF is used as line break. * Otherwise if the string contains a CR, then CR is used as line break. * Otherwise LF is used as line break. * @param s [in] The string to split. * @return Vector containing the split parts. */ vector split_linebreak(const string &s); /** * Split a string in two on the first occurrence of a separator. * @param s [in] The string to split. * @param c [in] The separator. * @return Vector containing the split parts. */ vector split_on_first(const string &s, char c); /** * Split a string in two on the last occurrence of a separator. * @param s [in] The string to split. * @param c [in] The separator. * @return Vector containing the split parts. */ vector split_on_last(const string &s, char c); // Split an escaped string into elements using c as a separator // Escaped means: \c will not be seen as a seperator and backslash is // escaped itself (\\) vector split_escaped(const string &s, char c); // Split a string into elements using spaces as separator // If quote_sensitive = true, then spaces within quoted strings will // not be used to split the string. vector split_ws(const string &s, bool quote_sensitive = false); /** * Join a vector of strings into one string. * @param v Vector of strings. * @param separator String to be inserted between the strings to join. * @return A string containing the concatenarion of all strings in v. * The invidual strings are separated by separator. */ string join_strings(const vector &v, const string &separator); // Remove surrounding quotes of a string if present. string unquote(const string &s); // Check if a string is a number bool is_number(const string &s); // Check if a string is an IP address bool is_ipaddr(const string &s); // Conversion between yes/no values and bool bool yesno2bool(const string &yesno); string bool2yesno(bool b); // Convert a text string to DTMF digits // Characters that cannot be converted will be removed string str2dtmf(const string &s); // Return true if string s looks like a phone number // A string looks like a phone number if it consists of digits, // *, #, special symbols and white space bool looks_like_phone(const string &s, const string &special_symbols); /** * Remove all special symbols from a string. * @param s [in] The string to convert. * @param special_symbols [in] The special symbols to remove. * @return The string without the special symbols. */ string remove_symbols(const string &s, const string &special_symbols); /** * Remove spaces and tabs from a string. * @param s [in] The string to convert. * @return The string without spaces and tabs. */ string remove_white_space(const string &s); /** * Truncate a string. If the string was longer than the truncated * result, then "..." will be appended. * @param s [in] The string to truncate. * @param len [in] The length in bytes to truncate to. * @return The truncated string. */ string dotted_truncate(const string &s, string::size_type len); /** * Convert a string to a printable representation, i.e. change * all non-printable chars into dots. * @param s [in] The string to convert. * @return The converted string. */ string to_printable(const string &s); /** * Get the error message describing an error number. * @param errnum [in] The error number. * @return The error message. */ string get_error_str(int errnum); #endif twinkle-1.4.2/src/cmd_socket.cpp0000644000175000001440000001240511127714057013525 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "cmd_socket.h" #include "log.h" #include "sys_settings.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" #include "sockets/socket.h" namespace cmdsocket { /** Command opcodes */ enum t_cmd_code { CMD_CALL, /**< Call */ CMD_CLI, /**< Any CLI command */ CMD_SHOW, /**< Show Twinkle */ CMD_HIDE /**< Hide Twinkle */ }; string cmd_code2str(t_cmd_code opcode) { switch (opcode) { case CMD_CALL: return "CALL"; case CMD_CLI: return "CLI"; case CMD_SHOW: return "SHOW"; case CMD_HIDE: return "HIDE"; default: return "UNKNOWN"; } } void exec_cmd(t_socket_local &sock_client) { t_cmd_code opcode; bool immediate; int len; string log_msg; try { if (sock_client.read(&opcode, sizeof(opcode)) != sizeof(opcode)) { log_file->write_report("Failed to read opcode from socket.", "cmdsocket::exec_cmd", LOG_NORMAL, LOG_WARNING); return; } if (sock_client.read(&immediate, sizeof(immediate)) != sizeof(immediate)) { log_file->write_report("Failed to read immediate mode from socket.", "cmdsocket::exec_cmd", LOG_NORMAL, LOG_WARNING); return; } if (sock_client.read(&len, sizeof(len)) != sizeof(len)) { log_file->write_report("Failed to read length from socket.", "cmdsocket::exec_cmd", LOG_NORMAL, LOG_WARNING); return; } char args[len]; if (sock_client.read(args, len) != len) { log_file->write_report("Failed to read arguments from socket.", "cmdsocket::exec_cmd", LOG_NORMAL, LOG_WARNING); return; } log_file->write_header("cmdsocket::exec_cmd", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("External command received:\n"); log_file->write_raw("Opcode: "); log_file->write_raw(cmd_code2str(opcode)); log_file->write_raw("\nImmediate: "); log_file->write_raw(bool2yesno(immediate)); log_file->write_raw("\nArguments: "); log_file->write_raw(args); log_file->write_endl(); log_file->write_footer(); switch (opcode) { case CMD_CALL: ui->cmd_call(args, immediate); break; case CMD_CLI: ui->cmd_cli(args, immediate); break; case CMD_SHOW: ui->cmd_show(); break; case CMD_HIDE: ui->cmd_hide(); break; default: // Discard unknown commands log_file->write_header("cmdsocket::exec_cmd", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unknown external command received:\n"); log_file->write_raw("Opcode: "); log_file->write_raw(cmd_code2str(opcode)); log_file->write_raw("\nImmediate: "); log_file->write_raw(bool2yesno(immediate)); log_file->write_raw("\nArguments: "); log_file->write_raw(args); log_file->write_endl(); log_file->write_footer(); break; } } catch (int e) { log_msg = "Failed to read from socket.\n"; log_msg += get_error_str(e); log_msg += "\n"; log_file->write_report(log_msg, "cmdsocket::exec_cmd", LOG_NORMAL, LOG_WARNING); } } void *listen_cmd(void *arg) { t_socket_local *sock_cmd = (t_socket_local *)arg; string log_msg; while (true) { try { int fd = sock_cmd->accept(); t_socket_local sock_client(fd); exec_cmd(sock_client); } catch (int e) { log_msg = "Accept failed on socket.\n"; log_msg += get_error_str(e); log_msg += "\n"; log_file->write_report(log_msg, "cmdsocket::listen_cmd", LOG_NORMAL, LOG_WARNING); return NULL; } } } void write_cmd_to_socket(t_cmd_code opcode, bool immediate, const string &args) { string name = sys_config->get_dir_user(); name += '/'; name += CMD_SOCKNAME; try { t_socket_local sock_cmd; sock_cmd.connect(name); sock_cmd.write(&opcode, sizeof(opcode)); sock_cmd.write(&immediate, sizeof(immediate)); int len = args.size() + 1; sock_cmd.write(&len, sizeof(len)); char *buf = strdup(args.c_str()); MEMMAN_NEW(buf); sock_cmd.write(buf, len); MEMMAN_DELETE(buf); free(buf); } catch (int e) { // This function will be called from Twinkle when it // notices another Twinkle is already running. In that // case this process does not have a log file. So write // errors to stderr cerr << "Failed to send " << cmd_code2str(opcode) << " command to " << name << endl; cerr << get_error_str(e) << endl; } } void cmd_call(const string &destination, bool immediate) { write_cmd_to_socket(CMD_CALL, immediate, destination); } void cmd_cli(const string &cli_command, bool immediate) { write_cmd_to_socket(CMD_CLI, immediate, cli_command); } void cmd_show(void) { write_cmd_to_socket(CMD_SHOW, true, ""); } void cmd_hide(void) { write_cmd_to_socket(CMD_HIDE, true, ""); } } twinkle-1.4.2/src/abstract_dialog.cpp0000644000175000001440000002174311127714057014541 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "abstract_dialog.h" #include "log.h" #include "phone.h" #include "phone_user.h" #include "util.h" #include "userintf.h" #include "audits/memman.h" extern string user_host; extern t_phone *phone; // Private void t_abstract_dialog::remove_client_request(t_client_request **cr) { if ((*cr)->dec_ref_count() == 0) { MEMMAN_DELETE(*cr); delete *cr; } *cr = NULL; } // Create a request within a dialog // RFC 3261 12.2.1.1 t_request *t_abstract_dialog::create_request(t_method m) { t_user *user_config = phone_user->get_user_profile(); t_request *r = new t_request(m); MEMMAN_NEW(r); // To header r->hdr_to.set_uri(remote_uri); r->hdr_to.set_display(remote_display); r->hdr_to.set_tag(remote_tag); // From header r->hdr_from.set_uri(local_uri); r->hdr_from.set_display(local_display); r->hdr_from.set_tag(local_tag); // Call-ID header r->hdr_call_id.set_call_id(call_id); // CSeq header r->hdr_cseq.set_method(m); r->hdr_cseq.set_seqnr(++local_seqnr); // Set Max-Forwards header r->hdr_max_forwards.set_max_forwards(MAX_FORWARDS); // User-Agent SET_HDR_USER_AGENT(r->hdr_user_agent); // RFC 3261 12.2.1.1 // Request URI and Route header r->set_route(remote_target_uri, route_set); // Caculate destination set. A DNS request can result in multiple // IP address. In failover scenario's the request must be sent to // the next IP address in the list. As the request will be copied // in various places, the destination set must be calculated now. // In previous version the DNS request was done by the transaction // manager. This is too late as the transaction manager gets a copy // of the request. The destination set should be set in the copy // kept by the dialog. r->calc_destinations(*user_config); // The Via header can only be created after the destinations // are calculated, because the destination deterimines which // local IP address should be used. // Via header unsigned long local_ip = r->get_local_ip(); t_via via(USER_HOST(user_config, h_ip2str(local_ip)), PUBLIC_SIP_PORT(user_config)); r->hdr_via.add_via(via); return r; } void t_abstract_dialog::create_route_set(t_response *r) { // Originally the check was this: // if (route_set.empty() && r->hdr_record_route.is_populated()) // This prevented the route set from being altered between a 18X response // and a 2XX response. This is allowed per RFC 3261 13.2.2.4 if (r->hdr_record_route.is_populated()) { route_set = r->hdr_record_route.route_list; route_set.reverse(); } else { route_set.clear(); } } void t_abstract_dialog::create_remote_target(t_response *r) { if (r->hdr_contact.is_populated()) { remote_target_uri = r->hdr_contact.contact_list.front().uri; remote_target_display = r->hdr_contact.contact_list.front().display; } } void t_abstract_dialog::resend_request(t_client_request *cr) { t_user *user_config = phone_user->get_user_profile(); t_request *req = cr->get_request(); // A new sequence number must be assigned req->hdr_cseq.set_seqnr(++local_seqnr); // Create a new via-header. Otherwise the // request will be seen as a retransmission unsigned long local_ip = req->get_local_ip(); req->hdr_via.via_list.clear(); t_via via(USER_HOST(user_config, h_ip2str(local_ip)), PUBLIC_SIP_PORT(user_config)); req->hdr_via.add_via(via); cr->renew(0); send_request(req, cr->get_tuid()); } bool t_abstract_dialog::resend_request_auth(t_client_request *cr, t_response *resp) { t_user *user_config = phone_user->get_user_profile(); t_request *req = cr->get_request(); // Add authorization header, increment CSeq and create new branch id if (phone->authorize(user_config, req, resp)) { resend_request(cr); return true; } return false; } bool t_abstract_dialog::redirect_request(t_client_request *cr, t_response *resp, t_contact_param &contact) { t_user *user_config = phone_user->get_user_profile(); // If the response is a 3XX response then add redirection contacts if (resp->get_class() == R_3XX && resp->hdr_contact.is_populated()) { cr->redirector.add_contacts( resp->hdr_contact.contact_list); } // Get next destination if (!cr->redirector.get_next_contact(contact)) { // There is no next destination return false; } t_request *req = cr->get_request(); // Ask user for permission to redirect if indicated by user config if (user_config->get_ask_user_to_redirect()) { if(!ui->cb_ask_user_to_redirect_request(user_config, contact.uri, contact.display, resp->hdr_cseq.method)) { // User did not permit to redirect return false; } } // Change the request URI to the new URI. // As the URI changes the destination set must be recalculated req->uri = contact.uri; req->calc_destinations(*user_config); resend_request(cr); return true; } bool t_abstract_dialog::failover_request(t_client_request *cr) { log_file->write_report("Failover to next destination.", "t_abstract_dialog::failover_request"); t_request *req = cr->get_request(); // Get next destination if (!req->next_destination()) { log_file->write_report("No next destination for failover.", "t_abstract_dialog::failover_request"); return false; } resend_request(cr); return true; } //////////// // Public //////////// t_abstract_dialog::t_abstract_dialog(t_phone_user *pu) : t_id_object() { assert(pu); phone_user = pu; call_id_owner = false; local_seqnr = 0; remote_seqnr = 0; remote_seqnr_set = false; local_resp_nr = 0; remote_resp_nr = 0; remote_ip_port.clear(); log_file->write_header("t_abstract_dialog::t_abstract_dialog", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Created dialog, id="); log_file->write_raw(get_object_id()); log_file->write_endl(); log_file->write_footer(); } t_abstract_dialog::~t_abstract_dialog() { log_file->write_header("t_abstract_dialog::~t_abstract_dialog", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Destroy dialog, id="); log_file->write_raw(get_object_id()); log_file->write_endl(); log_file->write_footer(); } t_user *t_abstract_dialog::get_user(void) const { return phone_user->get_user_profile(); } void t_abstract_dialog::recvd_response(t_response *r, t_tuid tuid, t_tid tid) { // The source address and port of a message may be 0 when the // message was sent internally. if (!r->src_ip_port.is_null()) { remote_ip_port = r->src_ip_port; } } void t_abstract_dialog::recvd_request(t_request *r, t_tuid tuid, t_tid tid) { // The source address and port of a message may be 0 when the // message was sent internally. if (!r->src_ip_port.is_null()) { remote_ip_port = r->src_ip_port; } } bool t_abstract_dialog::match_response(t_response *r, t_tuid tuid) { return (call_id == r->hdr_call_id.call_id && local_tag == r->hdr_from.tag && (remote_tag.size() == 0 || remote_tag == r->hdr_to.tag)); } bool t_abstract_dialog::match_request(t_request *r) { return match(r->hdr_call_id.call_id, r->hdr_to.tag, r->hdr_from.tag); } bool t_abstract_dialog::match_partial_request(t_request *r) { return (r->hdr_call_id.call_id == call_id && r->hdr_to.tag == local_tag); } bool t_abstract_dialog::match(const string &_call_id, const string &to_tag, const string &from_tag) const { return (call_id == _call_id && local_tag == to_tag && remote_tag == from_tag); } t_url t_abstract_dialog::get_remote_target_uri(void) const { return remote_target_uri; } string t_abstract_dialog::get_remote_target_display(void) const { return remote_target_display; } t_url t_abstract_dialog::get_remote_uri(void) const { return remote_uri; } string t_abstract_dialog::get_remote_display(void) const { return remote_display; } t_ip_port t_abstract_dialog::get_remote_ip_port(void) const { return remote_ip_port; } string t_abstract_dialog::get_call_id(void) const { return call_id; } string t_abstract_dialog::get_local_tag(void) const { return local_tag; } string t_abstract_dialog::get_remote_tag(void) const { return remote_tag; } bool t_abstract_dialog::remote_extension_supported(const string &extension) const { return (remote_extensions.find(extension) != remote_extensions.end()); } bool t_abstract_dialog::is_call_id_owner(void) const { return call_id_owner; } twinkle-1.4.2/src/session.cpp0000644000175000001440000005757211134700777013115 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "line.h" #include "log.h" #include "phone.h" #include "phone_user.h" #include "session.h" #include "util.h" #include "userintf.h" #include "audits/memman.h" extern string user_host; extern string local_hostname; extern t_phone *phone; /////////// // PRIVATE /////////// void t_session::set_recvd_codecs(t_sdp *sdp) { recvd_codecs.clear(); send_ac2payload.clear(); send_payload2ac.clear(); list payloads = sdp->get_codecs(SDP_AUDIO); for (list::iterator i = payloads.begin(); i != payloads.end(); i++) { t_audio_codec ac = sdp->get_codec(SDP_AUDIO, *i); if (ac > CODEC_UNSUPPORTED) { recvd_codecs.push_back(ac); send_ac2payload[ac] = *i; send_payload2ac[*i] = ac; } } } bool t_session::is_3way(void) const { t_line *l = get_line(); t_phone *p = l->get_phone(); return p->part_of_3way(l->get_line_number()); } t_session *t_session::get_peer_3way(void) const { t_line *l = get_line(); t_phone *p = l->get_phone(); t_line *peer_line = p->get_3way_peer_line(l->get_line_number()); return peer_line->get_session(); } /////////// // PUBLIC /////////// t_session::t_session(t_dialog *_dialog, string _receive_host, unsigned short _receive_port) { dialog = _dialog; user_config = dialog->get_line()->get_user(); assert(user_config); receive_host = _receive_host; retrieve_host = _receive_host; receive_port = _receive_port; src_sdp_version = int2str(rand()); src_sdp_id = int2str(rand()); use_codec = CODEC_NULL; switch (user_config->get_dtmf_transport()) { case DTMF_RFC2833: case DTMF_AUTO: recv_dtmf_pt = user_config->get_dtmf_payload_type(); break; default: recv_dtmf_pt = 0; } send_dtmf_pt = 0; offer_codecs = user_config->get_codecs(); ptime = user_config->get_ptime(); ilbc_mode = user_config->get_ilbc_mode(); recvd_offer = false; recvd_answer = false; sent_offer = false; direction = SDP_SENDRECV; audio_rtp_session = NULL; is_on_hold = false; is_killed = false; // Initialize audio codec to payload mappings recv_ac2payload[CODEC_G711_ULAW] = SDP_FORMAT_G711_ULAW; recv_ac2payload[CODEC_G711_ALAW] = SDP_FORMAT_G711_ALAW; recv_ac2payload[CODEC_GSM] = SDP_FORMAT_GSM; recv_ac2payload[CODEC_SPEEX_NB] = user_config->get_speex_nb_payload_type(); recv_ac2payload[CODEC_SPEEX_WB] = user_config->get_speex_wb_payload_type(); recv_ac2payload[CODEC_SPEEX_UWB] = user_config->get_speex_uwb_payload_type(); recv_ac2payload[CODEC_ILBC] = user_config->get_ilbc_payload_type(); recv_ac2payload[CODEC_G726_16] = user_config->get_g726_16_payload_type(); recv_ac2payload[CODEC_G726_24] = user_config->get_g726_24_payload_type(); recv_ac2payload[CODEC_G726_32] = user_config->get_g726_32_payload_type(); recv_ac2payload[CODEC_G726_40] = user_config->get_g726_40_payload_type(); recv_ac2payload[CODEC_TELEPHONE_EVENT] = user_config->get_dtmf_payload_type(); send_ac2payload.clear(); // Initialize pauload to audio codec mappings recv_payload2ac[SDP_FORMAT_G711_ULAW] = CODEC_G711_ULAW; recv_payload2ac[SDP_FORMAT_G711_ALAW] = CODEC_G711_ALAW; recv_payload2ac[SDP_FORMAT_GSM] = CODEC_GSM; recv_payload2ac[user_config->get_speex_nb_payload_type()] = CODEC_SPEEX_NB; recv_payload2ac[user_config->get_speex_wb_payload_type()] = CODEC_SPEEX_WB; recv_payload2ac[user_config->get_speex_uwb_payload_type()] = CODEC_SPEEX_UWB; recv_payload2ac[user_config->get_ilbc_payload_type()] = CODEC_ILBC; recv_payload2ac[user_config->get_g726_16_payload_type()] = CODEC_G726_16; recv_payload2ac[user_config->get_g726_24_payload_type()] = CODEC_G726_24; recv_payload2ac[user_config->get_g726_32_payload_type()] = CODEC_G726_32; recv_payload2ac[user_config->get_g726_40_payload_type()] = CODEC_G726_40; recv_payload2ac[user_config->get_dtmf_payload_type()] = CODEC_TELEPHONE_EVENT; send_payload2ac.clear(); } t_session::~t_session() { stop_rtp(); } t_session *t_session::create_new_version(void) const { t_session *s = new t_session(*this); MEMMAN_NEW(s); s->src_sdp_version = int2str(atoi(src_sdp_version.c_str()) + 1); s->recvd_codecs.clear(); s->recvd_offer = false; s->recvd_answer = false; s->sent_offer = false; // Do not copy the RTP session s->set_audio_session(NULL); // Clear the codec to payload mappings as a new response must // be received from the far end s->send_ac2payload.clear(); s->send_payload2ac.clear(); return s; } t_session *t_session::create_call_hold(void) const { t_session *s = create_new_version(); if (user_config->get_hold_variant() == HOLD_RFC2543) { s->receive_host = "0.0.0.0"; } else if (user_config->get_hold_variant() == HOLD_RFC3264) { // RFC 3264 8.4 if (direction == SDP_SENDRECV) { s->direction = SDP_SENDONLY; } else if (direction == SDP_RECVONLY) { s->direction = SDP_INACTIVE; } } else { assert(false); } // Prevent RTP from being started for this session as long // as the call is put on hold. Without this, the RTP sessions // will get started when a re-INVITE is received from the far-end // while the call is still locally on-hold. s->hold(); return s; } t_session *t_session::create_call_retrieve(void) const { t_session *s = create_new_version(); if (user_config->get_hold_variant() == HOLD_RFC2543) { s->receive_host = retrieve_host; } else if (user_config->get_hold_variant() == HOLD_RFC3264) { // RFC 3264 8.4 if (direction == SDP_SENDONLY) { s->direction = SDP_SENDRECV; } else if (direction == SDP_INACTIVE) { s->direction = SDP_RECVONLY; } } else { assert(false); } return s; } t_session *t_session::create_clean_copy(void) const { t_session *s = new t_session(*this); MEMMAN_NEW(s); s->src_sdp_version = int2str(atoi(src_sdp_version.c_str()) + 1); s->dst_sdp_version = ""; s->dst_sdp_id = ""; s->dst_rtp_host = ""; s->dst_rtp_port = 0; s->recvd_codecs.clear(); s->recvd_offer = false; s->recvd_answer = false; s->sent_offer = false; s->direction = SDP_SENDRECV; // Do not copy the RTP session s->set_audio_session(NULL); // Clear the codec to payload mappings as a new response must // be received from the far end s->send_ac2payload.clear(); s->send_payload2ac.clear(); return s; } bool t_session::process_sdp_offer(t_sdp *sdp, int &warn_code, string &warn_text) { if (!sdp->is_supported(warn_code, warn_text)) return false; dst_sdp_version = sdp->origin.session_version; dst_sdp_id = sdp->origin.session_id; recvd_sdp_offer = *sdp; // RFC 3264 5 // SDP may contain 0 m= lines if (sdp->media.empty()) return true; dst_rtp_host = sdp->get_rtp_host(SDP_AUDIO); dst_rtp_port = sdp->get_rtp_port(SDP_AUDIO); set_recvd_codecs(sdp); dst_zrtp_support = sdp->get_zrtp_support(SDP_AUDIO); // The direction in the SDP is from the point of view of the // far end. Swap the direction to store it as the point of view // from the near end. switch(sdp->get_direction(SDP_AUDIO)) { case SDP_INACTIVE: direction = SDP_INACTIVE; break; case SDP_SENDONLY: if (is_on_hold && user_config->get_hold_variant() == HOLD_RFC3264) { // The phone is put on-hold. We don't want to // receive media. direction = SDP_INACTIVE; } else { direction = SDP_RECVONLY; } break; case SDP_RECVONLY: direction = SDP_SENDONLY; break; case SDP_SENDRECV: if (is_on_hold && user_config->get_hold_variant() == HOLD_RFC3264) { // The phone is put on-hold. We don't want to // receive media. direction = SDP_SENDONLY; } else { direction = SDP_SENDRECV; } break; default: assert(false); } // Check if the list of received codecs has at least 1 codec // in common with the list of codecs we can offer. If there // is no common codec, then no call can be established. list::iterator supported_codec_it = offer_codecs.end(); for (list::const_iterator i = recvd_codecs.begin(); i != recvd_codecs.end(); i++) { list::iterator tmp_it; if ((supported_codec_it == offer_codecs.end() || !user_config->get_in_obey_far_end_codec_pref()) && (tmp_it = std::find(offer_codecs.begin(), supported_codec_it, *i)) != supported_codec_it) { // Codec supported supported_codec_it = tmp_it; use_codec = *i; // this codec goes into answer // Use the payload to codec bindings as signalled in the // offer by the far end. recv_payload2ac[send_ac2payload[use_codec]] = use_codec; recv_ac2payload[use_codec] = send_ac2payload[use_codec]; } else if (*i == CODEC_TELEPHONE_EVENT) { // telephone-event payload is supported send_dtmf_pt = send_ac2payload[*i]; // When we support RFC 2833 events, then take the payload // type from the far end. if (recv_dtmf_pt > 0) { recv_dtmf_pt = send_dtmf_pt; // this goes into answer as well } } } if (supported_codec_it == offer_codecs.end()) { warn_code = W_305_INCOMPATIBLE_MEDIA_FORMAT; warn_text = "None of the audio codecs is supported"; return false; } // Overwrite ptime value with ptime from SDP unsigned short p = sdp->get_ptime(SDP_AUDIO); if (p > 0) ptime = p; // RFC 3952 5 // Select the iLBC mode that needs the lowest bandwidth if (use_codec == CODEC_ILBC) { int recvd_mode = sdp->get_fmtp_int_param(SDP_AUDIO, send_ac2payload[use_codec], "mode"); if (recvd_mode == -1) recvd_mode = 30; if (VALID_ILBC_MODE(recvd_mode) && recvd_mode > ilbc_mode) { ilbc_mode = static_cast(recvd_mode); } } return true; } bool t_session::process_sdp_answer(t_sdp *sdp, int &warn_code, string &warn_text) { if (!sdp->is_supported(warn_code, warn_text)) return false; // As our offer always contains an audio m= line, the answer // should contain one as well. If there are media lines, then // the sdp->is_supported already verified there is audio. if (sdp->media.empty()) { warn_code = W_304_MEDIA_TYPE_NOT_AVAILABLE; warn_text = "Valid media stream for audio is missing"; return false; } dst_sdp_version = sdp->origin.session_version; dst_sdp_id = sdp->origin.session_id; dst_rtp_host = sdp->get_rtp_host(SDP_AUDIO); dst_rtp_port = sdp->get_rtp_port(SDP_AUDIO); dst_zrtp_support = sdp->get_zrtp_support(SDP_AUDIO); set_recvd_codecs(sdp); // Find the first codec in the received codecs list that // is supported. // Per the offer/answer model all received codecs should be // supported! It seems that some applications put more codecs // in the answer though. list::iterator codec_found_it = offer_codecs.end(); for (list::const_iterator i = recvd_codecs.begin(); i != recvd_codecs.end(); i++) { list::iterator tmp_it; if ((codec_found_it == offer_codecs.end() || !user_config->get_out_obey_far_end_codec_pref()) && (tmp_it = std::find(offer_codecs.begin(), codec_found_it, *i)) != codec_found_it) { codec_found_it = tmp_it; use_codec = *i; } else if (*i == CODEC_TELEPHONE_EVENT) { // telephone-event payload is supported send_dtmf_pt = send_ac2payload[*i]; } } if (codec_found_it == offer_codecs.end()) { // None of the answered codecs is supported warn_code = W_305_INCOMPATIBLE_MEDIA_FORMAT; warn_text = "None of the codecs is supported"; return false; } // Overwrite ptime value with ptime from SDP unsigned short p = sdp->get_ptime(SDP_AUDIO); if (p > 0) ptime = p; // RFC 3952 5 // Select the iLBC mode that needs the lowest bandwidth if (use_codec == CODEC_ILBC) { int recvd_mode = sdp->get_fmtp_int_param(SDP_AUDIO, send_ac2payload[use_codec], "mode"); if (recvd_mode == -1) recvd_mode = 30; if (VALID_ILBC_MODE(recvd_mode) && recvd_mode > ilbc_mode) { ilbc_mode = static_cast(recvd_mode); } } return true; } void t_session::create_sdp_offer(t_sip_message *m, const string &user) { // Delete old body if present if (m->body) { MEMMAN_DELETE(m->body); delete m->body; } // Determine the IP address to receive the media streams if (receive_host == AUTO_IP4_ADDRESS) { unsigned local_ip = m->get_local_ip(); if (local_ip == 0) { log_file->write_report("Cannot determine local IP address.", "t_session::create_sdp_offer", LOG_NORMAL, LOG_CRITICAL); } else { receive_host = USER_HOST(user_config, h_ip2str(local_ip)); retrieve_host = receive_host; } } m->body = new t_sdp(user, src_sdp_id, src_sdp_version, receive_host, receive_host, receive_port, offer_codecs, recv_dtmf_pt, recv_ac2payload); MEMMAN_NEW(m->body); // Set ptime for G711/G726 codecs list::iterator it_g7xx; it_g7xx = find(offer_codecs.begin(), offer_codecs.end(), CODEC_G711_ALAW); if (it_g7xx == offer_codecs.end()) { it_g7xx = find(offer_codecs.begin(), offer_codecs.end(), CODEC_G711_ULAW); } if (it_g7xx == offer_codecs.end()) { it_g7xx = find(offer_codecs.begin(), offer_codecs.end(), CODEC_G726_16); } if (it_g7xx == offer_codecs.end()) { it_g7xx = find(offer_codecs.begin(), offer_codecs.end(), CODEC_G726_24); } if (it_g7xx == offer_codecs.end()) { it_g7xx = find(offer_codecs.begin(), offer_codecs.end(), CODEC_G726_32); } if (it_g7xx == offer_codecs.end()) { it_g7xx = find(offer_codecs.begin(), offer_codecs.end(), CODEC_G726_40); } if (it_g7xx != offer_codecs.end()) { ((t_sdp *)m->body)->set_ptime(SDP_AUDIO, ptime); } // Set mode for iLBC codecs list::iterator it_ilbc; it_ilbc = find(offer_codecs.begin(), offer_codecs.end(), CODEC_ILBC); if (it_ilbc != offer_codecs.end() && ilbc_mode != 30) { ((t_sdp *)m->body)->set_fmtp_int_param(SDP_AUDIO, recv_ac2payload[CODEC_ILBC], "mode", ilbc_mode); } // Set direction if (direction != SDP_SENDRECV) { ((t_sdp *)m->body)->set_direction(SDP_AUDIO, direction); } // Set zrtp support if (user_config->get_zrtp_enabled() && user_config->get_zrtp_sdp()) { ((t_sdp *)m->body)->set_zrtp_support(SDP_AUDIO); } m->hdr_content_type.set_media(t_media("application", "sdp")); sent_offer = true; } void t_session::create_sdp_answer(t_sip_message *m, const string &user) { // Delete old body if present if (m->body) { MEMMAN_DELETE(m->body); delete m->body; } // Determine the IP address to receive the media streams if (receive_host == AUTO_IP4_ADDRESS) { unsigned long local_ip = 0; unsigned long dst_ip = gethostbyname(dst_rtp_host); if (dst_ip != 0) { // Determine source IP address for RTP from the // destination RTP IP address. log_file->write_report("Cannot determine local IP address from RTP destination.", "t_session::create_sdp_answer", LOG_NORMAL, LOG_WARNING); local_ip = get_src_ip4_address_for_dst(dst_ip); } else { string log_msg = "Cannot determine IP address for: "; log_msg += dst_rtp_host; log_file->write_report(log_msg, "t_session::create_sdp_answer", LOG_NORMAL, LOG_WARNING); } if (local_ip == 0) { // Somehow the source IP address could not be determined // from the destination RTP address. Try to determine it // from the destination of the SIP message. local_ip = m->get_local_ip(); } if (local_ip == 0) { log_file->write_report("Cannot determine local IP address.", "t_session::create_sdp_answer", LOG_NORMAL, LOG_CRITICAL); } else { receive_host = USER_HOST(user_config, h_ip2str(local_ip)); retrieve_host = receive_host; } } list answer_codecs; answer_codecs.push_back(use_codec); // RFC 3264 6 // The answer must contain an m-line for each m-line in the offer in // the same order. Media can be rejected by setting the port to 0. // Only the first audio stream is accepted, all other media streams // will be rejected. m->body = new t_sdp(user, src_sdp_id, src_sdp_version, receive_host, receive_host); MEMMAN_NEW(m->body); bool audio_answered = false; for (list::const_iterator i = recvd_sdp_offer.media.begin(); i != recvd_sdp_offer.media.end(); i++) { if (!audio_answered && i->get_media_type() == SDP_AUDIO && i->port != 0) { // Accept the first audio stream ((t_sdp *)m->body)->add_media(t_sdp_media( SDP_AUDIO, receive_port, answer_codecs, recv_dtmf_pt, send_ac2payload)); audio_answered = true; } else { // Reject media stream by setting port to zero t_sdp_media reject_media(*i); reject_media.port = 0; ((t_sdp *)m->body)->add_media(reject_media); } } m->hdr_content_type.set_media(t_media("application", "sdp")); // If there were no media lines in the offer, we sent no media // lines in the answer if (recvd_sdp_offer.media.empty()) return; // Set audio attributes // Set ptime for G711 codecs if (use_codec == CODEC_G711_ALAW || use_codec == CODEC_G711_ULAW) { ((t_sdp *)m->body)->set_ptime(SDP_AUDIO, ptime); } // Set mode for iLBC codecs if (use_codec == CODEC_ILBC && ilbc_mode != 30) { unsigned short ilbc_payload = const_cast(this)-> recv_ac2payload[CODEC_ILBC]; ((t_sdp *)m->body)->set_fmtp_int_param(SDP_AUDIO, ilbc_payload, "mode", ilbc_mode); } // Set direction if (direction != SDP_SENDRECV) { ((t_sdp *)m->body)->set_direction(SDP_AUDIO, direction); } // Set zrtp support if (user_config->get_zrtp_enabled() && user_config->get_zrtp_sdp()) { ((t_sdp *)m->body)->set_zrtp_support(SDP_AUDIO); } } void t_session::start_rtp(void) { // If a session is killed, it may not be started again. if (is_killed) { log_file->write_report("Cannot start. The session is killed already.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); return; } // If a session is on-hold then do not start RTP. if (is_on_hold) { log_file->write_report("Cannot start. The session is on hold.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); return; } if (receive_host.empty()) { log_file->write_report("Cannot start. receive_host is empty.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); return; } if (dst_rtp_host.empty()) { log_file->write_report("Cannot start. dst_rtp_host is empty.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); return; } // Local and remote hold if (((receive_host == "0.0.0.0" || receive_port == 0) && (dst_rtp_host == "0.0.0.0" || dst_rtp_port == 0)) || direction == SDP_INACTIVE) { log_file->write_report("Cannot start. Local and remote on hold.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); return; } // Inform user about the codecs get_line()->ci_set_send_codec(use_codec); get_line()->ci_set_recv_codec(use_codec); ui->cb_send_codec_changed(get_line()->get_line_number(), use_codec); ui->cb_recv_codec_changed(get_line()->get_line_number(), use_codec); // Determine ptime unsigned short audio_ptime; if (use_codec == CODEC_ILBC) { audio_ptime = ilbc_mode; } else { audio_ptime = ptime; } // Determine if audio must be encrypted bool encrypt_audio = get_line()->get_try_to_encrypt(); if (user_config->get_zrtp_send_if_supported()) { encrypt_audio = encrypt_audio && dst_zrtp_support; } // Start the RTP streams if (dst_rtp_host == "0.0.0.0" || dst_rtp_port == 0 || direction == SDP_RECVONLY) { // Local hold -> do not send RTP log_file->write_report("Local hold. Do not send RTP.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); audio_rtp_session = new t_audio_session(this, "0.0.0.0", get_line()->get_rtp_port(), "", 0, use_codec, audio_ptime, recv_payload2ac, send_ac2payload, encrypt_audio); MEMMAN_NEW(audio_rtp_session); } else if (receive_host == "0.0.0.0" || receive_port == 0 || direction == SDP_SENDONLY) { // Remote hold // For music on-hold music should be played here. // Without music on-hold do not send out RTP /* audio_rtp_session = new t_audio_session(this, "", 0, dst_rtp_host, dst_rtp_port, codec, ptime); */ log_file->write_report("Do not start. Remote hold.", "t_session::start_rtp", LOG_NORMAL, LOG_DEBUG); return; } else { // Bi-directional audio audio_rtp_session = new t_audio_session(this, "0.0.0.0", get_line()->get_rtp_port(), dst_rtp_host, dst_rtp_port, use_codec, audio_ptime, recv_payload2ac, send_ac2payload, encrypt_audio); MEMMAN_NEW(audio_rtp_session); } // Check if the created audio session is valid. if (!audio_rtp_session->is_valid()) { log_file->write_report("Audio session is invalid.", "t_session::start_rtp", LOG_NORMAL, LOG_CRITICAL); MEMMAN_DELETE(audio_rtp_session); delete audio_rtp_session; audio_rtp_session = NULL; return; } // Set dynamic payload type for DTMF events if (recv_dtmf_pt > 0) { unsigned short alt_dtmf_pt; if (recv_payload2ac.find(send_dtmf_pt) == recv_payload2ac.end()) { // Allow the payload type as signalled by the far end // as an alternative to the payload as signalled by Twinkle. alt_dtmf_pt = send_dtmf_pt; } else { // The payload type as signalled by the far end for DTMF // is already in use by Twinkle for another codec, so it // cannot be used as an alternative. alt_dtmf_pt = recv_dtmf_pt; } audio_rtp_session->set_pt_in_dtmf(recv_dtmf_pt, alt_dtmf_pt); } if (send_dtmf_pt > 0) { audio_rtp_session->set_pt_out_dtmf(send_dtmf_pt); switch (user_config->get_dtmf_transport()) { case DTMF_AUTO: case DTMF_RFC2833: get_line()->ci_set_dtmf_supported(true, false); break; case DTMF_INBAND: get_line()->ci_set_dtmf_supported(true, true); break; case DTMF_INFO: get_line()->ci_set_dtmf_supported(true, false, true); break; default: assert(false); } ui->cb_dtmf_supported(get_line()->get_line_number()); } else { switch (user_config->get_dtmf_transport()) { case DTMF_AUTO: case DTMF_INBAND: get_line()->ci_set_dtmf_supported(true, true); ui->cb_dtmf_supported(get_line()->get_line_number()); break; case DTMF_RFC2833: get_line()->ci_set_dtmf_supported(false); ui->cb_dtmf_not_supported(get_line()->get_line_number()); break; case DTMF_INFO: get_line()->ci_set_dtmf_supported(true, false, true); ui->cb_dtmf_supported(get_line()->get_line_number()); break; default: assert(false); } } audio_rtp_session->run(); } void t_session::stop_rtp(void) { if (audio_rtp_session) { MEMMAN_DELETE(audio_rtp_session); delete audio_rtp_session; audio_rtp_session = NULL; get_line()->ci_set_dtmf_supported(false); ui->cb_line_state_changed(); } } void t_session::kill_rtp(void) { stop_rtp(); is_killed = true; } t_audio_session *t_session::get_audio_session(void) const { return audio_rtp_session; } void t_session::set_audio_session(t_audio_session *as) { audio_rtp_session = as; } bool t_session::equal_audio(const t_session &s) const { // According to RFC 3264 6, the SDP version in the o= line // must be updated when the SDP is changed. // We check for more changes to interoperate with SIP // devices that do not adhere fully to RFC 3264 return (receive_host == s.receive_host && receive_port == s.receive_port && dst_rtp_host == s.dst_rtp_host && dst_rtp_port == s.dst_rtp_port && direction == s.direction && src_sdp_version == s.src_sdp_version && dst_sdp_version == s.dst_sdp_version && src_sdp_id == s.src_sdp_id && dst_sdp_id == s.dst_sdp_id); } void t_session::send_dtmf(char digit, bool inband) { if (audio_rtp_session) audio_rtp_session->send_dtmf(digit, inband); } t_line *t_session::get_line(void) const { return dialog->get_line(); } void t_session::set_owner(t_dialog *d) { dialog = d; } void t_session::hold(void) { is_on_hold = true; } void t_session::unhold(void) { is_on_hold = false; } bool t_session::is_rtp_active(void) const { return (audio_rtp_session != NULL); } twinkle-1.4.2/src/userintf.h0000644000175000001440000004541511130733173012717 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _USERINTF_H #define _USERINTF_H #include #include #include "events.h" #include "phone.h" #include "protocol.h" #include "parser/request.h" #include "parser/response.h" #include "audio/tone_gen.h" #include "threads/thread.h" #include "im/msg_session.h" #include "presence/presence_state.h" #include "twinkle_config.h" #define PRODUCT_DATE VERSION_DATE #define PRODUCT_AUTHOR "Michel de Boer" // Tone definitions // The intervals indicate the length of silence between repetitions // of the wav file. Duration is in ms #define FILE_RINGTONE "ringtone.wav" #define INTERVAL_RINGTONE 3000 #define FILE_RINGBACK "ringback.wav" #define INTERVAL_RINGBACK 3000 using namespace std; struct t_command_arg { char flag; string value; }; class t_userintf : public i_prohibit_thread { protected: enum t_zrtp_cmd { ZRTP_ENCRYPT, ZRTP_GO_CLEAR, ZRTP_CONFIRM_SAS, ZRTP_RESET_SAS }; private: bool end_interface; // indicates if interface loop should quit list all_commands; // list of all commands t_tone_gen *tone_gen; // tone generator for ringing // The user for which out-of-dialog requests are executed. t_user *active_user; // The user can type a prefix of the command only. This method // completes a prefix to a full command. // If no command is found then the empty string is returned. // If the prefix is ambiguous, then argument ambiguous is set to true // and the empty string is returned. string complete_command(const string &c, bool &ambiguous); // Parse command arguments. The list must contain the command as first // element followed by the arguments. bool parse_args(const list command_list, list &al); // The command_list must contain the command itself as first // argument. Subsequent elements are the arguments. bool exec_invite(const list command_list, bool immediate = false); bool exec_redial(const list command_list); bool exec_answer(const list command_list); bool exec_answerbye(const list command_list); bool exec_reject(const list command_list); bool exec_redirect(const list command_list, bool immediate = false); bool exec_dnd(const list command_list); bool exec_auto_answer(const list command_list); bool exec_bye(const list command_list); bool exec_hold(const list command_list); bool exec_retrieve(const list command_list); bool exec_refer(const list command_list, bool immediate = false); bool exec_conference(const list command_list); bool exec_mute(const list command_list); bool exec_dtmf(const list command_list); bool exec_register(const list command_list); bool exec_deregister(const list command_list); bool exec_fetch_registrations(const list command_list); bool exec_options(const list command_list, bool immediate = false); bool exec_line(const list command_list); bool exec_user(const list command_list); bool exec_zrtp(const list command_list); bool exec_message(const list command_list); bool exec_presence(const list command_list); bool exec_quit(const list command_list); bool exec_help(const list command_list); protected: t_phone *phone; // Asynchronous event queue t_event_queue evq_ui_events; t_thread *thr_process_events; // Indicates if commands should print output to stdout bool use_stdout; // Throttle dtmtf not supported messages bool throttle_dtmf_not_supported; // Last call information t_url last_called_url; string last_called_display; string last_called_subject; string last_called_profile; // profile used to make the call bool last_called_hide_user; // The do_* methods perform the commands parsed by the exec_* methods. virtual bool do_invite(const string &destination, const string &display, const string &subject, bool immediate, bool anonymous); virtual void do_redial(void); virtual void do_answer(void); virtual void do_answerbye(void); virtual void do_reject(void); virtual void do_redirect(bool show_status, bool type_present, t_cf_type cf_type, bool action_present, bool enable, int num_redirections, const list &dest_strlist, bool immediate); virtual void do_dnd(bool show_status, bool toggle, bool enable); virtual void do_auto_answer(bool show_status, bool toggle, bool enable); virtual void do_bye(void); virtual void do_hold(void); virtual void do_retrieve(void); virtual bool do_refer(const string &destination, t_transfer_type transfer_type, bool immediate); virtual void do_conference(void); virtual void do_mute(bool show_status, bool toggle, bool enable); virtual void do_dtmf(const string &digits); virtual void do_register(bool reg_all_profiles); virtual void do_deregister(bool dereg_all_profiles, bool dereg_all_devices); virtual void do_fetch_registrations(void); virtual bool do_options(bool dest_set, const string &destination, bool immediate); virtual void do_line(int line); virtual void do_user(const string &profile_name); virtual void do_zrtp(t_zrtp_cmd zrtp_cmd); virtual bool do_message(const string &destination, const string &display, const im::t_msg &msg); virtual void do_presence(t_presence_state::t_basic_state basic_state); virtual void do_quit(void); virtual void do_help(const list &al); public: t_userintf(t_phone *_phone); virtual ~t_userintf(); /** * Expand a SIP destination to a full SIP/TEL uri, i.e. add sip/tel scheme * and domain if these are missing. * @param user_config [in] User profile of the user for which the expansion is done. * @param dst [in] The address string to expand. * @param scheme [in] Scheme to expand to (sip/tel/""). If scheme is empty then * the expansion is done according to preferences from the user profile. * @return The expanded address. */ string expand_destination(t_user *user_config, const string &dst, const string &scheme = ""); // Expand a SIP destination into a display and a full SIP uri void expand_destination(t_user *user_config, const string &dst, string &display, string &dst_url); void expand_destination(t_user *user_config, const string &dst, t_display_url &display_url); // Expand a SIP destination as above, but split off any headers if any. // If the subject header is present, then its value will be returned in // subject. // The dst_no_headers parameter will contain the dst string with the headers // cut off. void expand_destination(t_user *user_config, const string &dst, t_display_url &display_url, string &subject, string &dst_no_headers); // Format a SIP address for user display virtual string format_sip_address(t_user *user_config, const string &display, const t_url &uri) const; // Format a warning for user display virtual list format_warnings(const t_hdr_warning &hdr_warning) const; // Format a codec for user display virtual string format_codec(t_audio_codec codec) const; // The immediate flag is by the cmd_cli method (see below) bool exec_command(const string &command_line, bool immediate = false); // Run the user interface virtual void run(void); // This method executes asynchronous uier interface events virtual void process_events(void); // Save user interface state to system settings virtual void save_state(void); // Restore user interface state from system settings virtual void restore_state(void); // Lock the user interface to synchornize output virtual void lock(void); virtual void unlock(void); // Select a network interface. Returns string representation of IP address. virtual string select_network_intf(void); // Select a user configuration file. Returns false if selection failed. virtual bool select_user_config(list &config_files); // Call back functions virtual void cb_incoming_call(t_user *user_config, int line, const t_request *r); virtual void cb_call_cancelled(int line); virtual void cb_far_end_hung_up(int line); virtual void cb_answer_timeout(int line); virtual void cb_sdp_answer_not_supported(int line, const string &reason); virtual void cb_sdp_answer_missing(int line); virtual void cb_unsupported_content_type(int line, const t_sip_message *r); virtual void cb_ack_timeout(int line); virtual void cb_100rel_timeout(int line); virtual void cb_prack_failed(int line, const t_response *r); virtual void cb_provisional_resp_invite(int line, const t_response *r); virtual void cb_cancel_failed(int line, const t_response *r); virtual void cb_call_answered(t_user *user_config, int line, const t_response *r); virtual void cb_call_failed(t_user *user_config, int line, const t_response *r); virtual void cb_stun_failed_call_ended(int line); virtual void cb_call_ended(int line); virtual void cb_call_established(int line); virtual void cb_options_response(const t_response *r); virtual void cb_reinvite_success(int line, const t_response *r); virtual void cb_reinvite_failed(int line, const t_response *r); virtual void cb_retrieve_failed(int line, const t_response *r); virtual void cb_invalid_reg_resp(t_user *user_config, const t_response *r, const string &reason); virtual void cb_register_success(t_user *user_config, const t_response *r, unsigned long expires, bool first_success); virtual void cb_register_failed(t_user *user_config, const t_response *r, bool first_failure); virtual void cb_register_stun_failed(t_user *user_config, bool first_failure); virtual void cb_deregister_success(t_user *user_config, const t_response *r); virtual void cb_deregister_failed(t_user *user_config, const t_response *r); virtual void cb_fetch_reg_failed(t_user *user_config, const t_response *r); virtual void cb_fetch_reg_result(t_user *user_config, const t_response *r); virtual void cb_register_inprog(t_user *user_config, t_register_type register_type); virtual void cb_redirecting_request(t_user *user_config, int line, const t_contact_param &contact); virtual void cb_redirecting_request(t_user *user_config, const t_contact_param &contact); virtual void cb_play_ringtone(int line); virtual void cb_play_ringback(t_user *user_config); virtual void cb_stop_tone(int line); virtual void cb_notify_call(int line, string from_party); virtual void cb_stop_call_notification(int line); virtual void cb_dtmf_detected(int line, char dtmf_event); virtual void cb_async_dtmf_detected(int line, char dtmf_event); virtual void cb_send_dtmf(int line, char dtmf_event); virtual void cb_async_send_dtmf(int line, char dtmf_event); virtual void cb_dtmf_not_supported(int line); virtual void cb_dtmf_supported(int line); virtual void cb_line_state_changed(void); virtual void cb_async_line_state_changed(void); virtual void cb_send_codec_changed(int line, t_audio_codec codec); virtual void cb_recv_codec_changed(int line, t_audio_codec codec); virtual void cb_async_recv_codec_changed(int line, t_audio_codec codec); virtual void cb_notify_recvd(int line, const t_request *r); virtual void cb_refer_failed(int line, const t_response *r); virtual void cb_refer_result_success(int line); virtual void cb_refer_result_failed(int line); virtual void cb_refer_result_inprog(int line); // A call is being referred by the far end. r must be the REFER request. virtual void cb_call_referred(t_user *user_config, int line, t_request *r); // The reference failed. Call to referrer is retrieved. virtual void cb_retrieve_referrer(t_user *user_config, int line); // A consulation call for a call transfer is being setup. virtual void cb_consultation_call_setup(t_user *user_config, int line); // STUN errors virtual void cb_stun_failed(t_user *user_config, int err_code, const string &err_reason); virtual void cb_stun_failed(t_user *user_config); // Interactive call back functions virtual bool cb_ask_user_to_redirect_invite(t_user *user_config, const t_url &destination, const string &display); virtual bool cb_ask_user_to_redirect_request(t_user *user_config, const t_url &destination, const string &display, t_method method); virtual bool cb_ask_credentials(t_user *user_config, const string &realm, string &username, string &password); // Ask questions asynchronously. virtual void cb_ask_user_to_refer(t_user *user_config, const t_url &refer_to_uri, const string &refer_to_display, const t_url &referred_by_uri, const string &referred_by_display); // Send the answer for refer permission to the transaction layer. void send_refer_permission(bool permission); // Show an error message to the user. Depending on the interface mode // the user has to acknowledge the error before processing continues. virtual void cb_show_msg(const string &msg, t_msg_priority prio = MSG_INFO); // Ask a yes/no question to the user. // Returns true for yes and false for no. virtual bool cb_ask_msg(const string &msg, t_msg_priority prio = MSG_INFO); /** * Display an error/information message. * @param msg [in] Message to display. * @param prio [in] Priority associated with the message. */ virtual void cb_display_msg(const string &msg, t_msg_priority prio = MSG_INFO); /** * Display an error/information message in an asynchronous way. * @param msg [in] Message to display. * @param prio [in] Priority associated with the message. */ virtual void cb_async_display_msg(const string &msg, t_msg_priority prio = MSG_INFO); // Log file has been updated virtual void cb_log_updated(bool log_zapped = false); // Call history has been updated virtual void cb_call_history_updated(void); virtual void cb_missed_call(int num_missed_calls); // Show firewall/NAT discovery progress virtual void cb_nat_discovery_progress_start(int num_steps); virtual void cb_nat_discovery_progress_step(int step); virtual void cb_nat_discovery_finished(void); virtual bool cb_nat_discovery_cancelled(void); // ZRTP virtual void cb_line_encrypted(int line, bool encrypted, const string &cipher_mode = ""); virtual void cb_async_line_encrypted(int line, bool encrypted, const string &cipher_mode = ""); virtual void cb_show_zrtp_sas(int line, const string &sas); virtual void cb_async_show_zrtp_sas(int line, const string &sas); virtual void cb_zrtp_confirm_go_clear(int line); virtual void cb_async_zrtp_confirm_go_clear(int line); virtual void cb_zrtp_sas_confirmed(int line); virtual void cb_zrtp_sas_confirmation_reset(int line); // MWI virtual void cb_update_mwi(void); virtual void cb_mwi_subscribe_failed(t_user *user_config, t_response *r, bool first_failure); virtual void cb_mwi_terminated(t_user *user_config, const string &reason); /** @name Instant messaging */ //@{ /** * Incoming MESSAGE request callback. * @param user_config [in] User profile of the user receiving this MESSAGE request. * @param r [in] The MESSAGE request. * @return True if the message is accepted. * @return False if the message is rejected, i.e. maximum number of sessions reached. */ virtual bool cb_message_request(t_user *user_config, t_request *r); /** * Incoming MESSAGE response callback. * @param user_config [in] User profile of the user receiving this MESSAGE response. * @param r [in] The MESSAGE response. * @param req [in] The MESSAGE request for which the response is received. */ virtual void cb_message_response(t_user *user_config, t_response *r, t_request *req); /** * Incoming MESSAGE request with composing indication callback. * @param user_config [in] User profile of the user receiving this MESSAGE response. * @param r [in] The MESSAGE request containing the composing indication. * @param state [in] The message composing state. * @param refresh [in] The refresh interval in seconds when state is active. */ virtual void cb_im_iscomposing_request(t_user *user_config, t_request *r, im::t_composing_state state, time_t refresh); /** * Indication that the far-end does not support message composing indications. * @param user_config [in] User profile of the user receiving this MESSAGE response. * @param r [in] The MESSAGE response on the composing indication. */ virtual void cb_im_iscomposing_not_supported(t_user *user_config, t_response *r); //@} // Get last call information // Returns true if last call information is valid // Returns false is there is no valid last call information virtual bool get_last_call_info(t_url &url, string &display, string &subject, t_user **user_config, bool &hide_user) const; virtual bool can_redial(void) const; // Execute external commands // Some comments require confirmation from the user via the user // interface, e.g. in GUI mode, a call dialog may popup for cmd_call. // The 'immediate' flag indicates that no user confirmation is required. // The command should be executed immediately. virtual void cmd_call(const string &destination, bool immediate); virtual void cmd_quit(void); void cmd_quit_async(void); virtual void cmd_cli(const string &command, bool immeidate); /** Execute the SHOW command. */ virtual void cmd_show(void); /** Execute the HIDE command. */ virtual void cmd_hide(void); // Lookup a URL in the address book virtual string get_name_from_abook(t_user *user_config, const t_url &u); // Get all command names const list& get_all_commands(void); }; void *process_events_main(void *arg); extern t_userintf *ui; #endif twinkle-1.4.2/src/exceptions.h0000644000175000001440000000216111127714051013230 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Exceptions. */ #ifndef _EXCEPTIONS_H #define _EXCEPTIONS_H #include /** Exception tupe. */ enum t_exception { X_DIALOG_ALREADY_ESTABLISHED, /**< Dialog is already established. */ X_WRONG_STATE /**< State machine is in wrong state. */ }; class empty_list_exception : public std::exception { }; #endif twinkle-1.4.2/src/twinkle_config.h.in0000644000175000001440000001566411151323401014462 00000000000000/* src/twinkle_config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_CARBON_CARBON_H /* Define if you have the CoreAudio API */ #undef HAVE_COREAUDIO /* Define to 1 if you have the header file. */ #undef HAVE_CRT_EXTERNS_H /* Defines if your system has the crypt function */ #undef HAVE_CRYPT /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_HISTORY_H /* Define to 1 if you have the library. */ #undef HAVE_ILBC /* Define to 1 if you have a C++ ilbc library. */ #undef HAVE_ILBC_CPP /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have KDE. */ #undef HAVE_KDE /* Define to 1 if you have the library. */ #undef HAVE_LIBASOUND /* Define if you have libjpeg */ #undef HAVE_LIBJPEG /* Define to 1 if you have the `magic' library (-lmagic). */ #undef HAVE_LIBMAGIC /* Define if you have libpng */ #undef HAVE_LIBPNG /* Define if you have a working libpthread (will enable threaded code) */ #undef HAVE_LIBPTHREAD /* Define if you have a readline compatible library */ #undef HAVE_LIBREADLINE /* Define to 1 if you have the `sndfile' library (-lsndfile). */ #undef HAVE_LIBSNDFILE /* Define if you have libz */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_ERRQUEUE_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define if your system needs _NSGetEnviron to set up the environment */ #undef HAVE_NSGETENVIRON /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_H /* Define if your readline library has \`add_history' */ #undef HAVE_READLINE_HISTORY /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_HISTORY_H /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_READLINE_H /* Define if you have res_init */ #undef HAVE_RES_INIT /* Define if you have the res_init prototype */ #undef HAVE_RES_INIT_PROTO /* Define if you have a STL implementation by SGI */ #undef HAVE_SGI_STL /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the library. */ #undef HAVE_SPEEX /* Define to 1 if you have the header file. */ #undef HAVE_SPEEX_SPEEX_ECHO_H /* Define to 1 if you have the header file. */ #undef HAVE_SPEEX_SPEEX_PREPROCESS_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define if you have strlcat */ #undef HAVE_STRLCAT /* Define if you have the strlcat prototype */ #undef HAVE_STRLCAT_PROTO /* Define if you have strlcpy */ #undef HAVE_STRLCPY /* Define if you have the strlcpy prototype */ #undef HAVE_STRLCPY_PROTO /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BITYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to 1 if you have the library. */ #undef HAVE_ZRTP /* Suffix for lib directories */ #undef KDELIBSUFF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `char *', as computed by sizeof. */ #undef SIZEOF_CHAR_P /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* The size of `size_t', as computed by sizeof. */ #undef SIZEOF_SIZE_T /* The size of `unsigned long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if strerror_r returns char *. */ #undef STRERROR_R_CHAR_P /* Version number of package */ #undef VERSION /* Version release date */ #undef VERSION_DATE /* Defined if compiling without arts */ #undef WITHOUT_ARTS /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system * headers and I'm too lazy to write a configure test as long as only * unixware is related */ #ifdef _UNIXWARE #define HAVE_BOOLEAN #endif /* * AIX defines FD_SET in terms of bzero, but fails to include * that defines bzero. */ #if defined(_AIX) #include #endif #if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) # include # include # define environ (*_NSGetEnviron()) #endif #if !defined(HAVE_RES_INIT_PROTO) #ifdef __cplusplus extern "C" { #endif int res_init(void); #ifdef __cplusplus } #endif #endif #if !defined(HAVE_STRLCAT_PROTO) #ifdef __cplusplus extern "C" { #endif unsigned long strlcat(char*, const char*, unsigned long); #ifdef __cplusplus } #endif #endif #if !defined(HAVE_STRLCPY_PROTO) #ifdef __cplusplus extern "C" { #endif unsigned long strlcpy(char*, const char*, unsigned long); #ifdef __cplusplus } #endif #endif /* * On HP-UX, the declaration of vsnprintf() is needed every time ! */ #if !defined(HAVE_VSNPRINTF) || defined(hpux) #if __STDC__ #include #include #else #include #endif #ifdef __cplusplus extern "C" #endif int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); #ifdef __cplusplus extern "C" #endif int snprintf(char *str, size_t n, char const *fmt, ...); #endif #if defined(__SVR4) && !defined(__svr4__) #define __svr4__ 1 #endif /* type to use in place of socklen_t if not defined */ #undef kde_socklen_t /* type to use in place of socklen_t if not defined (deprecated, use kde_socklen_t) */ #undef ksize_t twinkle-1.4.2/src/client_request.cpp0000644000175000001440000000552711127714057014447 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "client_request.h" #include "audits/memman.h" t_mutex t_client_request::mtx_next_tuid; t_tuid t_client_request::next_tuid = 1; t_client_request::t_client_request(t_user *user, t_request *r, const t_tid _tid) : redirector(r->uri, user->get_max_redirections()) { request = (t_request *)r->copy(); stun_request = NULL; tid = _tid; ref_count = 1; mtx_next_tuid.lock(); tuid = next_tuid++; if (next_tuid == 65535) next_tuid = 1; mtx_next_tuid.unlock(); } t_client_request::t_client_request(t_user *user, StunMessage *r, const t_tid _tid) : redirector(t_url(), user->get_max_redirections()) { request = NULL; stun_request = new StunMessage(*r); MEMMAN_NEW(stun_request); tid = _tid; ref_count = 1; mtx_next_tuid.lock(); tuid = next_tuid++; if (next_tuid == 65535) next_tuid = 1; mtx_next_tuid.unlock(); } t_client_request::~t_client_request() { if (request) { MEMMAN_DELETE(request); delete request; } if (stun_request) { MEMMAN_DELETE(stun_request); delete stun_request; } } t_client_request *t_client_request::copy(void) { t_client_request *cr = new t_client_request(*this); MEMMAN_NEW(cr); if (request) { cr->request = (t_request *)request->copy(); } if (stun_request) { cr->stun_request = new StunMessage(*stun_request); MEMMAN_NEW(cr->stun_request); } cr->ref_count = 1; return cr; } t_request *t_client_request::get_request(void) const { return request; } StunMessage *t_client_request::get_stun_request(void) const { return stun_request; } t_tuid t_client_request::get_tuid(void) const { return tuid; } t_tid t_client_request::get_tid(void) const { return tid; } void t_client_request::set_tid(t_tid _tid) { tid = _tid; } void t_client_request::renew(t_tid _tid) { mtx_next_tuid.lock(); tuid = next_tuid++; if (next_tuid == 65535) next_tuid = 1; mtx_next_tuid.unlock(); tid = _tid; } int t_client_request::get_ref_count(void) const { return ref_count; } int t_client_request::inc_ref_count(void) { ref_count++; return ref_count; } int t_client_request::dec_ref_count(void) { ref_count--; return ref_count; } twinkle-1.4.2/src/prohibit_thread.h0000644000175000001440000000301111127714051014211 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PROHIBIT_THREAD_H #define _PROHIBIT_THREAD_H #include #include "threads/mutex.h" #include "threads/thread.h" using namespace std; // This class implements an interface to keep track of thread id's that are // prohibited from some actions, e.g. taking a certain lock class i_prohibit_thread { private: // List of thread id's that are prohibited from some action mutable t_mutex prohibited_mutex; set prohibited_threads; public: // Operations on the prohibited set of thread id's // Add/remove the thread id of the calling thread void add_prohibited_thread(void); void remove_prohibited_thread(void); // Returns true if the current thread is prohibited bool is_prohibited_thread(void) const; }; #endif twinkle-1.4.2/src/subscription.h0000644000175000001440000002260311127714051013576 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Subscription (RFC 3265) */ #ifndef _SUBSCRIPTION_H #define _SUBSCRIPTION_H #include #include #include "abstract_dialog.h" /** Subscription role */ enum t_subscription_role { SR_SUBSCRIBER, /**< Subscriber */ SR_NOTIFIER /**< Notifier */ }; /** Subscription state */ enum t_subscription_state { SS_NULL, /**< Initial state */ SS_ESTABLISHED, /**< Subscription is in place */ SS_UNSUBSCRIBING, /**< A request to unsubscribe has been sent */ SS_UNSUBSCRIBED, /**< An outoging unsubscribe was succesful. Waiting for the final NOTIFY. */ SS_TERMINATED, /**< Subscription ended */ }; /** * Convert a subscription state to string. * @param state [in] Subscription state. * @return String representation of state. */ string t_subscription_state2str(t_subscription_state state); /** * RFC 3265 * Generic subscription state for subscribers and notifiers * For each event type this class should be subclassed. */ class t_subscription { protected: t_subscription_role role; t_subscription_state state; /** * When a subscriber subscription is terminated, this reason indicates * the reason conveyed in the NOTIFY, if any. */ string reason_termination; /** * If the NOTIFY indicated that the subscriber may retry subscription at * a later time, then resubscribe_after indicates the number of seconds to wait. */ unsigned long resubscribe_after; /** Indicates if a re-subscribe may be done after a failure. */ bool may_resubscribe; t_abstract_dialog *dialog; /**< Dialog owning the subscription */ string event_type; string event_id; /** * User profile of user using the line * This is a pointer to the user_config owned by a phone user. * So this pointer should never be deleted. */ t_user *user_config; bool pending; /**< Indicates if not active yet. */ /** @name Timers */ //@{ /** * For a subscriber the subscription_timeout timer indicates when * the subscription must be refreshed. * For a notifier it indicates when the subscription expires. */ unsigned short id_subscription_timeout; /** * Indicates if a subscriber automatically refreshes the subscritption * when the subscription timer expires. If not, then the subscription * terminates at expiry. */ bool auto_refresh; /** Subcription expiry for a SUBSCRIBE request */ unsigned long subscription_expiry; /** Default duration for a subscription */ unsigned long default_duration; //@} /** Protect constructor from being used */ t_subscription() {}; /** Write event type and id to log file */ void log_event() const; /** * Remove a pending request. Pass one of the client request pointers. * @param cr [in] Client request to remove. */ void remove_client_request(t_client_request **cr); /** @name Create requests based on the event type */ //@{ /** * Create a SUBSCRIBE request. * Creating a SUBSCRIBE is for subscription refreshment/unsubscribe. * @param expires [in] Expiry time in seconds. */ virtual t_request *create_subscribe(unsigned long expires) const; /** * Create a NOTIFY request. * @param sub_state [in] Subscription state to be put in the Subscription-State header. * @param reason [in] The reason parameter of the Subscription-State header. */ virtual t_request *create_notify(const string &sub_state, const string &reason = "") const; //@} /** * Send request. * @param user_config [in] User profile of user sending the request. * @param r [in] Request to send. * @param tuid [in] Transaction user id. */ void send_request(t_user *user_config, t_request *r, t_tuid tuid) const; /** * Send response. * @param user_config [in] User profile of user sending the response. * @param r [in] Response to send. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ void send_response(t_user *user_config, t_response *r, t_tuid tuid, t_tid tid) const; /** * Start a subscription timer. * @param timer [in] Type of subscription timer. * @param duration [in] Duration of timer in ms */ void start_timer(t_subscribe_timer timer, long duration); /** * Stop a subscription timer. * @param timer [in] Type of subscription timer. */ void stop_timer(t_subscribe_timer timer); public: /** Pending request */ t_client_request *req_out; /** * Queue of pending outgoing NOTIFY requests. A next NOTIFY * will only be sent after the previous NOTIFY has been * answered. */ queue queue_notify; /** * Constructor * @param _dialog [in] Dialog owning this subscription. SUBSCRIBE and NOTIFY * requests are sent within this dialog. * @param _role [in] Role * @param _event_type [in] Event type of the subscription. */ t_subscription(t_abstract_dialog *_dialog, t_subscription_role _role, const string &_event_type); /** * Constructor * @param _dialog [in] Dialog owning this subscription. SUBSCRIBE and NOTIFY * requests are sent within this dialog. * @param _role [in] Role * @param _event_type [in] Event type of the subscription. * @param _event_id [in] Event id. */ t_subscription(t_abstract_dialog *_dialog, t_subscription_role _role, const string &_event_type, const string &_event_id); /** Destructor */ virtual ~t_subscription(); /** @name Getters */ //@{ t_subscription_role get_role(void) const; t_subscription_state get_state(void) const; string get_reason_termination(void) const; unsigned long get_resubscribe_after(void) const; bool get_may_resubscribe(void) const; string get_event_type(void) const; string get_event_id(void) const; unsigned long get_expiry(void) const; //@} /** @name Receive requests */ //@{ /** * Reveive SUBSCRIBE request * @param r [in] Received request. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return The return value indicates if processing is finished. * This way a subclass can first call the parent class method. * If the parent indicates that process is finished, then the child * does not need to further process. * Note that recv_subscribe returns false if the SUBSCRIBE is valid. The * subscription timer will be started, but no response is sent. The subclass * MUST further handle the SUBSCRIBE, i.e. send a response and a NOTIFY. */ virtual bool recv_subscribe(t_request *r, t_tuid tuid, t_tid tid); /** * Receive NOTIFY request. * @param r [in] Received request. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return When the NOTIFY is valid, false is returned. The subclass MUST further * handle the NOTIFY, i.e. send a response. */ virtual bool recv_notify(t_request *r, t_tuid tuid, t_tid tid); //@} /** @name Receive responses */ //@{ /** * Receive NOTIFY/SUBSCRIBE response. * @param r [in] Received response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return The return value indicates if processing is finished. */ virtual bool recv_response(t_response *r, t_tuid tuid, t_tid tid); /** * Receive NOTIFY response. * @param r [in] Received response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return The return value indicates if processing is finished. */ virtual bool recv_notify_response(t_response *r, t_tuid tuid, t_tid tid); /** * Receive SUBSCRIBE response. * @param r [in] Received response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return The return value indicates if processing is finished. */ virtual bool recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid); //@} /** * Process timeouts * @param timer [in] Type of subscription timer. * @return The return value indicates if processing is finished. */ virtual bool timeout(t_subscribe_timer timer); /** * Match timer id with a running timer. * @param timer [in] Type of subscription timer. * @return True, if id matches, otherwise false. */ virtual bool match_timer(t_subscribe_timer timer, t_object_id id_timer) const; /** * Does incoming request match with event type and id? * @param r [in] Request to match. * @return True if request matches, otherwise false. */ virtual bool match(t_request *r) const; /** * Check if subscription is pending. * @return True if subscription is pending, otherwise false. */ bool is_pending(void) const; /** * Subscribe to an event. * @param expires [in] Expiry in seconds. If expires == 0, then the default duration is used. */ virtual void subscribe(unsigned long expires); /** Unsubscribe from an event. */ virtual void unsubscribe(void); /** Refresh subscription. */ virtual void refresh_subscribe(void); }; #endif twinkle-1.4.2/src/call_script.h0000644000175000001440000001475611127714051013363 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Call scripting interface. * A call script is called by Twinkle during call processing. * Currently only when a call comes in (INVITE received). * Twinkle calls the script and based of the output of the script, the * call is further handled. * * The following environment variables are passed to the script: * @verbatim TWINKLE_USER_PROFILE= TWINKLE_TRIGGER= TWINKLE_LINE= SIPREQUEST_METHOD= SIPREQUEST_URI= SIPSTATUS_CODE= SIPSTATUS_REASON= SIP_FROM_USER= SIP_FROM_HOST= SIP_TO_USER= SIP_TO_HOST= SIP_=
@endverbatim * * The header name is in capitals and dashed are replaced by underscores * * The script can return on stdout how the call should be further * processed. The following output parameters are recognized: * @verbatim action=[continue|reject|dnd|redirect] reason=, for reject and dnd actions contact=, for redirect ation ringtone=, for continue action caller_name= display_msg= (may occur multiple times) end This parameter makes Twinkle stop waiting for the script to complete. @endverbatim * * If no action is returned, the "continue" action is performed. * Invalid output will be skipped. */ #ifndef _H_CALL_SCRIPT #define _H_CALL_SCRIPT #include #include #include #include "user.h" #include "parser/request.h" using namespace std; /** Results of the incoming call script. */ class t_script_result { public: /** Action to perform. */ enum t_action { ACTION_CONTINUE, /**< Continue with incoming call */ ACTION_REJECT, /**< Reject incoming call with 603 response */ ACTION_DND, /**< Do not disturb, send 480 response */ ACTION_REDIRECT, /**< Redirect call (302 response) */ ACTION_AUTOANSWER, /**< Auto answer incoming call */ ACTION_ERROR /**< Fail call due to error (500 response) */ }; /** @name Output parameters */ //@{ t_action action; /**< How to proceed with call */ string reason; /**< Reason if call is not continued */ string contact; /**< Redirect destination for redirect action */ string caller_name; /**< Name of caller (can be used to override display name) */ string ringtone; /**< Wav file for ring tone */ vector display_msgs; /**< Message (multi line) to show on display */ //@} /** Constructor. */ t_script_result(); /** * Convert string representation to an action. * @param action_string [in] String representation of an action. * @return The action. */ static t_action str2action(const string action_string); /** Clear the results. */ void clear(void); /** * Set output parameter from values read from the result output of a script. * @param parameter [in] Name of the parameter to set, * @param value [in] The value to set. */ void set_parameter(const string ¶meter, const string &value); }; /** Call script definition. */ class t_call_script { public: /** Trigger type. */ enum t_trigger { TRIGGER_IN_CALL, /**< Incoming call. */ TRIGGER_IN_CALL_ANSWERED, /**< Incoming call answered. */ TRIGGER_IN_CALL_FAILED, /**< Incoming call failed. */ TRIGGER_OUT_CALL, /**< Outgoing call made. */ TRIGGER_OUT_CALL_ANSWERED, /**< Outgoing call answered. */ TRIGGER_OUT_CALL_FAILED, /**< Outgoing call failed. */ TRIGGER_LOCAL_RELEASE, /**< Call released by local party. */ TRIGGER_REMOTE_RELEASE /**< Call released by remotre party. */ }; private: t_user *user_config; /**< The user profile. */ string script_command; /**< The script to execute. */ t_trigger trigger; /**< Trigger point for this script. */ /** * Number of the line associated with the call causing the trigger. * The line numbers start at 1. For some triggers a line number does not * apply, e.g. incoming call and all lines are busy. In that case the * line number is 0. */ uint16 line_number; /** * Convert a trigger type value to a string. * @param t [in] Trigger * @return String representation for the trigger. */ string trigger2str(t_trigger t) const; /** * Create environment for the process running the script. * The environment contains the header values of a SIP message. * @param m [in] The SIP message. * @return The environment. * @note This function creates the env array without registering * the memory allocation to MEMMAN. */ char **create_env(t_sip_message *m) const; /** * Create script command argument list. * @return The argument list. * @note This function creates the argv array without registering * the memory allocation to MEMMAN. */ char **create_argv(void) const; protected: /** Cannot use this constructor. */ t_call_script() {}; public: /** * Constructor. * @param _user_config [in] User profile associated with the trigger. * @param _trigger [in] The trigger type. * @param _line_number [in] Line associated with the trigger (0 if no line * is associated). */ t_call_script(t_user *_user_config, t_trigger _trigger, uint16 _line_number); /** * Execute call script resulting in an action. * @param result [out] Contains the result on return. * @param m [in] The SIP message triggering this call script. */ void exec_action(t_script_result &result, t_sip_message *m) const; /** * Execute notification call script. * @param m [in] The SIP message triggering this call script. */ void exec_notify(t_sip_message *m) const; }; #endif twinkle-1.4.2/src/phone.cpp0000644000175000001440000026076211146341146012532 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "call_history.h" #include "call_script.h" #include "exceptions.h" #include "phone.h" #include "line.h" #include "log.h" #include "sdp/sdp.h" #include "translator.h" #include "util.h" #include "user.h" #include "userintf.h" #include "audits/memman.h" #include "parser/parse_ctrl.h" #include "sockets/socket.h" #include "stun/stun_transaction.h" extern t_phone *phone; extern t_event_queue *evq_timekeeper; extern string user_host; // t_transfer_data t_transfer_data::t_transfer_data(t_request *r, unsigned short _lineno, bool _hide_user, t_phone_user *pu) : refer_request(dynamic_cast(r->copy())), lineno(_lineno), hide_user(_hide_user), phone_user(pu) {} t_transfer_data::~t_transfer_data() { MEMMAN_DELETE(refer_request); delete refer_request; } t_request *t_transfer_data::get_refer_request(void) const { return refer_request; } bool t_transfer_data::get_hide_user(void) const { return hide_user; } unsigned short t_transfer_data::get_lineno(void) const { return lineno; } t_phone_user *t_transfer_data::get_phone_user(void) const { return phone_user; } // t_phone /////////// // Private /////////// void t_phone::move_line_to_background(unsigned short lineno) { // The line will be released in the background. It should // immediately release its RTP ports as these maybe needed // for new calls. lines.at(lineno)->kill_rtp(); cleanup_3way_state(lineno); // Move the line to the back of the vector. lines.push_back(lines.at(lineno)); lines.back()->line_number = lines.size() - 1; // Create a new line for making calls. lines.at(lineno) = new t_line(this, lineno); MEMMAN_NEW(lines.at(lineno)); // The new line must have the same RTP port as the // releasing line, otherwise it may conflict with // the other lines. Due to call transfers, the port // number may be unrelated to the line position. lines.at(lineno)->rtp_port = lines.back()->get_rtp_port(); log_file->write_header("t_phone::move_line_to_background", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Moved line "); log_file->write_raw(lineno + 1); log_file->write_raw(" to background position "); log_file->write_raw(lines.back()->get_line_number() + 1); log_file->write_endl(); log_file->write_footer(); // Notify the user interface of the line state change ui->cb_line_state_changed(); } void t_phone::cleanup_dead_lines(void) { // Only remove idle lines at the end of the dead pool to avoid // moving lines in the vector. while (lines.size() > NUM_CALL_LINES && lines.back()->get_state() == LS_IDLE) { log_file->write_header("t_phone::cleanup_dead_lines", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Removed dead line "); log_file->write_raw(lines.back()->get_line_number() + 1); log_file->write_endl(); log_file->write_footer(); MEMMAN_DELETE(lines.back()); delete lines.back(); lines.pop_back(); } } void t_phone::move_releasing_lines_to_background(void) { // NOTE: the line on the REFERRER position is not moved to the // background as a subscription may still be active. for (int i = 0; i < NUM_USER_LINES; i++) { if (lines.at(i)->get_substate() == LSSUB_RELEASING && !lines.at(i)->get_keep_seized()) { move_line_to_background(i); } } } void t_phone::cleanup_3way_state(unsigned short lineno) { assert(lineno < lines.size()); lock(); // Clean up 3-way data if the line was involved in a 3-way if (is_3way) { bool line_in_3way = false; t_audio_session *as_peer; t_line *line_peer; if (lineno == line1_3way->get_line_number()) { line_in_3way = true; line_peer = line2_3way; } else if (lineno == line2_3way->get_line_number()) { line_in_3way = true; line_peer = line1_3way; } if (line_in_3way) { // Stop the 3-way mixing on the peer line as_peer = line_peer->get_audio_session(); if (as_peer) as_peer->stop_3way(); // Make the peer line the active line set_active_line(line_peer->get_line_number()); // If the 3-way was with mixed codec sample rates, then // the remaining audio session might have a mismatch // between the sound card sample rate and the codec // sample rate. In that case clear the sample rate by // toggling the audio session off and on. if (!as_peer->matching_sample_rates()) { log_file->write_report( "Hold/retrieve call to align codec and sound card.", "t_phone::line_cleared", LOG_NORMAL, LOG_DEBUG); line_peer->hold(true); line_peer->retrieve(); } is_3way = false; line1_3way = NULL; line2_3way = NULL; ui->cb_line_state_changed(); } } unlock(); } void t_phone::cleanup_3way(void) { if (!is_3way) return; if (line1_3way->get_substate() == LSSUB_IDLE) { cleanup_3way_state(line1_3way->get_line_number()); } else if (line2_3way->get_substate() == LSSUB_IDLE) { cleanup_3way_state(line2_3way->get_line_number()); } } void t_phone::invite(t_phone_user *pu, const t_url &to_uri, const string &to_display, const string &subject, bool no_fork, bool anonymous) { // Ignore if active line is not idle if (lines[active_line]->get_state() != LS_IDLE) { return; } lines[active_line]->invite(pu, to_uri, to_display, subject, no_fork, anonymous); } void t_phone::answer(void) { // Ignore if active line is idle if (lines[active_line]->get_state() == LS_IDLE) return; lines[active_line]->answer(); } void t_phone::reject(void) { // Ignore if active line is idle if (lines[active_line]->get_state() == LS_IDLE) return; lines[active_line]->reject(); } void t_phone::reject(unsigned short line) { if (line > NUM_USER_LINES) return; if (lines[line]->get_state() == LS_IDLE) return; lines[line]->reject(); } void t_phone::redirect(const list &destinations, int code, string reason) { // Ignore if active line is idle if (lines[active_line]->get_state() == LS_IDLE) return; lines[active_line]->redirect(destinations, code, reason); } void t_phone::end_call(void) { // If 3-way is active then end call on both lines if (is_3way && ( active_line == line1_3way->get_line_number() || active_line == line2_3way->get_line_number())) { if (sys_config->get_hangup_both_3way()) { line1_3way->end_call(); line2_3way->end_call(); // NOTE: moving a line to the dying pool causes the // 3way line pointers to be cleared. unsigned short lineno1 = line1_3way->get_line_number(); unsigned short lineno2 = line2_3way->get_line_number(); move_line_to_background(lineno1); move_line_to_background(lineno2); } else { // Hangup the active line, and make the next // line active. int l = active_line; activate_line((l+1) % NUM_USER_LINES); lines.at(l)->end_call(); move_line_to_background(l); } return; } // Ignore if active line is idle if (lines.at(active_line)->get_state() == LS_IDLE) return; lines.at(active_line)->end_call(); move_line_to_background(active_line); } void t_phone::registration(t_phone_user *pu, t_register_type register_type, unsigned long expires) { pu->registration(register_type, false, expires); } void t_phone::options(t_phone_user *pu, const t_url &to_uri, const string &to_display) { pu->options(to_uri, to_display); } void t_phone::options(void) { lines[active_line]->options(); } bool t_phone::hold(bool rtponly) { // A line in a 3-way call cannot be held if (is_3way && ( active_line == line1_3way->get_line_number() || active_line == line2_3way->get_line_number())) { return false; } return lines[active_line]->hold(rtponly); } void t_phone::retrieve(void) { lines[active_line]->retrieve(); } void t_phone::refer(const t_url &uri, const string &display) { lines[active_line]->refer(uri, display); } void t_phone::refer(unsigned short lineno_from, unsigned short lineno_to) { // The nicest transfer is an attended transfer. An attended transfer // is only possible of the transfer target supports the 'replaces' // extension (RFC 3891). // If 'replaces' is not supported, then a transfer with consultation // is done. First hang up the consultation call, then transfer the // line. // HACK: if the call is in progress, then assume that Replaces is // supported. We don't know if it is as the call is not established // yet. An in-progress call can only be replaced if the user // deliberately allowed this (allow_transfer_consultation_inprog). if (lines.at(lineno_to)->remote_extension_supported(EXT_REPLACES)) { log_file->write_report("Remote end supports 'replaces'.\n"\ "Attended transfer.", "t_phone::refer"); refer_attended(lineno_from, lineno_to); } else if (get_line_substate(lineno_to) == LSSUB_OUTGOING_PROGRESS) { log_file->write_report("Call transfer while consultation in progress.\n"\ "Attended transfer.", "t_phone::refer"); refer_attended(lineno_from, lineno_to); } else { log_file->write_report("Remote end does not support 'replaces'.\n"\ "Transfer with consultation.", "t_phone::refer"); refer_consultation(lineno_from, lineno_to); } } // Attended call transfer // See draft-ietf-sipping-cc-transfer-07 7.3 void t_phone::refer_attended(unsigned short lineno_from, unsigned short lineno_to) { t_line *line = lines.at(lineno_to); switch (line->get_substate()) { case LSSUB_ESTABLISHED: // Transfer allowed break; case LSSUB_OUTGOING_PROGRESS: { unsigned short dummy; t_user *user_config = get_line_user(lineno_to); if (!user_config->get_allow_transfer_consultation_inprog() || !is_line_transfer_consult(lineno_to, dummy)) { // Transfer not allowed return; } } // Transfer allowed break; default: // Transfer not allowed return; }; t_user *user_config = get_line_user(lineno_from); // draft-ietf-sipping-cc-transfer-07 section 7.3 // The call must be referred to the contact URI of the far-end. // As the contact URI may not be globally routable, the AoR // may be used alternatively. t_url uri; string display; if (user_config->get_attended_refer_to_aor()) { if (line->get_substate() == LSSUB_OUTGOING_PROGRESS) { uri = line->get_remote_uri_pending(); display = line->get_remote_target_display_pending(); } else { uri = line->get_remote_uri(); display = line->get_remote_target_display(); } } else { if (line->get_substate() == LSSUB_OUTGOING_PROGRESS) { uri = line->get_remote_target_uri_pending(); display = line->get_remote_target_display_pending(); } else { uri = line->get_remote_target_uri(); display = line->get_remote_target_display(); } } // Create Replaces header for replacing the call on lineno_to t_hdr_replaces hdr_replaces; if (line->get_substate() == LSSUB_OUTGOING_PROGRESS) { hdr_replaces.set_call_id(line->get_call_id_pending()); hdr_replaces.set_from_tag(line->get_local_tag_pending()); hdr_replaces.set_to_tag(line->get_remote_tag_pending()); } else { hdr_replaces.set_call_id(line->get_call_id()); hdr_replaces.set_from_tag(line->get_local_tag()); hdr_replaces.set_to_tag(line->get_remote_tag()); } uri.add_header(hdr_replaces); // draft-ietf-sipping-cc-transfer-07 section 7.3 // If the call is referred to the AoR, then add a Require header // that requires the 'Replaces' extension, to make the correct phone // ring in case of forking. if (user_config->get_attended_refer_to_aor()) { t_hdr_require hdr_require; hdr_require.add_feature(EXT_REPLACES); uri.add_header(hdr_require); } // Transfer call lines.at(lineno_from)->refer(uri, display); } // Call transfer with consultation // See draft-ietf-sipping-cc-transfer-07 7 void t_phone::refer_consultation(unsigned short lineno_from, unsigned short lineno_to) { t_line *line = lines.at(lineno_to); if (line->get_substate() != LSSUB_ESTABLISHED) { return; } // Refer call to the URI of the far-end t_url uri = line->get_remote_uri(); string display = line->get_remote_display(); // End consultation call line->end_call(); move_line_to_background(lineno_to); // Transfer call lines.at(lineno_from)->refer(uri, display); } void t_phone::setup_consultation_call(const t_url &uri, const string &display) { unsigned short consult_line; if (!get_idle_line(consult_line)) { log_file->write_report("Cannot get idle line for consultation call.", "t_phone::setup_consultation_call"); return; } unsigned short xfer_line = active_line; t_user *user_config = get_line_user(xfer_line); t_phone_user *pu = find_phone_user(user_config->get_profile_name()); if (!pu) { log_file->write_header("t_phone::setup_consultation_call", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user_config->get_profile_name()); log_file->write_footer(); } activate_line(consult_line); string subject = TRANSLATE("Call transfer - %1"); subject = replace_first(subject, "%1", ui->format_sip_address(user_config, get_remote_display(xfer_line), get_remote_uri(xfer_line))); bool no_fork = false; if (user_config->get_allow_transfer_consultation_inprog()) { // If the configuration allows a call to be transferred // while the consultation call is still in progress, then // we send a no-fork request disposition in the INVTE // to setup the consultation call. This way we know that // the call has not been forked and it should be possible // to replace the early dialog. // // The scenario is: // A calls B // B sets up a consultation call to C (no-fork) // B sends a REFER with replaces to A // A sends an INVITE with replaces to C. // // NOTE: this is a non-standard implementation. RFC 3891 // does not allow to replace an early dialog not // setup by the UA. In this case the REFER from A to C // intends to replace the dialog from B to C, but C // did not setup the B-C dialog itself. no_fork = true; } invite(pu, uri, display, subject, no_fork, false); lines.at(consult_line)->set_is_transfer_consult(true, xfer_line); lines.at(xfer_line)->set_to_be_transferred(true, consult_line); ui->cb_consultation_call_setup(user_config, consult_line); } void t_phone::activate_line(unsigned short l) { unsigned short a = get_active_line(); if (a == l) return; // Just switch the active line if there is a conference. if (is_3way) { set_active_line(l); ui->cb_line_state_changed(); return; } // Put the current active line on hold if it has a call. // Only established calls can be put on-hold. Transient calls // should be torn down or just kept in the same transient state // when switching to the other line. if (get_line(a)->get_state() == LS_BUSY && !hold()) { // The line is busy but could not be put on-hold. Determine // what to do based on the line sub state. switch(get_line(a)->get_substate()) { case LSSUB_OUTGOING_PROGRESS: // User has outgoing call in progress on the active // line, but decided to switch line, so tear down // the call. end_call(); ui->cb_stop_call_notification(a); break; case LSSUB_INCOMING_PROGRESS: // The incoming call on the current active will stay, // just stop the ring tone. ui->cb_stop_call_notification(a); break; case LSSUB_ANSWERING: // Answering is in progress, so call cannot be put // on-hold. Tear down the call. end_call(); break; case LSSUB_RELEASING: // The releasing call on the current line will get // released. No need to take any action here. break; default: // This should not happen. log_file->write_report("ERROR: Call cannot be put on hold.", "t_phone::activate_line"); } } set_active_line(l); // Retrieve the call on the new active line unless that line // is transferring a call and the user profile indicates that // the referrer holds the call during call transfer. t_user *user_config = lines[l]->get_user(); if (get_line_refer_state(l) == REFST_NULL || (user_config && !user_config->get_referrer_hold())) { retrieve(); } // Play ring tone, if the new active line has an incoming call // in progress. if (get_line(l)->get_substate() == LSSUB_INCOMING_PROGRESS) { ui->cb_play_ringtone(l); } ui->cb_line_state_changed(); } void t_phone::send_dtmf(char digit, bool inband, bool info) { lines[active_line]->send_dtmf(digit, inband, info); } void t_phone::start_timer(t_phone_timer timer, t_phone_user *pu) { t_tmr_phone *t; t_user *user_config = pu->get_user_profile(); switch(timer) { case PTMR_NAT_KEEPALIVE: t = new t_tmr_phone(user_config->get_timer_nat_keepalive() * 1000, timer, this); MEMMAN_NEW(t); pu->id_nat_keepalive = t->get_object_id(); break; case PTMR_TCP_PING: t = new t_tmr_phone(user_config->get_timer_tcp_ping() * 1000, timer, this); MEMMAN_NEW(t); pu->id_tcp_ping = t->get_object_id(); break; default: assert(false); } evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_phone::stop_timer(t_phone_timer timer, t_phone_user *pu) { unsigned short *id; switch(timer) { case PTMR_REGISTRATION: id = &pu->id_registration; break; case PTMR_NAT_KEEPALIVE: id = &pu->id_nat_keepalive; break; case PTMR_TCP_PING: id = &pu->id_tcp_ping; break; default: assert(false); } if (*id != 0) evq_timekeeper->push_stop_timer(*id); *id = 0; } void t_phone::start_set_timer(t_phone_timer timer, long time, t_phone_user *pu) { t_tmr_phone *t; switch(timer) { case PTMR_REGISTRATION: long new_time; // Re-register before registration expires if (pu->get_last_reg_failed() || time <= RE_REGISTER_DELTA * 1000) { new_time = time; } else { new_time = time - (RE_REGISTER_DELTA * 1000); } t = new t_tmr_phone(new_time, timer, this); MEMMAN_NEW(t); pu->id_registration = t->get_object_id(); break; default: assert(false); } evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_phone::handle_response_out_of_dialog(t_response *r, t_tuid tuid, t_tid tid) { t_phone_user *pu = match_phone_user(r, tuid); if (!pu) { log_file->write_report("Response does not match any pending request.", "t_phone::handle_response_out_of_dialog"); return; } log_file->write_header("t_phone::handle_response_out_of_dialog", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Out of dialog matches phone user: "); log_file->write_raw(pu->get_user_profile()->get_profile_name()); log_file->write_endl(); log_file->write_footer(); pu->handle_response_out_of_dialog(r, tuid, tid); } void t_phone::handle_response_out_of_dialog(StunMessage *r, t_tuid tuid) { t_phone_user *pu = match_phone_user(r, tuid); if (!pu) { log_file->write_report("STUN response does not match any pending request.", "t_phone::handle_response_out_of_dialog"); return; } pu->handle_response_out_of_dialog(r, tuid); } t_phone_user *t_phone::find_phone_user(const string &profile_name) const { for (list::const_iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if (!(*i)->is_active()) continue; t_user *user_config = (*i)->get_user_profile(); if (user_config->get_profile_name() == profile_name) { return *i; } } return NULL; } t_phone_user *t_phone::find_phone_user(const t_url &user_uri) const { for (list::const_iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if (!(*i)->is_active()) continue; t_user *user_config = (*i)->get_user_profile(); if (t_url(user_config->create_user_uri(false)) == user_uri) { return *i; } } return NULL; } t_phone_user *t_phone::match_phone_user(t_response *r, t_tuid tuid, bool active_only) { for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if (active_only && !(*i)->is_active()) continue; if ((*i)->match(r, tuid)) return *i; } return NULL; } t_phone_user *t_phone::match_phone_user(t_request *r, bool active_only) { for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if (active_only && !(*i)->is_active()) continue; if ((*i)->match(r)) return *i; } return NULL; } t_phone_user *t_phone::match_phone_user(StunMessage *r, t_tuid tuid, bool active_only) { for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if (active_only && !(*i)->is_active()) continue; if ((*i)->match(r, tuid)) return *i; } return NULL; } int t_phone::hunt_line(void) { // Send incoming call to active line if it is idle. if (lines.at(active_line)->get_substate() == LSSUB_IDLE) { return active_line; } if (sys_config->get_call_waiting() || all_lines_idle()) { // Send the INVITE to the first idle unseized line for (unsigned short i = 0; i < NUM_USER_LINES; i++) { if (lines[i]->get_substate() == LSSUB_IDLE) { return i; } } } return -1; } ////////////// // Protected ////////////// void t_phone::recvd_provisional(t_response *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_provisional(r, tuid, tid); return; } } // out-of-dialog response // Provisional responses should only be given for INVITE. // A response for an INVITE is always in a dialog. // Ignore provisional responses for other requests. } void t_phone::recvd_success(t_response *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_success(r, tuid, tid); return; } } // out-of-dialog responses handle_response_out_of_dialog(r, tuid, tid); } void t_phone::recvd_redirect(t_response *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_redirect(r, tuid, tid); return; } } // out-of-dialog responses handle_response_out_of_dialog(r, tuid, tid); } void t_phone::recvd_client_error(t_response *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_client_error(r, tuid, tid); return; } } // out-of-dialog responses handle_response_out_of_dialog(r, tuid, tid); } void t_phone::recvd_server_error(t_response *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_server_error(r, tuid, tid); return; } } // out-of-dialog responses handle_response_out_of_dialog(r, tuid, tid); } void t_phone::recvd_global_error(t_response *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_global_error(r, tuid, tid); return; } } // out-of-dialog responses handle_response_out_of_dialog(r, tuid, tid); } void t_phone::post_process_response(t_response *r, t_tuid tuid, t_tid tid) { cleanup_dead_lines(); move_releasing_lines_to_background(); cleanup_3way(); } void t_phone::recvd_invite(t_request *r, t_tid tid) { // Check if this INVITE is a retransmission. // Once the TU sent a 2XX repsonse on an INVITE it has to deal // with retransmissions. for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->is_invite_retrans(r)) { lines[i]->process_invite_retrans(); return; } } // RFC 3261 12.2.2 // An INVITE with a To-header without a tag is an initial // INVITE if (r->hdr_to.tag == "") { recvd_initial_invite(r, tid); } else { recvd_re_invite(r, tid); } } void t_phone::recvd_initial_invite(t_request *r, t_tid tid) { t_response *resp; list unsupported; t_call_record call_record; // Find out for which user this INVITE is. t_phone_user *pu = match_phone_user(r, true); if (!pu) { resp = r->create_response(R_404_NOT_FOUND); send_response(resp, 0, tid); // Do not create a call history record as this is a misrouted // call. MEMMAN_DELETE(resp); delete resp; return; } // Reject call if phone is not active if (!is_active) { resp = r->create_response(R_480_TEMP_NOT_AVAILABLE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } t_user *user_config = pu->get_user_profile(); // Check if the far end requires any unsupported extensions if (!user_config->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); // Do not create a call history record here. The far-end // should retry the call without the extension, so this // is not a missed call from the user point of view. MEMMAN_DELETE(resp); delete resp; return; } // RFC 3891 3 // If a replaces header is present, check if it matches a dialog int replace_line = -1; if (r->hdr_replaces.is_populated() && user_config->get_ext_replaces()) { bool early_matched = false; bool no_fork_req_disposition = r->hdr_request_disposition.is_populated() && r->hdr_request_disposition.fork_directive == t_hdr_request_disposition::NO_FORK; for (size_t i = 0; i < lines.size(); i++) { if (lines.at(i)->match_replaces(r->hdr_replaces.call_id, r->hdr_replaces.to_tag, r->hdr_replaces.from_tag, no_fork_req_disposition, early_matched)) { replace_line = i; break; } } if (replace_line >= NUM_CALL_LINES) { // Replaces header matches a releasing line. resp = r->create_response(R_603_DECLINE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } else if (replace_line >= 0) { if (replace_line == active_line) { if (r->hdr_replaces.early_only && !early_matched) { resp = r->create_response(R_486_BUSY_HERE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } // The existing call will be torn down only after // it has been checked that this incoming INVITE // is not rejected by the user, e.g. DND. } else { // Implementation decision: // Don't allow a held call to be replaced. resp = r->create_response(R_486_BUSY_HERE); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); MEMMAN_DELETE(resp); delete resp; return; } } else { // Replaces does not match any line. resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } } // Hunt for an idle line to handle the call. int hunted_line = -1; if (replace_line >= 0) { hunted_line = replace_line; } else { hunted_line = hunt_line(); } t_display_url display_url; list cf_dest; // call forwarding destinations // Call user defineable incoming call script to determine how // to handle this call t_script_result script_result; if (!user_config->get_script_incoming_call().empty()) { // Send 100 Trying as the script might take a while resp = r->create_response(R_100_TRYING); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; t_call_script script(user_config, t_call_script::TRIGGER_IN_CALL, hunted_line + 1); script.exec_action(script_result, r); if (!script_result.display_msgs.empty()) { string text(join_strings(script_result.display_msgs, "\n")); ui->cb_display_msg(text, MSG_NO_PRIO); } // Override display name with caller name returned by script if (!script_result.caller_name.empty()) { r->hdr_from.display_override = script_result.caller_name; log_file->write_header("t_phone::recvd_invite", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Override display name with caller name:\n"); log_file->write_raw(script_result.caller_name); log_file->write_endl(); log_file->write_footer(); } } t_call_script script_in_call_failed(user_config, t_call_script::TRIGGER_IN_CALL_FAILED, 0); // Lookup address in address book. if (script_result.caller_name.empty() && sys_config->get_ab_lookup_name() && (sys_config->get_ab_override_display() || r->hdr_from.display.empty())) { // Send 100 Trying as name lookup might take a while resp = r->create_response(R_100_TRYING); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; string name = ui->get_name_from_abook(user_config, r->hdr_from.uri); if (!name.empty()) { r->hdr_from.display_override = name; log_file->write_header("t_phone::recvd_invite", LOG_NORMAL, LOG_DEBUG); log_file->write_raw( "Override display name with address book name:\n"); log_file->write_raw(name); log_file->write_endl(); log_file->write_footer(); } } // Perform the action in the script_result. // NOTE: the default action is "continue" switch (script_result.action) { case t_script_result::ACTION_CONTINUE: // Continue with call break; case t_script_result::ACTION_AUTOANSWER: log_file->write_report("Incoming call script action: autoanswer", "t_phone::recvd_invite"); break; case t_script_result::ACTION_REJECT: log_file->write_report("Incoming call script action: reject", "t_phone::recvd_invite"); resp = r->create_response(R_603_DECLINE, script_result.reason); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; break; case t_script_result::ACTION_DND: log_file->write_report("Incoming call script action: dnd", "t_phone::recvd_invite"); resp = r->create_response(R_480_TEMP_NOT_AVAILABLE, script_result.reason); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; break; case t_script_result::ACTION_REDIRECT: log_file->write_report("Incoming call script action: redirect", "t_phone::recvd_invite"); ui->expand_destination(user_config, script_result.contact, display_url); if (display_url.is_valid()) { cf_dest.clear(); cf_dest.push_back(display_url); resp = r->create_response(R_302_MOVED_TEMPORARILY); resp->hdr_contact.set_contacts(cf_dest); } else { log_file->write_report("Invalid redirect contact", "t_phone::recvd_invite", LOG_NORMAL, LOG_WARNING); resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); } send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; break; default: log_file->write_report("Error in incoming call script", "t_phone::recvd_invite", LOG_NORMAL, LOG_WARNING); resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; break; } // Call forwarding always // NOTE: if a call script returned the autoanswer action, then // call forwarding should be bypassed if (pu->service->get_cf_active(CF_ALWAYS, cf_dest) && script_result.action == t_script_result::ACTION_CONTINUE) { log_file->write_report("Call redirection unconditional", "t_phone::recvd_invite"); resp = r->create_response(R_302_MOVED_TEMPORARILY); resp->hdr_contact.set_contacts(cf_dest); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; } // Do not disturb // RFC 3261 21.4.18 // NOTE: if a call script returned the autoanswer action, then // do not disturb should be bypassed if (pu->service->is_dnd_active() && script_result.action == t_script_result::ACTION_CONTINUE) { log_file->write_report("Do not disturb", "t_phone::recvd_invite"); resp = r->create_response(R_480_TEMP_NOT_AVAILABLE); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; } // RFC 3891 bool auto_answer_replace_call = false; if (replace_line >= 0) { // This call replaces an existing call. Tear down this existing // call. This will clear the active line. log_file->write_report("End call due to Replaces header.", "t_phone::recvd_initial_invite"); if (lines.at(replace_line)->get_substate() == LSSUB_INCOMING_PROGRESS) { ui->cb_stop_call_notification(replace_line); lines.at(replace_line)->reject(); } else { lines.at(replace_line)->end_call(); auto_answer_replace_call = true; } move_line_to_background(replace_line); } // Auto answer if (hunted_line == active_line) { // Auto-answer is only applicable to the active line. if (replace_line >= 0 && auto_answer_replace_call) { // RFC 3891 // This call replaces an existing established call, answer immediate. lines.at(active_line)->set_auto_answer(true); } else if (pu->service->is_auto_answer_active() || script_result.action == t_script_result::ACTION_AUTOANSWER) { // Auto answer log_file->write_report("Auto answer", "t_phone::recvd_invite"); lines.at(active_line)->set_auto_answer(true); } } // Send INVITE to hunted line if (hunted_line >= 0) { lines.at(hunted_line)->recvd_invite(pu, r, tid, script_result.ringtone); return; } // The phone is busy // Call forwarding busy if (pu->service->get_cf_active(CF_BUSY, cf_dest)) { log_file->write_report("Call redirection busy", "t_phone::recvd_invite"); resp = r->create_response(R_302_MOVED_TEMPORARILY); resp->hdr_contact.set_contacts(cf_dest); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; return; } // Send busy response resp = r->create_response(R_486_BUSY_HERE); send_response(resp, 0, tid); // Create a call history record call_record.start_call(r, t_call_record::DIR_IN, user_config->get_profile_name()); call_record.fail_call(resp); call_history->add_call_record(call_record); // Trigger call script script_in_call_failed.exec_notify(resp); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_re_invite(t_request *r, t_tid tid) { t_response *resp; list unsupported; // RFC 3261 12.2.2 // A To-header with a tag is a mid-dialog request. // Find a line that matches the request for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { t_phone_user *pu = lines[i]->get_phone_user(); assert(pu); t_user *user_config = pu->get_user_profile(); // Check if the far end requires any unsupported extensions if (!user_config->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } lines[i]->recvd_invite(pu, r, tid, ""); return; } } // No dialog matches with the request. resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_ack(t_request *r, t_tid tid) { t_response *resp; for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { lines[i]->recvd_ack(r, tid); return; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid) { t_response *resp; for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match_cancel(r, target_tid)) { lines[i]->recvd_cancel(r, cancel_tid, target_tid); return; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, cancel_tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_bye(t_request *r, t_tid tid) { t_response *resp; list unsupported; for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { t_user *user_config = lines[i]->get_user(); assert(user_config); if (!user_config->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } lines[i]->recvd_bye(r, tid); return; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_options(t_request *r, t_tid tid) { t_response *resp; if (r->hdr_to.tag =="") { // Out-of-dialog OPTIONS t_phone_user *pu = find_phone_user_out_dialog_request(r, tid); if (pu) { resp = pu->create_options_response(r); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } } else { // In-dialog OPTIONS t_line *l = find_line_in_dialog_request(r, tid); if (l) { l->recvd_options(r, tid); } } } t_phone_user *t_phone::find_phone_user_out_dialog_request(t_request *r, t_tid tid) { t_response *resp; list unsupported; // Find out for which user this request is. t_phone_user *pu = match_phone_user(r, true); if (!pu) { resp = r->create_response(R_404_NOT_FOUND); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return NULL; } // Check if the far end requires any unsupported extensions if (!pu->get_user_profile()->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return NULL; } return pu; } t_line *t_phone::find_line_in_dialog_request(t_request *r, t_tid tid) { t_response *resp; list unsupported; // RFC 3261 12.2.2 // A To-header with a tag is a mid-dialog request. // No dialog matches with the request. for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { t_user *user_config = lines[i]->get_user(); assert(user_config); // Check if the far end requires any unsupported extensions if (!user_config->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return NULL; } return lines[i]; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return NULL; } void t_phone::recvd_register(t_request *r, t_tid tid) { // The softphone is not a registrar. t_response *resp = r->create_response(R_403_FORBIDDEN); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; // TEST ONLY: code for testing a 423 Interval Too Brief /* if (r->hdr_contact.contact_list.front().get_expires() < 30) { t_response *resp = r->create_response( R_423_INTERVAL_TOO_BRIEF); resp->hdr_min_expires.set_time(30); send_response(resp, 0, tid); delete resp; return; } // Code for testing a 200 OK response (register) t_response *resp = r->create_response(R_200_OK); resp->hdr_contact.set_contacts(r->hdr_contact.contact_list); resp->hdr_contact.contact_list.front().set_expires(30); resp->hdr_date.set_now(); send_response(resp, 0, tid); delete resp; // Code for testing 200 OK response (de-register) t_response *resp = r->create_response(R_200_OK); send_response(resp, 0, tid); delete resp; // Code for testing 200 OK response (query) t_response *resp = r->create_response(R_200_OK); t_contact_param contact; contact.uri.set_url("sip:aap@xs4all.nl"); resp->hdr_contact.add_contact(contact); contact.uri.set_url("sip:noot@xs4all.nl"); resp->hdr_contact.add_contact(contact); send_response(resp, 0, tid); delete resp; // Code for testing a 401 response (register) if (r->hdr_authorization.is_populated() && r->hdr_authorization.credentials_list.front().digest_response. nonce == "0123456789abcdef") { t_response *resp = r->create_response(R_200_OK); resp->hdr_contact.set_contacts(r->hdr_contact.contact_list); resp->hdr_contact.contact_list.front().set_expires(30); resp->hdr_date.set_now(); send_response(resp, 0, tid); delete resp; } else { t_response *resp = r->create_response(R_401_UNAUTHORIZED); t_challenge c; c.auth_scheme = AUTH_DIGEST; c.digest_challenge.realm = "mtel.nl"; if (r->hdr_authorization.is_populated()) { c.digest_challenge.nonce = "0123456789abcdef"; c.digest_challenge.stale = true; } else { c.digest_challenge.nonce = "aaaaaa0123456789"; } c.digest_challenge.opaque = "secret"; c.digest_challenge.algorithm = ALG_MD5; // c.digest_challenge.qop_options.push_back(QOP_AUTH); // c.digest_challenge.qop_options.push_back(QOP_AUTH_INT); resp->hdr_www_authenticate.set_challenge(c); send_response(resp, 0, tid); } */ } void t_phone::recvd_prack(t_request *r, t_tid tid) { t_response *resp; for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { lines[i]->recvd_prack(r, tid); return; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_subscribe(t_request *r, t_tid tid) { t_response *resp; if (r->hdr_event.event_type != SIP_EVENT_REFER) { // Non-supported event type resp = r->create_response(R_489_BAD_EVENT); resp->hdr_allow_events.add_event_type(SIP_EVENT_REFER); send_response(resp, 0 ,tid); MEMMAN_DELETE(resp); delete resp; return; } for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { lines[i]->recvd_subscribe(r, tid); return; } } if (r->hdr_to.tag == "") { // A REFER outside a dialog is not allowed by Twinkle if (r->hdr_event.event_type == SIP_EVENT_REFER) { // RFC 3515 2.4.4 resp = r->create_response(R_403_FORBIDDEN); send_response(resp, 0 ,tid); MEMMAN_DELETE(resp); delete resp; return; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_notify(t_request *r, t_tid tid) { t_response *resp; t_phone_user *pu; // Check support for the notified event if (!SIP_EVENT_SUPPORTED(r->hdr_event.event_type)) { // Non-supported event type resp = r->create_response(R_489_BAD_EVENT); ADD_SUPPORTED_SIP_EVENTS(resp->hdr_allow_events); send_response(resp, 0 ,tid); MEMMAN_DELETE(resp); delete resp; return; } // MWI or presence notification if (r->hdr_event.event_type == SIP_EVENT_MSG_SUMMARY || r->hdr_event.event_type == SIP_EVENT_PRESENCE) { pu = match_phone_user(r, true); if (pu) { pu->recvd_notify(r, tid); } else { resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0 ,tid); MEMMAN_DELETE(resp); delete resp; } return; } // REFER notification for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { lines[i]->recvd_notify(r, tid); if (lines[i]->get_refer_state() == REFST_NULL) { // Refer subscription has finished. log_file->write_report("Refer subscription terminated.", "t_phone::recvd_notify"); if (lines[i]->get_substate() == LSSUB_RELEASING || lines[i]->get_substate() == LSSUB_IDLE) { // The line is (being) cleared already. So this // NOTIFY signals the end of the refer subscription // attached to this line. cleanup_dead_lines(); return; } else if (lines[i]->is_refer_succeeded()) { log_file->write_report( "Refer succeeded. End call with referee,", "t_phone::recvd_notify"); lines[i]->end_call(); } else { log_file->write_report("Refer failed.", "t_phone::recvd_notify"); t_user *user_config = lines[i]->get_user(); assert(user_config); if (user_config->get_referrer_hold() && lines[i]->get_is_on_hold()) { // Retrieve the call if the line is active. if (i == active_line) { log_file->write_report( "Retrieve call with referee.", "t_phone::recvd_notify"); lines[i]->retrieve(); } } } } return; } } if (r->hdr_to.tag == "") { // NOTIFY outside a dialog is not allowed. resp = r->create_response(R_403_FORBIDDEN); send_response(resp, 0 ,tid); MEMMAN_DELETE(resp); delete resp; return; } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_refer(t_request *r, t_tid tid) { t_response *resp; for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { t_phone_user *pu = lines[i]->get_phone_user(); assert(pu); t_user *user_config = pu->get_user_profile(); list unsupported; if (!user_config->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } // Reject if a 3-way call is established. if (is_3way) { log_file->write_report("3-way call active. Reject REFER.", "t_phone::recvd_refer"); resp = r->create_response(R_603_DECLINE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } // Reject if the line is on-hold. if (is_3way || lines[i]->get_is_on_hold()) { log_file->write_report("Line is on-hold. Reject REFER.", "t_phone::recvd_refer"); resp = r->create_response(R_603_DECLINE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } // Check if a refer is already in progress if (i == LINENO_REFERRER || lines[LINENO_REFERRER]->get_state() != LS_IDLE || incoming_refer_data != NULL) { log_file->write_report( "A REFER is still in progress. Reject REFER.", "t_phone::recvd_refer"); resp = r->create_response(R_603_DECLINE); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } if (!lines[i]->recvd_refer(r, tid)) { // Refer has been rejected. log_file->write_report("Incoming REFER rejected.", "t_phone::recvd_refer"); return; } // Make sure the line stays seized if the far-end ends the // call, so a line will be available if the user gives permission // for the call transfer. lines[i]->set_keep_seized(true); incoming_refer_data = new t_transfer_data(r, i, lines[i]->get_hide_user(), pu); MEMMAN_NEW(incoming_refer_data); return; } } if (r->hdr_to.tag == "") { // Twinkle does not allow a REFER outside a dialog. resp = r->create_response(R_403_FORBIDDEN); send_response(resp, 0 ,tid); MEMMAN_DELETE(resp); delete resp; return; } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_refer_permission(bool permission) { if (!incoming_refer_data) { // This should not happen log_file->write_report("Incoming REFER data is gone.", "t_phone::recvd_refer_permission", LOG_NORMAL, LOG_WARNING); return; } unsigned short i = incoming_refer_data->get_lineno(); t_request *r = incoming_refer_data->get_refer_request(); bool hide_user = incoming_refer_data->get_hide_user(); t_phone_user *pu = incoming_refer_data->get_phone_user(); t_user *user_config = pu->get_user_profile(); lines[i]->recvd_refer_permission(permission, r); if (!permission) { log_file->write_report("Incoming REFER rejected.", "t_phone::recvd_refer_permission"); lines[i]->set_keep_seized(false); move_releasing_lines_to_background(); MEMMAN_DELETE(incoming_refer_data); delete incoming_refer_data; incoming_refer_data = NULL; return; } else { log_file->write_report("Incoming REFER allowed.", "t_phone::recvd_refer_permission"); } if (lines[i]->get_substate() == LSSUB_ESTABLISHED) { // Put line on-hold and place it in the referrer line log_file->write_report( "Hold call before calling the refer-target.", "t_phone::recvd_refer_permission"); if (user_config->get_referee_hold()) { lines[i]->hold(); } else { // The user profile indicates that the line should // not be put on-hold, i.e. do not send re-INVITE. // So only stop RTP. lines[i]->hold(true); } } // Move the original line to the REFERRER line (the line may be idle // already). t_line *l = lines[i]; lines[i] = lines[LINENO_REFERRER]; lines[i]->line_number = i; lines[LINENO_REFERRER] = l; lines[LINENO_REFERRER]->line_number = LINENO_REFERRER; lines[LINENO_REFERRER]->set_keep_seized(false); ui->cb_line_state_changed(); // Setup call to the Refer-To destination log_file->write_report("Call refer-target.", "t_phone::recvd_refer_permission"); t_hdr_replaces hdr_replaces; t_hdr_require hdr_require; // Analyze headers in Refer-To URI. // For an attended call transfer the Refer-To URI // will contain a Replaces header and possibly a Require // header. Other headers are ignored for now. // See draft-ietf-sipping-cc-transfer-07 7.3 if (!r->hdr_refer_to.uri.get_headers().empty()) { try { list parse_errors; t_sip_message *m = t_parser::parse_headers( r->hdr_refer_to.uri.get_headers(), parse_errors); hdr_replaces = m->hdr_replaces; hdr_require = m->hdr_require; MEMMAN_DELETE(m); delete m; } catch (int) { log_file->write_header("t_phone::recvd_refer_permission", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Cannot parse headers in Refer-To URI\n"); log_file->write_raw(r->hdr_refer_to.uri.encode()); log_file->write_endl(); log_file->write_footer(); } } ui->cb_call_referred(user_config, i, r); lines[i]->invite(pu, r->hdr_refer_to.uri.copy_without_headers(), r->hdr_refer_to.display, "", r->hdr_referred_by, hdr_replaces, hdr_require, t_hdr_request_disposition(), hide_user); lines[i]->open_dialog->is_referred_call = true; MEMMAN_DELETE(incoming_refer_data); delete incoming_refer_data; incoming_refer_data = NULL; return; } void t_phone::recvd_info(t_request *r, t_tid tid) { t_response *resp; list unsupported; for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r)) { t_user *user_config = lines[i]->get_user(); assert(user_config); if (!user_config->check_required_ext(r, unsupported)) { // Not all required extensions are supported resp = r->create_response(R_420_BAD_EXTENSION); resp->hdr_unsupported.set_features(unsupported); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; return; } lines[i]->recvd_info(r, tid); return; } } resp = r->create_response(R_481_TRANSACTION_NOT_EXIST); send_response(resp, 0, tid); MEMMAN_DELETE(resp); delete resp; } void t_phone::recvd_message(t_request *r, t_tid tid) { if (r->hdr_to.tag =="") { // Out-of-dialog MESSAGE t_phone_user *pu = find_phone_user_out_dialog_request(r, tid); if (pu) { pu->recvd_message(r, tid); } } else { // In-dialog MESSAGE t_line *l = find_line_in_dialog_request(r, tid); if (l) { l->recvd_message(r, tid); } } } void t_phone::post_process_request(t_request *r, t_tid cancel_tid, t_tid target_tid) { cleanup_dead_lines(); move_releasing_lines_to_background(); cleanup_3way(); } void t_phone::failure(t_failure failure, t_tid tid) { // TODO } void t_phone::recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid) { for (unsigned short i = 0; i < lines.size(); i++) { if (lines[i]->match(r, tuid)) { lines[i]->recvd_stun_resp(r, tuid, tid); return; } } // out-of-dialog STUN responses handle_response_out_of_dialog(r, tuid); } void t_phone::handle_event_timeout(t_event_timeout *e) { t_timer *t = e->get_timer(); t_tmr_phone *tmr_phone; t_tmr_line *tmr_line; t_tmr_subscribe *tmr_subscribe; t_tmr_publish *tmr_publish; t_object_id line_id; lock(); switch (t->get_type()) { case TMR_PHONE: tmr_phone = dynamic_cast(t); timeout(tmr_phone->get_phone_timer(), tmr_phone->get_object_id()); break; case TMR_LINE: tmr_line = dynamic_cast(t); line_timeout(tmr_line->get_line_id(), tmr_line->get_line_timer(), tmr_line->get_dialog_id()); break; case TMR_SUBSCRIBE: tmr_subscribe = dynamic_cast(t); line_id = tmr_subscribe->get_line_id(); if (line_id == 0) { subscription_timeout(tmr_subscribe->get_subscribe_timer(), tmr_subscribe->get_object_id()); } else { line_timeout_sub(line_id, tmr_subscribe->get_subscribe_timer(), tmr_subscribe->get_dialog_id(), tmr_subscribe->get_sub_event_type(), tmr_subscribe->get_sub_event_id()); } break; case TMR_PUBLISH: tmr_publish = dynamic_cast(t); publication_timeout(tmr_publish->get_publish_timer(), tmr_publish->get_object_id()); break; default: assert(false); break; } unlock(); } void t_phone::line_timeout(t_object_id id, t_line_timer timer, t_object_id did) { // If there is no line with id anymore, then the timer expires // silently. t_line *line = get_line_by_id(id); if (line) { line->timeout(timer, did); } } void t_phone::line_timeout_sub(t_object_id id, t_subscribe_timer timer, t_object_id did, const string &event_type, const string &event_id) { // If there is no line with id anymore, then the timer expires // silently. t_line *line = get_line_by_id(id); if (line) { line->timeout_sub(timer, did, event_type, event_id); } } void t_phone::subscription_timeout(t_subscribe_timer timer, t_object_id id_timer) { for (list::iterator i = phone_users.begin(); i != phone_users.end(); i++) { if ((*i)->match_subscribe_timer(timer, id_timer)) { (*i)->timeout_sub(timer, id_timer); } } } void t_phone::publication_timeout(t_publish_timer timer, t_object_id id_timer) { for (list::iterator i = phone_users.begin(); i != phone_users.end(); i++) { if ((*i)->match_publish_timer(timer, id_timer)) { (*i)->timeout_publish(timer, id_timer); } } } void t_phone::timeout(t_phone_timer timer, unsigned short id_timer) { lock(); switch (timer) { case PTMR_REGISTRATION: for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if ((*i)->id_registration == id_timer) { (*i)->timeout(timer); } } break; case PTMR_NAT_KEEPALIVE: for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if ((*i)->id_nat_keepalive == id_timer) { (*i)->timeout(timer); } } break; case PTMR_TCP_PING: for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if ((*i)->id_tcp_ping == id_timer) { (*i)->timeout(timer); } } break; default: assert(false); } unlock(); } void t_phone::handle_broken_connection(t_event_broken_connection *e) { // Find the phone user that was associated with the connection. // This phone user has to handle the event. t_phone_user *pu = find_phone_user(e->get_user_uri()); if (pu) { pu->handle_broken_connection(); } else { log_file->write_header("t_phone::handle_broken_connection", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Cannot find active phone user "); log_file->write_raw(e->get_user_uri().encode()); log_file->write_endl(); log_file->write_footer(); } } /////////// // Public /////////// t_phone::t_phone() : t_transaction_layer(), lines(NUM_CALL_LINES) { is_active = true; active_line = 0; // Create phone lines for (unsigned short i = 0; i < NUM_CALL_LINES; i++) { lines[i] = new t_line(this, i); MEMMAN_NEW(lines[i]); } // Initialize 3-way conference data is_3way = false; line1_3way = NULL; line2_3way = NULL; incoming_refer_data = NULL; struct timeval t; gettimeofday(&t, NULL); startup_time = t.tv_sec; // NOTE: The RTP ports for the lines are initialized after the // system settings have been read. } t_phone::~t_phone() { // Delete phone lines log_file->write_header("t_phone::~t_phone"); log_file->write_raw("Number of lines to cleanup: "); log_file->write_raw(lines.size()); log_file->write_endl(); log_file->write_footer(); if (incoming_refer_data) { MEMMAN_DELETE(incoming_refer_data); delete incoming_refer_data; } for (unsigned short i = 0; i < lines.size(); i++) { MEMMAN_DELETE(lines[i]); delete lines[i]; } // Delete all phone users for (list::iterator i = phone_users.begin(); i != phone_users.end(); i++) { MEMMAN_DELETE(*i); delete *i; } } void t_phone::pub_invite(t_user *user, const t_url &to_uri, const string &to_display, const string &subject, bool anonymous) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { invite(pu, to_uri, to_display, subject, false, anonymous); } else { log_file->write_header("t_phone::pub_invite", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_answer(void) { lock(); answer(); unlock(); } void t_phone::pub_reject(void) { lock(); reject(); unlock(); } void t_phone::pub_reject(unsigned short line) { lock(); reject(line); unlock(); } void t_phone::pub_redirect(const list &destinations, int code, string reason) { lock(); redirect(destinations, code, reason); unlock(); } void t_phone::pub_end_call(void) { lock(); end_call(); unlock(); } void t_phone::pub_registration(t_user *user, t_register_type register_type, unsigned long expires) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { registration(pu, register_type, expires); } else { log_file->write_header("t_phone::pub_registration", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_options(t_user *user, const t_url &to_uri, const string &to_display) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { options(pu, to_uri, to_display); } else { log_file->write_header("t_phone::pub_options", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_options(void) { lock(); options(); unlock(); } bool t_phone::pub_hold(void) { lock(); bool retval = hold(); unlock(); return retval; } void t_phone::pub_retrieve(void) { lock(); retrieve(); unlock(); } void t_phone::pub_refer(const t_url &uri, const string &display) { lock(); refer(uri, display); unlock(); } void t_phone::pub_setup_consultation_call(const t_url &uri, const string &display) { lock(); setup_consultation_call(uri, display); unlock(); } void t_phone::pub_refer(unsigned short lineno_from, unsigned short lineno_to) { lock(); refer(lineno_from, lineno_to); unlock(); } void t_phone::mute(bool enable) { lock(); // In a 3-way call, both lines must be muted if (is_3way && ( active_line == line1_3way->get_line_number() || active_line == line2_3way->get_line_number())) { line1_3way->mute(enable); line2_3way->mute(enable); } else { lines[active_line]->mute(enable); } unlock(); } void t_phone::pub_activate_line(unsigned short l) { lock(); activate_line(l); unlock(); } void t_phone::pub_send_dtmf(char digit, bool inband, bool info) { lock(); send_dtmf(digit, inband, info); unlock(); } bool t_phone::pub_seize(void) { bool retval; lock(); retval = lines[active_line]->seize(); unlock(); return retval; } bool t_phone::pub_seize(unsigned short line) { assert(line < NUM_USER_LINES); bool retval; lock(); retval = lines[line]->seize(); unlock(); return retval; } void t_phone::pub_unseize(void) { lock(); lines[active_line]->unseize(); unlock(); } void t_phone::pub_unseize(unsigned short line) { assert(line < NUM_USER_LINES); lock(); lines[line]->unseize(); unlock(); } void t_phone::pub_confirm_zrtp_sas(unsigned short line) { assert(line < NUM_USER_LINES); lock(); lines[line]->confirm_zrtp_sas(); unlock(); } void t_phone::pub_confirm_zrtp_sas(void) { lock(); lines[active_line]->confirm_zrtp_sas(); unlock(); } void t_phone::pub_reset_zrtp_sas_confirmation(unsigned short line) { assert(line < NUM_USER_LINES); lock(); lines[line]->reset_zrtp_sas_confirmation(); unlock(); } void t_phone::pub_reset_zrtp_sas_confirmation(void) { lock(); lines[active_line]->reset_zrtp_sas_confirmation(); unlock(); } void t_phone::pub_enable_zrtp(void) { lock(); lines[active_line]->enable_zrtp(); unlock(); } void t_phone::pub_zrtp_request_go_clear(void) { lock(); lines[active_line]->zrtp_request_go_clear(); unlock(); } void t_phone::pub_zrtp_go_clear_ok(unsigned short line) { assert(line < NUM_USER_LINES); lock(); lines[line]->zrtp_go_clear_ok(); unlock(); } void t_phone::pub_subscribe_mwi(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { pu->subscribe_mwi(); } else { log_file->write_header("t_phone::pub_subscribe_mwi", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_unsubscribe_mwi(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { pu->unsubscribe_mwi(); } else { log_file->write_header("t_phone::pub_unsubscribe_mwi", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_subscribe_presence(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { pu->subscribe_presence(); } else { log_file->write_header("t_phone::pub_subscribe_presence", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_unsubscribe_presence(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { pu->unsubscribe_presence(); } else { log_file->write_header("t_phone::pub_unsubscribe_presence", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_publish_presence(t_user *user, t_presence_state::t_basic_state basic_state) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { pu->publish_presence(basic_state); } else { log_file->write_header("t_phone::pub_publish_presence", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } void t_phone::pub_unpublish_presence(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { pu->unpublish_presence(); } else { log_file->write_header("t_phone::pub_publish_presence", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_footer(); } unlock(); } bool t_phone::pub_send_message(t_user *user, const t_url &to_uri, const string &to_display, const t_msg &msg) { bool retval = true; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { retval = pu->send_message(to_uri, to_display, msg); } else { log_file->write_header("t_phone::pub_send_message", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_endl(); log_file->write_footer(); retval = false; } unlock(); return retval; } bool t_phone::pub_send_im_iscomposing(t_user *user, const t_url &to_uri, const string &to_display, const string &state, time_t refresh) { bool retval = true; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { retval = pu->send_im_iscomposing(to_uri, to_display, state, refresh); } else { log_file->write_header("t_phone::pub_send_im_iscomposing", LOG_NORMAL, LOG_WARNING); log_file->write_raw("User profile not active: "); log_file->write_raw(user->get_profile_name()); log_file->write_endl(); log_file->write_footer(); retval = false; } unlock(); return retval; } t_phone_state t_phone::get_state(void) const { lock(); for (unsigned short i = 0; i < NUM_USER_LINES; i++) { if (lines[i]->get_state() == LS_IDLE) { unlock(); return PS_IDLE; } } // All lines are busy, so the phone is busy. unlock(); return PS_BUSY; } bool t_phone::all_lines_idle(void) const { lock(); for (unsigned short i = 0; i < NUM_USER_LINES; i++) { if (lines[i]->get_substate() != LSSUB_IDLE) { unlock(); return false; } } // All lines are idle unlock(); return true; } bool t_phone::get_idle_line(unsigned short &lineno) const { lock(); bool found_idle_line = false; for (unsigned short i = 0; i < NUM_USER_LINES; i++) { if (lines[i]->get_substate() == LSSUB_IDLE) { lineno = i; found_idle_line = true; break; } } unlock(); return found_idle_line; } void t_phone::set_active_line(unsigned short l) { lock(); assert (l < NUM_USER_LINES); active_line = l; unlock(); } unsigned short t_phone::get_active_line(void) const { return active_line; } t_line *t_phone::get_line_by_id(t_object_id id) const { for (size_t i = 0; i < lines.size(); i++) { if (lines[i]->get_object_id() == id) { return lines[i]; } } return NULL; } t_line *t_phone::get_line(unsigned short lineno) const { assert(lineno < lines.size()); return lines[lineno]; } bool t_phone::authorize(t_user *user, t_request *r, t_response *resp) { bool result = false; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->authorize(r, resp); unlock(); return result; } void t_phone::remove_cached_credentials(t_user *user, const string &realm) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) pu->remove_cached_credentials(realm); unlock(); } bool t_phone::get_is_registered(t_user *user) { bool result = false; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->get_is_registered(); unlock(); return result; } bool t_phone::get_last_reg_failed(t_user *user) { bool result = false; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->get_last_reg_failed(); unlock(); return result; } t_line_state t_phone::get_line_state(unsigned short lineno) const { assert(lineno < lines.size()); lock(); t_line_state s = get_line(lineno)->get_state(); unlock(); return s; } t_line_substate t_phone::get_line_substate(unsigned short lineno) const { assert(lineno < lines.size()); lock(); t_line_substate s = get_line(lineno)->get_substate(); unlock(); return s; } bool t_phone::is_line_on_hold(unsigned short lineno) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->get_is_on_hold(); unlock(); return b; } bool t_phone::is_line_muted(unsigned short lineno) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->get_is_muted(); unlock(); return b; } bool t_phone::is_line_transfer_consult(unsigned short lineno, unsigned short &transfer_from_line) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->get_is_transfer_consult(transfer_from_line); unlock(); return b; } bool t_phone::line_to_be_transferred(unsigned short lineno, unsigned short &transfer_to_line) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->get_to_be_transferred(transfer_to_line); unlock(); return b; } bool t_phone::is_line_encrypted(unsigned short lineno) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->get_is_encrypted(); unlock(); return b; } bool t_phone::is_line_auto_answered(unsigned short lineno) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->get_auto_answer(); unlock(); return b; } t_refer_state t_phone::get_line_refer_state(unsigned short lineno) const { assert(lineno < lines.size()); lock(); t_refer_state s = get_line(lineno)->get_refer_state(); unlock(); return s; } t_user *t_phone::get_line_user(unsigned short lineno) { assert(lineno < lines.size()); lock(); t_user *user = get_line(lineno)->get_user(); unlock(); return user; } bool t_phone::has_line_media(unsigned short lineno) const { assert(lineno < lines.size()); lock(); bool b = get_line(lineno)->has_media(); unlock(); return b; } bool t_phone::is_mwi_subscribed(t_user *user) const { bool result = false; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->is_mwi_subscribed(); unlock(); return result; } bool t_phone::is_mwi_terminated(t_user *user) const { bool result = false; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->is_mwi_terminated(); unlock(); return result; } t_mwi t_phone::get_mwi(t_user *user) const { t_mwi result; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->mwi; unlock(); return result; } bool t_phone::is_presence_terminated(t_user *user) const { bool result = false; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) result = pu->is_presence_terminated(); unlock(); return result; } t_url t_phone::get_remote_uri(unsigned short lineno) const { assert(lineno < lines.size()); lock(); t_url uri = get_line(lineno)->get_remote_uri(); unlock(); return uri; } string t_phone::get_remote_display(unsigned short lineno) const { assert(lineno < lines.size()); lock(); string display = get_line(lineno)->get_remote_display(); unlock(); return display; } bool t_phone::part_of_3way(unsigned short lineno) { lock(); if (!is_3way) { unlock(); return false; } if (line1_3way->get_line_number() == lineno) { unlock(); return true; } if (line2_3way->get_line_number() == lineno) { unlock(); return true; } unlock(); return false; } t_line *t_phone::get_3way_peer_line(unsigned short lineno) { lock(); if (!is_3way) { unlock(); return NULL; } if (line1_3way->get_line_number() == lineno) { unlock(); return line2_3way; } unlock(); return line1_3way; } bool t_phone::join_3way(unsigned short lineno1, unsigned short lineno2) { assert(lineno1 < NUM_USER_LINES); assert(lineno2 < NUM_USER_LINES); lock(); // Check if there isn't a 3-way already if (is_3way) { unlock(); return false; } // Both lines must have a call. if (lines[lineno1]->get_substate() != LSSUB_ESTABLISHED || lines[lineno2]->get_substate() != LSSUB_ESTABLISHED) { unlock(); return false; } // One of the lines must be on-hold t_line *held_line, *talking_line; if (lines[lineno1]->get_is_on_hold()) { held_line = lines[lineno1]; talking_line = lines[lineno2]; } else if (lines[lineno2]->get_is_on_hold()) { held_line = lines[lineno2]; talking_line = lines[lineno1]; } else { unlock(); return false; } // Set 3-way data is_3way = true; line1_3way = talking_line; line2_3way = held_line; // The user may have put both lines on-hold. In this case the // talking line is on-hold too! if (talking_line->get_is_on_hold()) { // Retrieve the held call // As the 3-way indication (is_3way) is set, the audio sessions // will automatically connect to each other. talking_line->retrieve(); } else { // Start the 3-way on the talking line t_audio_session *as_talking = talking_line->get_audio_session(); if (as_talking) as_talking->start_3way(); } // Retrieve the held call held_line->retrieve(); unlock(); return true; } void t_phone::notify_refer_progress(t_response *r, unsigned short referee_lineno) { if (lines[LINENO_REFERRER]->get_state() != LS_IDLE) { lines[LINENO_REFERRER]->notify_refer_progress(r); if (!lines[LINENO_REFERRER]->active_dialog || lines[LINENO_REFERRER]->active_dialog->get_state() != DS_CONFIRMED) { // The call to the referrer has already been // terminated. return; } if (r->is_final()) { if (r->is_success()) { // Reference was successful, end the call with // with the referrer. log_file->write_header( "t_phone::notify_refer_progress"); log_file->write_raw( "Call to refer-target succeeded.\n"); log_file->write_raw( "End call with referrer.\n"); log_file->write_footer(); lines[LINENO_REFERRER]->end_call(); } else { // Reference failed, retrieve the call with the // referrer. log_file->write_header( "t_phone::notify_refer_progress"); log_file->write_raw( "Call to refer-target failed.\n"); log_file->write_raw( "Restore call with referrer.\n"); log_file->write_footer(); // Retrieve the parked line t_line *l = lines[referee_lineno]; lines[referee_lineno] = lines[LINENO_REFERRER]; lines[referee_lineno]->line_number = referee_lineno; lines[LINENO_REFERRER] = l; lines[LINENO_REFERRER]->line_number = LINENO_REFERRER; // Retrieve the call if the line is active if (referee_lineno == active_line) { log_file->write_report( "Retrieve call with referrer.", "t_phone::notify_refer_progress"); lines[referee_lineno]->retrieve(); } t_user *user_config = lines[referee_lineno]->get_user(); assert(user_config); ui->cb_retrieve_referrer(user_config, referee_lineno); } } } } t_call_info t_phone::get_call_info(unsigned short lineno) const { assert(lineno < lines.size()); lock(); t_call_info call_info = get_line(lineno)->get_call_info(); unlock(); return call_info; } t_call_record t_phone::get_call_hist(unsigned short lineno) const { assert(lineno < lines.size()); lock(); t_call_record call_hist = get_line(lineno)->call_hist_record; unlock(); return call_hist; } string t_phone::get_ringtone(unsigned short lineno) const { assert(lineno < lines.size()); lock(); string ringtone = get_line(lineno)->get_ringtone(); unlock(); return ringtone; } time_t t_phone::get_startup_time(void) const { return startup_time; } void t_phone::init_rtp_ports(void) { for (size_t i = 0; i < lines.size(); i++) { lines[i]->init_rtp_port(); } } bool t_phone::add_phone_user(const t_user &user_config, t_user **dup_user) { lock(); t_phone_user *existing_phone_user = NULL; for (list::iterator i = phone_users.begin(); i != phone_users.end(); i++) { t_user *user = (*i)->get_user_profile(); // If the profile is already added, then just activate it. if (user->get_profile_name() == user_config.get_profile_name()) { existing_phone_user = (*i); // Continue checking to see if activating this user // does not conflict with another already active user. continue; } // Check if there is already another profile for the same // user. if (user->get_name() == user_config.get_name() && user->get_domain() == user_config.get_domain() && (*i)->is_active()) { *dup_user = user; unlock(); return false; } // Check if there is already another profile having // the same contact name. if (user->get_contact_name() == user_config.get_contact_name() && USER_HOST(user, AUTO_IP4_ADDRESS) == USER_HOST(&user_config, AUTO_IP4_ADDRESS) && (*i)->is_active()) { *dup_user = user; unlock(); return false; } } // Activate existing profile if (existing_phone_user) { if (!existing_phone_user->is_active()) { existing_phone_user->activate(user_config); } unlock(); return true; } // Add the user t_phone_user *pu = new t_phone_user(user_config); MEMMAN_NEW(pu); phone_users.push_back(pu); unlock(); return true; } void t_phone::remove_phone_user(const t_user &user_config) { lock(); t_phone_user *pu = find_phone_user(user_config.get_profile_name()); if (pu) pu->deactivate(); unlock(); } list t_phone::ref_users(void) { list l; lock(); for (list::iterator i = phone_users.begin(); i != phone_users.end(); i++) { if (!(*i)->is_active()) continue; l.push_back((*i)->get_user_profile()); } unlock(); return l; } t_user *t_phone::ref_user_display_uri(const string &display_uri) { t_user *u = NULL; lock(); for (list::iterator i = phone_users.begin(); i != phone_users.end(); i++) { if (!(*i)->is_active()) continue; if ((*i)->get_user_profile()->get_display_uri() == display_uri) { u = (*i)->get_user_profile(); break; } } unlock(); return u; } t_user *t_phone::ref_user_profile(const string &profile_name) { t_user *u = NULL; lock(); t_phone_user *pu = find_phone_user(profile_name); if (pu) u = pu->get_user_profile(); unlock(); return u; } t_service *t_phone::ref_service(t_user *user) { assert(user); t_service *srv = NULL; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) srv = pu->service; unlock(); return srv; } t_buddy_list *t_phone::ref_buddy_list(t_user *user) { assert(user); t_buddy_list *l = NULL; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) l = pu->get_buddy_list(); unlock(); return l; } t_presence_epa *t_phone::ref_presence_epa(t_user *user) { assert(user); t_presence_epa *epa = NULL; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) epa = pu->get_presence_epa(); unlock(); return epa; } string t_phone::get_ip_sip(const t_user *user, const string &auto_ip) const { string result; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { result = pu->get_ip_sip(auto_ip); } else { result = LOCAL_IP; } unlock(); if (result == AUTO_IP4_ADDRESS) result = auto_ip; return result; } unsigned short t_phone::get_public_port_sip(const t_user *user) const { unsigned short result; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { result = pu->get_public_port_sip(); } else { result = sys_config->get_sip_port(); } unlock(); return result; } bool t_phone::use_stun(t_user *user) { bool result; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { result = pu->use_stun; } else { result = false; } unlock(); return result; } bool t_phone::use_nat_keepalive(t_user *user) { bool result; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { result = pu->use_nat_keepalive; } else { result = false; } unlock(); return result; } void t_phone::disable_stun(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) pu->use_stun = false; unlock(); } void t_phone::sync_nat_keepalive(t_user *user) { lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) pu->sync_nat_keepalive(); unlock(); } bool t_phone::stun_discover_nat(list &msg_list) { bool retval = true; lock(); for (list::iterator i = phone_users.begin(); i != phone_users.end(); ++i) { if (!(*i)->is_active()) continue; t_user *user_config = (*i)->get_user_profile(); if (user_config->get_sip_transport() == SIP_TRANS_UDP || user_config->get_sip_transport() == SIP_TRANS_AUTO) { if (user_config->get_use_stun()) { string msg; if (!::stun_discover_nat(*i, msg)) { string s("User profile: "); s + user_config->get_profile_name(); s += "\n\n"; s += msg; msg_list.push_back(s); retval = false; } } else { (*i)->use_nat_keepalive = user_config->get_enable_nat_keepalive(); } } } unlock(); return retval; } bool t_phone::stun_discover_nat(t_user *user, string &msg) { bool retval = true; lock(); if (user->get_sip_transport() == SIP_TRANS_UDP || user->get_sip_transport() == SIP_TRANS_AUTO) { t_phone_user *pu = find_phone_user(user->get_profile_name()); if (user->get_use_stun()) { if (pu) retval = ::stun_discover_nat(pu, msg); } else { if (pu) pu->use_nat_keepalive = user->get_enable_nat_keepalive(); } } unlock(); return retval; } t_response *t_phone::create_options_response(t_user *user, t_request *r, bool in_dialog) { t_response *resp; lock(); t_phone_user *pu = find_phone_user(user->get_profile_name()); if (pu) { resp = pu->create_options_response(r, in_dialog); } else { resp = r->create_response(R_500_INTERNAL_SERVER_ERROR); } unlock(); return resp; } void t_phone::init(void) { lock(); list user_list = ref_users(); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { // Automatic registration at startup if requested if ((*i)->get_register_at_startup()) { pub_registration(*i, REG_REGISTER, DUR_REGISTRATION(*i)); } else { // No registration will be done, so initialize extensions now. init_extensions(*i); } // NOTE: Extension initialization is done after registration. // This way STUN will have set the correct // IP adres (STUN is done as part of registration.) } unlock(); } void t_phone::init_extensions(t_user *user_config) { // Subscribe to MWI if (user_config->get_mwi_sollicited()) { pub_subscribe_mwi(user_config); } // Publish presence if (user_config->get_pres_publish_startup()) { pub_publish_presence(user_config, t_presence_state::ST_BASIC_OPEN); } // Subscribe to presence pub_subscribe_presence(user_config); } bool t_phone::set_sighandler(void) const { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = phone_sighandler; sa.sa_flags = SA_RESTART; if (sigaction (SIGCHLD, &sa, NULL) < 0) return false; if (sigaction (SIGTERM, &sa, NULL) < 0) return false; if (sigaction (SIGINT, &sa, NULL) < 0) return false; return true; } void t_phone::terminate(void) { string msg; lock(); // Clear all lines log_file->write_report("Clear all lines.", "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); for (size_t i = 0; i < NUM_CALL_LINES; i++) { switch (lines[i]->get_substate()) { case LSSUB_IDLE: case LSSUB_RELEASING: break; case LSSUB_SEIZED: lines[i]->unseize(); break; case LSSUB_INCOMING_PROGRESS: ui->cb_stop_call_notification(i); lines[i]->reject(); break; case LSSUB_OUTGOING_PROGRESS: ui->cb_stop_call_notification(i); // Fall thru case LSSUB_ANSWERING: case LSSUB_ESTABLISHED: lines[i]->end_call(); break; } } // Deactivate phone is_active = false; // De-register all registered users. list user_list = ref_users(); ui->cb_display_msg("Deregistering phone..."); for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { // Unsubscribe MWI if (is_mwi_subscribed(*i)) { msg = (*i)->get_profile_name(); msg += ": Unsubscribe MWI."; log_file->write_report(msg, "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); pub_unsubscribe_mwi(*i); } // Unpublish presence pub_unpublish_presence(*i); // Unsubscribe presence pub_unsubscribe_presence(*i); // De-register if (get_is_registered(*i)) { msg = (*i)->get_profile_name(); msg += ": Deregister."; log_file->write_report(msg, "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); pub_registration(*i, REG_DEREGISTER); } } unlock(); // Wait till phone is deregistered. for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { while (get_is_registered(*i)) { sleep(1); } msg = (*i)->get_profile_name(); msg += ": Registration terminated."; log_file->write_report(msg, "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); } // Wait for MWI unsubscription int mwi_wait = 0; for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { while (!is_mwi_terminated(*i) && mwi_wait <= DUR_UNSUBSCRIBE_GUARD/1000) { sleep(1); mwi_wait++; } msg = (*i)->get_profile_name(); msg += ": MWI subscription terminated."; log_file->write_report(msg, "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); } // Wait for presence unsubscription int presence_wait = 0; for (list::iterator i = user_list.begin(); i != user_list.end(); i++) { while (!is_presence_terminated(*i) && presence_wait <= DUR_UNSUBSCRIBE_GUARD/1000) { sleep(1); presence_wait++; } msg = (*i)->get_profile_name(); msg += ": presence subscriptions terminated."; log_file->write_report(msg, "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); } // Wait till all lines are idle log_file->write_report("Waiting for all lines to become idle.", "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); int dur = 0; while (dur < QUIT_IDLE_WAIT) { if (all_lines_idle()) break; sleep(1); dur++; } // Force lines to idle state if they could not be cleared // gracefully lock(); for (size_t i = 0; i < lines.size(); i++) { if (lines[i]->get_substate() != LSSUB_IDLE) { msg = "Force line %1 to idle state."; msg = replace_first(msg, "%1", int2str(i)); log_file->write_report(msg, "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); lines[i]->force_idle(); } } log_file->write_report("Finished phone termination.", "t_phone::terminate", LOG_NORMAL, LOG_DEBUG); unlock(); } void *phone_uas_main(void *arg) { phone->run(); return NULL; } void *phone_sigwait(void *arg) { sigset_t sigset; int sig; int child_status; pid_t pid; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGCHLD); while (true) { // When SIGCONT is received after SIGSTOP, sigwait returns // with EINTR ?? if (sigwait(&sigset, &sig) == EINTR) continue; switch (sig) { case SIGINT: log_file->write_report("SIGINT received.", "::phone_sigwait"); ui->cmd_quit(); return NULL; case SIGTERM: log_file->write_report("SIGTERM received.", "::phone_sigwait"); ui->cmd_quit(); return NULL; case SIGCHLD: // Cleanup terminated child process pid = wait(&child_status); log_file->write_header("::phone_sigwait"); log_file->write_raw("SIGCHLD received.\n"); log_file->write_raw("Pid "); log_file->write_raw((int)pid); log_file->write_raw(" terminated.\n"); log_file->write_footer(); break; default: log_file->write_header("::phone_sigwait", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unexpected signal ("); log_file->write_raw(sig); log_file->write_raw(") received.\n"); log_file->write_footer(); } } } void phone_sighandler(int sig) { int child_status; pid_t pid; // Minimal processing should be done in a signal handler. // No I/O should be performed. switch (sig) { case SIGINT: // Post a quit command instead of executing it. As executing // involves a lock that may lead to a deadlock. ui->cmd_quit_async(); break; case SIGTERM: ui->cmd_quit_async(); break; case SIGCHLD: // Cleanup terminated child process pid = wait(&child_status); break; } } twinkle-1.4.2/src/service.cpp0000644000175000001440000002117611127714060013051 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "service.h" #include "log.h" #include "userintf.h" #include "util.h" #define FLD_CF_ALWAYS "cf_always" #define FLD_CF_BUSY "cf_busy" #define FLD_CF_NOANSWER "cf_noanswer" #define FLD_DND "dnd" #define FLD_AUTO_ANSWER "auto_answer" void t_service::lock() { mtx_service.lock(); } void t_service::unlock() { mtx_service.unlock(); } t_service::t_service(t_user *user) { user_config = user; // Call redirection cf_always_active = false; cf_busy_active = false; cf_noanswer_active = false; // Do not disturb dnd_active = false; // Auto answer auto_answer_active = false; string msg; (void)read_config(msg); } bool t_service::multiple_services_active(void) { int num_services = 0; if (is_cf_active()) num_services++; if (is_dnd_active()) num_services++; if (is_auto_answer_active()) num_services++; if (num_services > 1) return true; return false; } void t_service::enable_cf(t_cf_type cf_type, const list &cf_dest) { lock(); switch (cf_type) { case CF_ALWAYS: cf_always_active = true; cf_always_dest = cf_dest; break; case CF_BUSY: cf_busy_active = true; cf_busy_dest = cf_dest; break; case CF_NOANSWER: cf_noanswer_active = true; cf_noanswer_dest = cf_dest; break; default: assert(false); } unlock(); string msg; (void)write_config(msg); } void t_service::disable_cf(t_cf_type cf_type) { lock(); switch (cf_type) { case CF_ALWAYS: cf_always_active = false; cf_always_dest.clear(); break; case CF_BUSY: cf_busy_active = false; cf_busy_dest.clear(); break; case CF_NOANSWER: cf_noanswer_active = false; cf_noanswer_dest.clear(); break; default: assert(false); } unlock(); string msg; (void)write_config(msg); } bool t_service::get_cf_active(t_cf_type cf_type, list &dest) { bool active = false; lock(); switch (cf_type) { case CF_ALWAYS: active = cf_always_active; dest = cf_always_dest; break; case CF_BUSY: active = cf_busy_active; dest = cf_busy_dest; break; case CF_NOANSWER: active = cf_noanswer_active; dest = cf_noanswer_dest; break; default: assert(false); } unlock(); return active; } bool t_service::is_cf_active(void) { bool active = false; lock(); active = cf_always_active || cf_busy_active || cf_noanswer_active; unlock(); return active; } list t_service::get_cf_dest(t_cf_type cf_type) { list dest; lock(); switch (cf_type) { case CF_ALWAYS: dest = cf_always_dest; break; case CF_BUSY: dest = cf_busy_dest; break; case CF_NOANSWER: dest = cf_noanswer_dest; break; default: assert(false); } unlock(); return dest; } void t_service::enable_dnd(void) { lock(); dnd_active = true; unlock(); string msg; (void)write_config(msg); } void t_service::disable_dnd(void) { lock(); dnd_active = false; unlock(); string msg; (void)write_config(msg); } bool t_service::is_dnd_active(void) const { return dnd_active; } void t_service::enable_auto_answer(bool on) { lock(); auto_answer_active = on; unlock(); string msg; (void)write_config(msg); } bool t_service::is_auto_answer_active(void) const { return auto_answer_active; } bool t_service::read_config(string &error_msg) { struct stat stat_buf; lock(); string filename = user_config->get_profile_name() + SVC_FILE_EXT; string f = user_config->expand_filename(filename); // Check if config file exists if (stat(f.c_str(), &stat_buf) != 0) { unlock(); return true; } // Open file ifstream config(f.c_str()); if (!config) { error_msg = "Cannot open file for reading: "; error_msg += f; log_file->write_report(error_msg, "t_service::read_config", LOG_NORMAL, LOG_CRITICAL); unlock(); return false; } t_display_url display_url; cf_always_active = false; cf_always_dest.clear(); cf_busy_active = false; cf_busy_dest.clear(); cf_noanswer_active = false; cf_noanswer_dest.clear(); while (!config.eof()) { string line; getline(config, line); // Check if read operation succeeded if (!config.good() && !config.eof()) { error_msg = "File system error while reading file "; error_msg += f; log_file->write_report(error_msg, "t_service::read_config", LOG_NORMAL, LOG_CRITICAL); unlock(); return false; } line = trim(line); // Skip empty lines if (line.size() == 0) continue; // Skip comment lines if (line[0] == '#') continue; vector l = split_on_first(line, '='); if (l.size() != 2) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += line; log_file->write_report(error_msg, "t_service::read_config", LOG_NORMAL, LOG_CRITICAL); unlock(); return false; } string parameter = trim(l[0]); string value = trim(l[1]); if (parameter == FLD_CF_ALWAYS) { ui->expand_destination(user_config, value, display_url); if (display_url.is_valid()) { cf_always_active = true; cf_always_dest.push_back(display_url); } } else if (parameter == FLD_CF_BUSY) { ui->expand_destination(user_config, value, display_url); if (display_url.is_valid()) { cf_busy_active = true; cf_busy_dest.push_back(display_url); } } else if (parameter == FLD_CF_NOANSWER) { ui->expand_destination(user_config, value, display_url); if (display_url.is_valid()) { cf_noanswer_active = true; cf_noanswer_dest.push_back(display_url); } } else if (parameter == FLD_DND) { dnd_active = yesno2bool(value); } else if (parameter == FLD_AUTO_ANSWER) { auto_answer_active = yesno2bool(value); } else { // Ignore unknown parameters. Only report in log file. log_file->write_header("t_service::read_config", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unknown parameter in service config: "); log_file->write_raw(parameter); log_file->write_endl(); log_file->write_footer(); } } unlock(); return true; } bool t_service::write_config(string &error_msg) { struct stat stat_buf; lock(); string filename = user_config->get_profile_name() + SVC_FILE_EXT; string f = user_config->expand_filename(filename); // Make a backup of the file if we are editing an existing file, so // that can be restored when writing fails. string f_backup = f + '~'; if (stat(f.c_str(), &stat_buf) == 0) { if (rename(f.c_str(), f_backup.c_str()) != 0) { string err = get_error_str(errno); error_msg = "Failed to backup "; error_msg += f; error_msg += " to "; error_msg += f_backup; error_msg += "\n"; error_msg += err; log_file->write_report(error_msg, "t_service::write_config", LOG_NORMAL, LOG_CRITICAL); unlock(); return false; } } ofstream config(f.c_str()); if (!config) { error_msg = "Cannot open file for writing: "; error_msg += f; log_file->write_report(error_msg, "t_user::write_config", LOG_NORMAL, LOG_CRITICAL); unlock(); return false; } for (list::iterator i = cf_always_dest.begin(); i != cf_always_dest.end(); i++) { config << FLD_CF_ALWAYS << '=' << i->encode() << endl; } for (list::iterator i = cf_busy_dest.begin(); i != cf_busy_dest.end(); i++) { config << FLD_CF_BUSY << '=' << i->encode() << endl; } for (list::iterator i = cf_noanswer_dest.begin(); i != cf_noanswer_dest.end(); i++) { config << FLD_CF_NOANSWER << '=' << i->encode() << endl; } config << FLD_DND << '=' << bool2yesno(dnd_active) << endl; config << FLD_AUTO_ANSWER << '=' << bool2yesno(auto_answer_active) << endl; // Check if writing succeeded if (!config.good()) { // Restore backup config.close(); rename(f_backup.c_str(), f.c_str()); error_msg = "File system error while writing file "; error_msg += f; log_file->write_report(error_msg, "t_service::write_config", LOG_NORMAL, LOG_CRITICAL); unlock(); return false; } unlock(); return true; } twinkle-1.4.2/src/transaction.cpp0000644000175000001440000007677311127714060013753 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "log.h" #include "events.h" #include "timekeeper.h" #include "transaction.h" #include "transaction_mgr.h" #include "user.h" #include "util.h" #include "audits/memman.h" extern t_event_queue *evq_sender; extern t_event_queue *evq_trans_layer; extern t_transaction_mgr *transaction_mgr; string trans_state2str(t_trans_state s) { switch(s) { case TS_NULL: return "TS_NULL"; case TS_CALLING: return "TS_CALLING"; case TS_TRYING: return "TS_TRYING"; case TS_PROCEEDING: return "TS_PROCEEDING"; case TS_COMPLETED: return "TS_COMPLETED"; case TS_CONFIRMED: return "TS_CONFIRMED"; case TS_TERMINATED: return "TS_TERMINATED"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // RFC 3261 17 // General transaction /////////////////////////////////////////////////////////// t_mutex t_transaction::mtx_class; t_tid t_transaction::next_id = 1; t_transaction::t_transaction(t_request *r, unsigned short _tuid) { mtx_class.lock(); id = next_id++; if (next_id == 65535) next_id = 1; mtx_class.unlock(); state = TS_NULL; request = (t_request *)r->copy(); final = NULL; tuid = _tuid; } t_transaction::~t_transaction() { MEMMAN_DELETE(request); delete request; if (final != NULL) { MEMMAN_DELETE(final); delete final; } for (list::iterator i = provisional.begin(); i != provisional.end(); i++) { MEMMAN_DELETE(*i); delete *i; } } t_tid t_transaction::get_id(void) const { return id; } void t_transaction::process_provisional(t_response *r) { provisional.push_back((t_response *)r->copy()); } void t_transaction::process_final(t_response *r) { final = (t_response *)r->copy(); } void t_transaction::process_response(t_response *r) { if (r->is_provisional()) { process_provisional(r); } else { process_final(r); } } t_trans_state t_transaction::get_state(void) const { return state; } void t_transaction::set_tuid(unsigned short _tuid) { tuid = _tuid; } t_method t_transaction::get_method(void) const { return request->method; } string t_transaction::get_to_tag(void) { string tag; tag = request->hdr_to.tag; if (tag.size() > 0) return tag; if (to_tag.size() > 0) return to_tag; to_tag = random_token(TAG_LEN); return to_tag; } // RCF 3261 section 8.2.6.2 t_response *t_transaction::create_response(int code, string reason) { t_response *r; r = request->create_response(code, reason); // NOTE: 100 Trying does not establish a dialog if (code != R_100_TRYING) { r->hdr_to.set_tag(get_to_tag()); } return r; } /////////////////////////////////////////////////////////// // RFC 3261 17.1 // Client transaction /////////////////////////////////////////////////////////// t_trans_client::t_trans_client(t_request *r, const t_ip_port &ip_port, unsigned short _tuid) : t_transaction(r, _tuid), dst_ip_port(ip_port) { // Send request evq_sender->push_network(r, dst_ip_port); } // RFC 3261 17.1.3, 8.2.6.2 // Section 17.1.3 states that only the branch and CSeq method should match. // This can lead to the following problem however: // // 1) A response matches a BYE request, but has a wrong call id. // 2) As the response matches the request, the transaction finishes. // 3) Then the response is delivered to the TU which tries to match the // response to a dialog. // 4) As the call id is wrong, no match is found an the response is discarded. // 5) Now the TU keeps waiting forever for a response on the BYE // // By taking the call id into account here, this scenario is prevented. // When a call id is wrong, the BYE request will be retransmitted due to // timeouts until the transaction times out completely and a 408 is sent // to the TU. // // Same problem can occur when tags do not match, so tag is take into account // as well. So tags are take into account as well. bool t_trans_client::match(t_response *r) const { t_via &req_top_via = request->hdr_via.via_list.front(); t_via &resp_top_via = r->hdr_via.via_list.front(); return (req_top_via.branch == resp_top_via.branch && request->hdr_cseq.method == r->hdr_cseq.method && request->hdr_call_id.call_id == r->hdr_call_id.call_id && request->hdr_from.tag == r->hdr_from.tag && (request->hdr_to.tag.empty() || request->hdr_to.tag == r->hdr_to.tag)); } // An ICMP error matches a transaction when the destination IP address/port // of the packet that caused the ICMP error equals the destination // IP address/port of the transaction. Other information of the packet causing // the ICMP error is not available. // In theory when multiple transactions are open for the same destination, the // wrong transaction may process the ICMP error. In practice this should rarely // happen as the destination will be unreachable for all those transactions. // If it happens a transaction gets aborted. bool t_trans_client::match(const t_icmp_msg &icmp) const { return (dst_ip_port.ipaddr == icmp.ipaddr && dst_ip_port.port == icmp.port); } bool t_trans_client::match(const string &branch, const t_method &cseq_method) const { t_via &req_top_via = request->hdr_via.via_list.front(); return (req_top_via.branch == branch && request->hdr_cseq.method == cseq_method); } void t_trans_client::process_provisional(t_response *r) { // Set the to_tag, such that an internally genrated answer (when needed) // will have the correct tag. // An INVITE transaction may receive provisional responses with // different to-tags. Only the first to-tag will be kept and an // internally generated response will match this tag. if (!r->hdr_to.tag.empty() && to_tag.empty()) { to_tag = r->hdr_to.tag; } t_transaction::process_provisional(r); } /////////////////////////////////////////////////////////// // RFC 3261 17.1.1 // Client INVITE transaction /////////////////////////////////////////////////////////// void t_tc_invite::start_timer_A(void) { timer_A = transaction_mgr->start_timer(duration_A, TIMER_A, id); // Double duration for a next start duration_A = 2 * duration_A; } void t_tc_invite::start_timer_B(void) { timer_B = transaction_mgr->start_timer(DURATION_B, TIMER_B, id); } void t_tc_invite::start_timer_D(void) { // RFC 3261 17.1.1.2 // For reliable transport timer D must be set to zero seconds. if (dst_ip_port.transport == "udp") { timer_D = transaction_mgr->start_timer(DURATION_D, TIMER_D, id); } else { timer_D = transaction_mgr->start_timer(0, TIMER_D, id); } } void t_tc_invite::stop_timer_A(void) { if (timer_A) { transaction_mgr->stop_timer(timer_A); timer_A = 0; } } void t_tc_invite::stop_timer_B(void) { if (timer_B) { transaction_mgr->stop_timer(timer_B); timer_B = 0; } } void t_tc_invite::stop_timer_D(void) { if (timer_D) { transaction_mgr->stop_timer(timer_D); timer_D = 0; } } t_tc_invite::t_tc_invite(t_request *r, const t_ip_port &ip_port, unsigned short _tuid) : t_trans_client(r, ip_port, _tuid) { assert(r->method == INVITE); ack = NULL; duration_A = DURATION_A; state = TS_CALLING; // RFC 3261 17.1.1.2 // Start timer A for unreliable transports. if (ip_port.transport == "udp") start_timer_A(); // RFC 3261 17.1.1.2 // Start timer B for all transports start_timer_B(); timer_D = 0; } t_tc_invite::~t_tc_invite() { if (ack != NULL) { MEMMAN_DELETE(ack); delete ack; } stop_timer_A(); stop_timer_B(); stop_timer_D(); } void t_tc_invite::process_provisional(t_response *r) { assert(r->is_provisional()); switch (state) { case TS_CALLING: stop_timer_A(); stop_timer_B(); // fall through case TS_PROCEEDING: t_trans_client::process_provisional(r); state = TS_PROCEEDING; // Report to TU evq_trans_layer->push_user(r, tuid, id); break; default: // Discard provisional response in other states break; } } void t_tc_invite::process_final(t_response *r) { assert(r->is_final()); t_ip_port ip_port; switch (state) { case TS_CALLING: stop_timer_A(); stop_timer_B(); // fall through case TS_PROCEEDING: t_trans_client::process_final(r); if (r->is_success()) { state = TS_TERMINATED; } else { // RFC 3261 17.1.1.3 // construct ACK ack = new t_request(ACK); MEMMAN_NEW(ack); ack->uri = request->uri; ack->hdr_call_id = request->hdr_call_id; ack->hdr_from = request->hdr_from; ack->hdr_to = r->hdr_to; ack->hdr_via.add_via( request->hdr_via.via_list.front()); ack->hdr_cseq.set_seqnr(request->hdr_cseq.seqnr); ack->hdr_cseq.set_method(ACK); ack->hdr_route = request->hdr_route; ack->hdr_max_forwards.set_max_forwards(MAX_FORWARDS); SET_HDR_USER_AGENT(ack->hdr_user_agent) // RFC 3261 22.1 // Duplicate Authorization and Proxy-Authorization // headers from INVITE if the credentials in the // INVITE are accepted. if (r->code != R_401_UNAUTHORIZED && r->code != R_407_PROXY_AUTH_REQUIRED) { ack->hdr_authorization = request->hdr_authorization; ack->hdr_proxy_authorization = request->hdr_proxy_authorization; } // RFC 3263 4 // ACK for non-2xx SIP responses to INVITE MUST be sent t // to the same host. request->get_current_destination(ip_port); ack->set_destination(ip_port); // Send ACK evq_sender->push_network(ack, dst_ip_port); start_timer_D(); state = TS_COMPLETED; } // Report to TU evq_trans_layer->push_user(r, tuid, id); break; case TS_COMPLETED: // A failure has been received. So 2XX is not // expected anymore. Discard 2XX. if (r->is_success()) { break; } // Retransmit ACK evq_sender->push_network(ack, dst_ip_port); break; default: break; } } void t_tc_invite::process_icmp(const t_icmp_msg &icmp) { log_file->write_report("ICMP error received.", "t_tc_invite::process_icmp"); process_failure(FAIL_TRANSPORT); } void t_tc_invite::process_failure(t_failure failure) { t_response *r; switch(state) { case TS_CALLING: stop_timer_A(); stop_timer_B(); switch (failure) { case FAIL_TRANSPORT: // A transport failure indicates a kind of network problem. // So the server is not available. Generate an internal // 503 Service Unavailable repsponse to notify the TU. r = create_response(R_503_SERVICE_UNAVAILABLE); break; case FAIL_TIMEOUT: r = create_response(R_408_REQUEST_TIMEOUT); break; default: log_file->write_header("t_tc_invite::process_failure", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unknown type of failure: "); log_file->write_raw((int)failure); log_file->write_endl(); log_file->write_footer(); r = create_response(R_400_BAD_REQUEST); break; } log_file->write_header("t_tc_invite::process_failure", LOG_NORMAL, LOG_INFO); log_file->write_raw("Transaction failed.\n\n"); log_file->write_raw("Send internal:\n"); log_file->write_raw(r->encode()); log_file->write_footer(); evq_trans_layer->push_user(r, tuid, id); MEMMAN_DELETE(r); delete r; state = TS_TERMINATED; break; default: // In other states a response has been received already, // so this failure seems to be a mismatch. Discard. break; } } void t_tc_invite::timeout(t_sip_timer t) { t_response *r; assert (t == TIMER_A || t == TIMER_B || t == TIMER_D); switch (state) { case TS_CALLING: switch (t) { case TIMER_A: // Resend request evq_sender->push_network(request, dst_ip_port); start_timer_A(); break; case TIMER_B: stop_timer_A(); timer_B = 0; // Report timer expiry to TU r = create_response(R_408_REQUEST_TIMEOUT); log_file->write_header("t_tc_invite::timeout", LOG_NORMAL, LOG_INFO); log_file->write_raw("Timer B expired.\n\n"); log_file->write_raw("Send internal:\n"); log_file->write_raw(r->encode()); log_file->write_footer(); evq_trans_layer->push_user(r, tuid, id); MEMMAN_DELETE(r); delete r; state = TS_TERMINATED; break; default: // Ignore expiry of other timers. // Other timers should have been stopped. break; } break; case TS_COMPLETED: switch (t) { case TIMER_D: timer_D = 0; state = TS_TERMINATED; break; default: // Ignore expiry of other timers. // Other timers should have been stopped. break; } break; default: // Ignore timer expiries in other states // Other timers should have been stopped. break; } } void t_tc_invite::abort(void) { t_response *r; switch (state) { case TS_PROCEEDING: r = create_response(R_408_REQUEST_TIMEOUT, "Request Aborted"); log_file->write_header("t_tc_invite::abort", LOG_NORMAL, LOG_INFO); log_file->write_raw("Invite transaction aborted.\n\n"); log_file->write_raw("Send internal:\n"); log_file->write_raw(r->encode()); log_file->write_footer(); evq_trans_layer->push_user(r, tuid, id); MEMMAN_DELETE(r); delete r; state = TS_TERMINATED; break; default: // Ignore abortion in other states. // In other states the request can be terminated in // a normal way. break; } } /////////////////////////////////////////////////////////// // RFC 3261 17.1.2 // Client non-INVITE transaction /////////////////////////////////////////////////////////// void t_tc_non_invite::start_timer_E(void) { if (state == TS_PROCEEDING) duration_E = DURATION_T2; timer_E = transaction_mgr->start_timer(duration_E, TIMER_E, id); duration_E = 2 * duration_E; if (duration_E > DURATION_T2) duration_E = DURATION_T2; } void t_tc_non_invite::start_timer_F(void) { timer_F = transaction_mgr->start_timer(DURATION_F, TIMER_F, id); } void t_tc_non_invite::start_timer_K(void) { // RFC 3261 17.1.2.2 // For reliable transports set timer K to zero seconds. if (dst_ip_port.transport == "udp") { timer_K = transaction_mgr->start_timer(DURATION_K, TIMER_K, id); } else { timer_K = transaction_mgr->start_timer(0, TIMER_K, id); } } void t_tc_non_invite::stop_timer_E(void) { if (timer_E) { transaction_mgr->stop_timer(timer_E); timer_E = 0; } } void t_tc_non_invite::stop_timer_F(void) { if (timer_F) { transaction_mgr->stop_timer(timer_F); timer_F = 0; } } void t_tc_non_invite::stop_timer_K(void) { if (timer_K) { transaction_mgr->stop_timer(timer_K); timer_K = 0; } } t_tc_non_invite::t_tc_non_invite(t_request *r, const t_ip_port &ip_port, unsigned short _tuid) : t_trans_client(r, ip_port, _tuid) { assert(r->method != INVITE); state = TS_TRYING; duration_E = DURATION_E; // RFC 3261 17.1.2.2 // Start timer E for unreliable transports. if (ip_port.transport == "udp") start_timer_E(); // RFC 3261 17.1.2.2 // Start timer F for all transports. start_timer_F(); timer_K = 0; } t_tc_non_invite::~t_tc_non_invite() { stop_timer_E(); stop_timer_F(); stop_timer_K(); } void t_tc_non_invite::process_provisional(t_response *r) { assert(r->is_provisional()); switch (state) { case TS_TRYING: case TS_PROCEEDING: t_trans_client::process_provisional(r); state = TS_PROCEEDING; // Report to TU evq_trans_layer->push_user(r, tuid, id); break; default: // Discard provisional response in other states break; } } void t_tc_non_invite::process_final(t_response *r) { assert(r->is_final()); switch (state) { case TS_TRYING: case TS_PROCEEDING: t_trans_client::process_final(r); stop_timer_E(); stop_timer_F(); // Report to TU evq_trans_layer->push_user(r, tuid, id); start_timer_K(); state = TS_COMPLETED; break; case TS_COMPLETED: // The received response is a retransmission. // AS the final response is already received this // retransmission can be discarded. // fall through default: break; } } void t_tc_non_invite::process_icmp(const t_icmp_msg &icmp) { log_file->write_report("ICMP error received.", "t_tc_non_invite::process_icmp"); process_failure(FAIL_TRANSPORT); } void t_tc_non_invite::process_failure(t_failure failure) { t_response *r; switch(state) { case TS_TRYING: stop_timer_E(); stop_timer_F(); switch (failure) { case FAIL_TRANSPORT: // A transport failure indicates a kind of network problem. // So the server is not available. Generate an internal // 503 Service Unavailable repsponse to notify the TU. r = create_response(R_503_SERVICE_UNAVAILABLE); break; case FAIL_TIMEOUT: r = create_response(R_408_REQUEST_TIMEOUT); break; default: log_file->write_header("t_tc_non_invite::process_failure", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unknown type of failure: "); log_file->write_raw((int)failure); log_file->write_endl(); log_file->write_footer(); r = create_response(R_400_BAD_REQUEST); break; } log_file->write_header("t_tc_non_invite::process_failure", LOG_NORMAL, LOG_INFO); log_file->write_raw("Transaction failed.\n\n"); log_file->write_raw("Send internal:\n"); log_file->write_raw(r->encode()); log_file->write_footer(); evq_trans_layer->push_user(r, tuid, id); MEMMAN_DELETE(r); delete r; state = TS_TERMINATED; break; default: // In other states a response has been received already, // so this failure seems to be a mismatch. Discard. break; } } void t_tc_non_invite::timeout(t_sip_timer t) { t_response *r; assert (t == TIMER_E || t == TIMER_F || t == TIMER_K); switch (state) { case TS_TRYING: case TS_PROCEEDING: switch (t) { case TIMER_E: // Resend request evq_sender->push_network(request, dst_ip_port); start_timer_E(); break; case TIMER_F: timer_F = 0; stop_timer_E(); // Report timer expiry to TU r = create_response(R_408_REQUEST_TIMEOUT); log_file->write_header("t_tc_non_invite::timeout", LOG_NORMAL, LOG_INFO); log_file->write_raw("Timer F expired.\n\n"); log_file->write_raw("Send internal:\n"); log_file->write_raw(r->encode()); log_file->write_footer(); evq_trans_layer->push_user(r, tuid, id); MEMMAN_DELETE(r); delete r; state = TS_TERMINATED; break; default: // Ignore expiry of other timers. // Other timers should have been stopped. break; } break; case TS_COMPLETED: switch (t) { case TIMER_K: timer_K = 0; state = TS_TERMINATED; break; default: // Ignore expiry of other timers. // Other timers should have been stopped. break; } default: // Ignore timer expiries in other states // Other timers should have been stopped. break; } } void t_tc_non_invite::abort(void) { t_response *r; switch (state) { case TS_TRYING: case TS_PROCEEDING: stop_timer_E(); stop_timer_F(); r = create_response(R_408_REQUEST_TIMEOUT, "Request Aborted"); log_file->write_header("t_tc_non_invite::abort", LOG_NORMAL, LOG_INFO); log_file->write_raw("Non-invite transaction aborted.\n\n"); log_file->write_raw("Send internal:\n"); log_file->write_raw(r->encode()); log_file->write_footer(); evq_trans_layer->push_user(r, tuid, id); MEMMAN_DELETE(r); delete r; state = TS_TERMINATED; break; default: // Ignore abortion in other states. // In other states the request can be terminated in // a normal way. break; } } /////////////////////////////////////////////////////////// // RFC 3261 17.2 // Server transaction /////////////////////////////////////////////////////////// t_trans_server::t_trans_server(t_request *r, unsigned short _tuid) : t_transaction(r, _tuid), resp_100_trying_sent(false) { t_trans_server *t; t_tid tid_cancel = 0; // Report to TU if (request->method == CANCEL) { t = transaction_mgr->find_cancel_target(r); if (t) tid_cancel = t->get_id(); evq_trans_layer->push_user_cancel(r, tuid, id, tid_cancel); } else { evq_trans_layer->push_user(r, tuid, id); } } void t_trans_server::process_provisional(t_response *r) { t_ip_port ip_port; if (r->code == R_100_TRYING && resp_100_trying_sent) { // Send 100 Trying only once return; } t_transaction::process_provisional(r); r->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure(FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(r, ip_port); if (r->code == R_100_TRYING) { resp_100_trying_sent = true; } } } void t_trans_server::process_final(t_response *r) { t_ip_port ip_port; t_transaction::process_final(r); r->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure(FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(r, ip_port); } } void t_trans_server::process_retransmission(void) { // nothing to do } // RFC 3261 17.2.3 // NOTE: retransmission of an incoming INVITE for which a 2XX response // has been sent already is checked by the TU. // see dialog::is_invite_retrans bool t_trans_server::match(t_request *r, bool cancel) const { t_via &orig_top_via = request->hdr_via.via_list.front(); t_via &recv_top_via = r->hdr_via.via_list.front(); if (recv_top_via.rfc3261_compliant()) { if (orig_top_via.branch != recv_top_via.branch) return false; if (orig_top_via.host != recv_top_via.host) return false; if (orig_top_via.port != recv_top_via.port) return false; switch(r->method) { case ACK: // return (request->hdr_cseq.method == INVITE); return (request->method == INVITE); break; case CANCEL: if (!cancel) { // return (request->hdr_cseq.method == // r->hdr_cseq.method); return (request->method == r->method); } // The target of CANCEL cannot be a CANCEL request // return (request->hdr_cseq.method != CANCEL); return (request->method != CANCEL); break; default: // return (request->hdr_cseq.method == // r->hdr_cseq.method); return (request->method == r->method); break; } } // Matching rules for backward compatibiliy with RFC 2543 // TODO: verify rules for matching via headers switch (r->method) { case INVITE: return (request->method == INVITE && request->uri.sip_match(r->uri) && request->hdr_to.tag == r->hdr_to.tag && request->hdr_from.tag == r->hdr_from.tag && request->hdr_call_id.call_id == r->hdr_call_id.call_id && request->hdr_cseq.seqnr == r->hdr_cseq.seqnr && orig_top_via.host == recv_top_via.host && orig_top_via.port == recv_top_via.port); break; case ACK: return (request->method == INVITE && request->uri.sip_match(r->uri) && request->hdr_from.tag == r->hdr_from.tag && request->hdr_call_id.call_id == r->hdr_call_id.call_id && request->hdr_cseq.seqnr == r->hdr_cseq.seqnr && orig_top_via.host == recv_top_via.host && orig_top_via.port == recv_top_via.port && final != NULL && final->hdr_to.tag == r->hdr_to.tag); break; case CANCEL: if (cancel) { return (request->uri.sip_match(r->uri) && request->hdr_from.tag == r->hdr_from.tag && request->hdr_call_id.call_id == r->hdr_call_id.call_id && request->hdr_cseq.seqnr == r->hdr_cseq.seqnr && request->hdr_cseq.method != CANCEL && orig_top_via.host == recv_top_via.host && orig_top_via.port == recv_top_via.port); } // fall through default: return (request->uri.sip_match(r->uri) && request->hdr_from.tag == r->hdr_from.tag && request->hdr_call_id.call_id == r->hdr_call_id.call_id && request->hdr_cseq == r->hdr_cseq && orig_top_via.host == recv_top_via.host && orig_top_via.port == recv_top_via.port); break; } // Should not get here return false; } bool t_trans_server::match(t_request *r) const { return match(r, false); } bool t_trans_server::match_cancel(t_request *r) const { assert(r->method == CANCEL); return match(r, true); } /////////////////////////////////////////////////////////// // RFC 3261 17.2.1 // Server INVITE transaction /////////////////////////////////////////////////////////// void t_ts_invite::start_timer_G(void) { timer_G = transaction_mgr->start_timer(duration_G, TIMER_G, id); duration_G = 2 * duration_G; if (duration_G > DURATION_T2) duration_G = DURATION_T2; } void t_ts_invite::start_timer_H(void) { timer_H = transaction_mgr->start_timer(DURATION_H, TIMER_H, id); } void t_ts_invite::start_timer_I(void) { // RFC 17.2.1 // Set timer I to T4 seconds for unreliable transports and to 0 for // reliable transports. if (request->src_ip_port.transport == "udp") { timer_I = transaction_mgr->start_timer(DURATION_I, TIMER_I, id); } else { timer_I = transaction_mgr->start_timer(0, TIMER_I, id); } } void t_ts_invite::stop_timer_G(void) { if (timer_G) { transaction_mgr->stop_timer(timer_G); timer_G = 0; } } void t_ts_invite::stop_timer_H(void) { if (timer_H) { transaction_mgr->stop_timer(timer_H); timer_H = 0; } } void t_ts_invite::stop_timer_I(void) { if (timer_I) { transaction_mgr->stop_timer(timer_I); timer_I = 0; } } t_ts_invite::t_ts_invite(t_request *r, unsigned short _tuid) : t_trans_server(r, _tuid) { assert(r->method == INVITE); state = TS_PROCEEDING; ack = NULL; timer_G = 0; timer_H = 0; timer_I = 0; duration_G = DURATION_G; } t_ts_invite::~t_ts_invite() { if (ack != NULL) { MEMMAN_DELETE(ack); delete ack; } stop_timer_G(); stop_timer_H(); stop_timer_I(); } void t_ts_invite::process_provisional(t_response *r) { assert(r->is_provisional()); switch (state) { case TS_PROCEEDING: t_trans_server::process_provisional(r); break; default: // TU should not send a provisional response // in other states. assert(false); break; } } void t_ts_invite::process_final(t_response *r) { assert(r->is_final()); switch (state) { case TS_PROCEEDING: t_trans_server::process_final(r); if (r->is_success()) { state = TS_TERMINATED; } else { // RFC 3261 17.2.1 // Start timer G for unreliable transports. if (request->src_ip_port.transport == "udp") { start_timer_G(); } // RFC 3261 17.2.1 // Start timer H for all transports start_timer_H(); state = TS_COMPLETED; } break; default: // No final responses are expected anymore. Discard. break; } } void t_ts_invite::process_retransmission(void) { t_ip_port ip_port; switch (state) { case TS_PROCEEDING: // Retransmit the latest provisional response (if present) t_trans_server::process_retransmission(); if (provisional.size() > 0) { t_response *r = provisional.back(); r->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure( FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(r, ip_port); } } break; case TS_COMPLETED: // Retransmit the final response t_trans_server::process_retransmission(); final->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure(FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(final, ip_port); } break; default: // Retransmissions should not happen in other states. // Discard. break; } } void t_ts_invite::timeout(t_sip_timer t) { t_ip_port ip_port; assert(t == TIMER_G || t == TIMER_I || t == TIMER_H); switch (state) { case TS_COMPLETED: switch (t) { case TIMER_G: timer_G = 0; // Retransmit the final response final->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. stop_timer_H(); state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure( FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(final, ip_port); start_timer_G(); } break; case TIMER_H: timer_H = 0; stop_timer_G(); state = TS_TERMINATED; // Report timer expiry to TU evq_trans_layer->push_failure(FAIL_TIMEOUT, id); break; default: // No other timers should be running. Discard. break; } break; case TS_CONFIRMED: switch (t) { case TIMER_I: timer_I = 0; state = TS_TERMINATED; break; default: // No other timers should be running. Discard. break; } default: // In other states no timers should be running. break; } } void t_ts_invite::acknowledge(t_request *ack_request) { assert(ack_request->method == ACK); switch (state) { case TS_COMPLETED: ack = (t_request *)ack_request->copy(); stop_timer_G(); stop_timer_H(); start_timer_I(); state = TS_CONFIRMED; // Report TU // ACK should not be reported to TU for non-2xx // evq_trans_layer->push_user(ack_request, tuid, id); break; default: // ACK is not expected in other states. Discard; break; } } /////////////////////////////////////////////////////////// // RFC 3261 17.2.2 // Server non-INVITE transaction /////////////////////////////////////////////////////////// void t_ts_non_invite::start_timer_J(void) { // RFC 3261 17.2.2 // For unreliable transports set timer J to 64*T1, for reliable // transports set it to 0. if (request->src_ip_port.transport == "udp") { timer_J = transaction_mgr->start_timer(DURATION_J, TIMER_J, id); } else { timer_J = transaction_mgr->start_timer(0, TIMER_J, id); } } void t_ts_non_invite::stop_timer_J(void) { if (timer_J) { transaction_mgr->stop_timer(timer_J); timer_J = 0; } } t_ts_non_invite::t_ts_non_invite(t_request *r, unsigned short _tuid) : t_trans_server(r, _tuid) { assert(r->method != INVITE); timer_J = 0; state = TS_TRYING; } t_ts_non_invite::~t_ts_non_invite() { stop_timer_J(); } void t_ts_non_invite::process_provisional(t_response *r) { assert(r->is_provisional()); switch (state) { case TS_TRYING: case TS_PROCEEDING: t_trans_server::process_provisional(r); state = TS_PROCEEDING; break; default: // TU should not send a provisional response // in other states. assert(false); break; } } void t_ts_non_invite::process_final(t_response *r) { assert(r->is_final()); switch (state) { case TS_TRYING: case TS_PROCEEDING: t_trans_server::process_final(r); start_timer_J(); state = TS_COMPLETED; break; default: // No final responses are expected anymore. Discard. break; } } void t_ts_non_invite::process_retransmission(void) { t_ip_port ip_port; t_response *r; switch (state) { case TS_PROCEEDING: // Retransmit the latest provisional response t_trans_server::process_retransmission(); r = provisional.back(); r->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure(FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(r, ip_port); } break; case TS_COMPLETED: // Retransmit the final response t_trans_server::process_retransmission(); final->get_destination(ip_port); if (ip_port.ipaddr == 0) { // The response cannot be sent. stop_timer_J(); state = TS_TERMINATED; // Report failure to TU evq_trans_layer->push_failure(FAIL_TRANSPORT, id); } else { // Send response evq_sender->push_network(final, ip_port); } break; default: // Retransmissions should not happen in other states. // Discard. break; } } void t_ts_non_invite::timeout(t_sip_timer t) { assert (t == TIMER_J); switch (state) { case TS_COMPLETED: switch (t) { case TIMER_J: timer_J = 0; state = TS_TERMINATED; break; default: break; } default: break; } } twinkle-1.4.2/src/user.cpp0000644000175000001440000024403311151054614012365 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include "diamondcard.h" #include "log.h" #include "phone.h" #include "twinkle_config.h" #include "user.h" #include "userintf.h" #include "util.h" #include "protocol.h" #include "sys_settings.h" #include "audits/memman.h" #include "sdp/sdp.h" #include "parser/parse_ctrl.h" #include "parser/request.h" extern t_phone *phone; // Field names in the config file // USER fields #define FLD_NAME "user_name" #define FLD_DOMAIN "user_domain" #define FLD_DISPLAY "user_display" #define FLD_ORGANIZATION "user_organization" #define FLD_AUTH_REALM "auth_realm" #define FLD_AUTH_NAME "auth_name" #define FLD_AUTH_PASS "auth_pass" #define FLD_AUTH_AKA_OP "auth_aka_op" #define FLD_AUTH_AKA_AMF "auth_aka_amf" // SIP SERVER fields #define FLD_OUTBOUND_PROXY "outbound_proxy" #define FLD_ALL_REQUESTS_TO_PROXY "all_requests_to_proxy" #define FLD_NON_RESOLVABLE_TO_PROXY "non_resolvable_to_proxy" #define FLD_REGISTRAR "registrar" #define FLD_REGISTRATION_TIME "registration_time" #define FLD_REGISTER_AT_STARTUP "register_at_startup" #define FLD_REG_ADD_QVALUE "reg_add_qvalue" #define FLD_REG_QVALUE "reg_qvalue" // AUDIO fields #define FLD_CODECS "codecs" #define FLD_PTIME "ptime" #define FLD_OUT_FAR_END_CODEC_PREF "out_far_end_codec_pref" #define FLD_IN_FAR_END_CODEC_PREF "in_far_end_codec_pref" #define FLD_SPEEX_NB_PAYLOAD_TYPE "speex_nb_payload_type" #define FLD_SPEEX_WB_PAYLOAD_TYPE "speex_wb_payload_type" #define FLD_SPEEX_UWB_PAYLOAD_TYPE "speex_uwb_payload_type" #define FLD_SPEEX_BIT_RATE_TYPE "speex_bit_rate_type" #define FLD_SPEEX_ABR_NB "speex_abr_nb" #define FLD_SPEEX_ABR_WB "speex_abr_wb" #define FLD_SPEEX_DTX "speex_dtx" #define FLD_SPEEX_PENH "speex_penh" #define FLD_SPEEX_QUALITY "speex_quality" #define FLD_SPEEX_COMPLEXITY "speex_complexity" #define FLD_SPEEX_DSP_VAD "speex_dsp_vad" #define FLD_SPEEX_DSP_AGC "speex_dsp_agc" #define FLD_SPEEX_DSP_AGC_LEVEL "speex_dsp_agc_level" #define FLD_SPEEX_DSP_AEC "speex_dsp_aec" #define FLD_SPEEX_DSP_NRD "speex_dsp_nrd" #define FLD_ILBC_PAYLOAD_TYPE "ilbc_payload_type" #define FLD_ILBC_MODE "ilbc_mode" #define FLD_G726_16_PAYLOAD_TYPE "g726_16_payload_type" #define FLD_G726_24_PAYLOAD_TYPE "g726_24_payload_type" #define FLD_G726_32_PAYLOAD_TYPE "g726_32_payload_type" #define FLD_G726_40_PAYLOAD_TYPE "g726_40_payload_type" #define FLD_G726_PACKING "g726_packing" #define FLD_DTMF_TRANSPORT "dtmf_transport" #define FLD_DTMF_PAYLOAD_TYPE "dtmf_payload_type" #define FLD_DTMF_DURATION "dtmf_duration" #define FLD_DTMF_PAUSE "dtmf_pause" #define FLD_DTMF_VOLUME "dtmf_volume" // SIP PROTOCOL fields #define FLD_HOLD_VARIANT "hold_variant" #define FLD_CHECK_MAX_FORWARDS "check_max_forwards" #define FLD_ALLOW_MISSING_CONTACT_REG "allow_missing_contact_reg" #define FLD_REGISTRATION_TIME_IN_CONTACT "registration_time_in_contact" #define FLD_COMPACT_HEADERS "compact_headers" #define FLD_ENCODE_MULTI_VALUES_AS_LIST "encode_multi_values_as_list" #define FLD_USE_DOMAIN_IN_CONTACT "use_domain_in_contact" #define FLD_ALLOW_SDP_CHANGE "allow_sdp_change" #define FLD_ALLOW_REDIRECTION "allow_redirection" #define FLD_ASK_USER_TO_REDIRECT "ask_user_to_redirect" #define FLD_MAX_REDIRECTIONS "max_redirections" #define FLD_EXT_100REL "ext_100rel" #define FLD_EXT_REPLACES "ext_replaces" #define FLD_REFEREE_HOLD "referee_hold" #define FLD_REFERRER_HOLD "referrer_hold" #define FLD_ALLOW_REFER "allow_refer" #define FLD_ASK_USER_TO_REFER "ask_user_to_refer" #define FLD_AUTO_REFRESH_REFER_SUB "auto_refresh_refer_sub" #define FLD_ATTENDED_REFER_TO_AOR "attended_refer_to_aor" #define FLD_ALLOW_XFER_CONSULT_INPROG "allow_xfer_consult_inprog" #define FLD_SEND_P_PREFERRED_ID "send_p_preferred_id" // Transport/NAT fields #define FLD_SIP_TRANSPORT "sip_transport" #define FLD_SIP_TRANSPORT_UDP_THRESHOLD "sip_transport_udp_threshold" #define FLD_NAT_PUBLIC_IP "nat_public_ip" #define FLD_STUN_SERVER "stun_server" #define FLD_PERSISTENT_TCP "persistent_tcp" #define FLD_ENABLE_NAT_KEEPALIVE "enable_nat_keepalive" // TIMER fields #define FLD_TIMER_NOANSWER "timer_noanswer" #define FLD_TIMER_NAT_KEEPALIVE "timer_nat_keepalive" #define FLD_TIMER_TCP_PING "timer_tcp_ping" // ADDRESS FORMAT fields #define FLD_DISPLAY_USERONLY_PHONE "display_useronly_phone" #define FLD_NUMERICAL_USER_IS_PHONE "numerical_user_is_phone" #define FLD_REMOVE_SPECIAL_PHONE_SYM "remove_special_phone_symbols" #define FLD_SPECIAL_PHONE_SYMBOLS "special_phone_symbols" #define FLD_USE_TEL_URI_FOR_PHONE "use_tel_uri_for_phone" // Ring tone settings #define FLD_USER_RINGTONE_FILE "ringtone_file" #define FLD_USER_RINGBACK_FILE "ringback_file" // Incoming call script #define FLD_SCRIPT_INCOMING_CALL "script_incoming_call" #define FLD_SCRIPT_IN_CALL_ANSWERED "script_in_call_answered" #define FLD_SCRIPT_IN_CALL_FAILED "script_in_call_failed" #define FLD_SCRIPT_OUTGOING_CALL "script_outgoing_call" #define FLD_SCRIPT_OUT_CALL_ANSWERED "script_out_call_answered" #define FLD_SCRIPT_OUT_CALL_FAILED "script_out_call_failed" #define FLD_SCRIPT_LOCAL_RELEASE "script_local_release" #define FLD_SCRIPT_REMOTE_RELEASE "script_remote_release" // Number conversion #define FLD_NUMBER_CONVERSION "number_conversion" // Security #define FLD_ZRTP_ENABLED "zrtp_enabled" #define FLD_ZRTP_GOCLEAR_WARNING "zrtp_goclear_warning" #define FLD_ZRTP_SDP "zrtp_sdp" #define FLD_ZRTP_SEND_IF_SUPPORTED "zrtp_send_if_supported" // MWI #define FLD_MWI_SOLLICITED "mwi_sollicited" #define FLD_MWI_USER "mwi_user" #define FLD_MWI_SERVER "mwi_server" #define FLD_MWI_VIA_PROXY "mwi_via_proxy" #define FLD_MWI_SUBSCRIPTION_TIME "mwi_subscription_time" #define FLD_MWI_VM_ADDRESS "mwi_vm_address" // INSTANT MESSAGE #define FLD_IM_MAX_SESSIONS "im_max_sessions" #define FLD_IM_SEND_ISCOMPOSING "im_send_iscomposing" // PRESENCE #define FLD_PRES_SUBSCRIPTION_TIME "pres_subscription_time" #define FLD_PRES_PUBLICATION_TIME "pres_publication_time" #define FLD_PRES_PUBLISH_STARTUP "pres_publish_startup" ///////////////////////// // class t_user ///////////////////////// //////////////////// // Private //////////////////// t_ext_support t_user::str2ext_support(const string &s) const { if (s == "disabled") return EXT_DISABLED; if (s == "supported") return EXT_SUPPORTED; if (s == "preferred") return EXT_PREFERRED; if (s == "required") return EXT_REQUIRED; return EXT_INVALID; } string t_user::ext_support2str(t_ext_support e) const { switch(e) { case EXT_INVALID: return "invalid"; case EXT_DISABLED: return "disabled"; case EXT_SUPPORTED: return "supported"; case EXT_PREFERRED: return "preferred"; case EXT_REQUIRED: return "required"; default: assert(false); } return ""; } t_bit_rate_type t_user::str2bit_rate_type(const string &s) const { if (s == "cbr") return BIT_RATE_CBR; if (s == "vbr") return BIT_RATE_VBR; if (s == "abr") return BIT_RATE_ABR; return BIT_RATE_INVALID; } string t_user::bit_rate_type2str(t_bit_rate_type b) const { switch (b) { case BIT_RATE_INVALID: return "invalid"; case BIT_RATE_CBR: return "cbr"; case BIT_RATE_VBR: return "vbr"; case BIT_RATE_ABR: return "abr"; default: assert(false); } } t_dtmf_transport t_user::str2dtmf_transport(const string &s) const { if (s == "inband") return DTMF_INBAND; if (s == "rfc2833") return DTMF_RFC2833; if (s == "auto") return DTMF_AUTO; if (s == "info") return DTMF_INFO; return DTMF_AUTO; } string t_user::dtmf_transport2str(t_dtmf_transport d) const { switch (d) { case DTMF_INBAND: return "inband"; case DTMF_RFC2833: return "rfc2833"; case DTMF_AUTO: return "auto"; case DTMF_INFO: return "info"; default: assert(false); } } t_g726_packing t_user::str2g726_packing(const string &s) const { if (s == "rfc3551") return G726_PACK_RFC3551; if (s == "aal2") return G726_PACK_AAL2; return G726_PACK_AAL2; } string t_user::g726_packing2str(t_g726_packing packing) const { switch (packing) { case G726_PACK_RFC3551: return "rfc3551"; case G726_PACK_AAL2: return "aal2"; default: assert(false); } } t_sip_transport t_user::str2sip_transport(const string &s) const { if (s == "udp") return SIP_TRANS_UDP; if (s == "tcp") return SIP_TRANS_TCP; if (s == "auto") return SIP_TRANS_AUTO; return SIP_TRANS_AUTO; } string t_user::sip_transport2str(t_sip_transport transport) const { switch (transport) { case SIP_TRANS_UDP: return "udp"; case SIP_TRANS_TCP: return "tcp"; case SIP_TRANS_AUTO: return "auto"; default: assert(false); } } string t_user::expand_filename(const string &filename) { string f; if (filename[0] == '/') { f = filename; } else { f = string(DIR_HOME); f += "/"; f += USER_DIR; f += "/"; f += filename; } return f; } bool t_user::parse_num_conversion(const string &value, t_number_conversion &c) { vector l = split_escaped(value, ','); if (l.size() != 2) { // Invalid conversion rule return false; } try { c.re.assign(l[0]); c.fmt = l[1]; } catch (boost::bad_expression) { // Invalid regular expression log_file->write_header("t_user::parse_num_conversion", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Bad number conversion:\n"); log_file->write_raw(l.front()); log_file->write_raw(" --> "); log_file->write_raw(l.back()); log_file->write_endl(); log_file->write_footer(); return false; } return true; } bool t_user::set_server_value(t_url &server, const string &scheme, const string &value) { if (value.empty()) { server.set_url(""); return false; } string s = scheme + ":" + value; server.set_url(s); if (!server.is_valid() || server.get_user() != "") { string err_msg = "Invalid server value: "; err_msg += value; log_file->write_report(err_msg, "t_user::set_server_value", LOG_NORMAL, LOG_WARNING); server.set_url(""); return false; } return true; } //////////////////// // Public //////////////////// t_user::t_user() { // Set defaults memset(auth_aka_op, 0, AKA_OPLEN); memset(auth_aka_amf, 0, AKA_AMFLEN); use_outbound_proxy = false; all_requests_to_proxy = false; non_resolvable_to_proxy = false; use_registrar = false; registration_time = 3600; #ifdef HAVE_SPEEX codecs.push_back(CODEC_SPEEX_WB); codecs.push_back(CODEC_SPEEX_NB); #endif #ifdef HAVE_ILBC codecs.push_back(CODEC_ILBC); #endif codecs.push_back(CODEC_G711_ALAW); codecs.push_back(CODEC_G711_ULAW); codecs.push_back(CODEC_GSM); ptime = 20; out_obey_far_end_codec_pref = true; in_obey_far_end_codec_pref = true; hold_variant = HOLD_RFC3264; use_nat_public_ip = false; use_stun = false; persistent_tcp = true; enable_nat_keepalive = false; register_at_startup = true; reg_add_qvalue = false; reg_qvalue = 1.0; check_max_forwards = false; allow_missing_contact_reg = true; compact_headers = false; encode_multi_values_as_list = true; registration_time_in_contact = true; use_domain_in_contact = false; allow_sdp_change = false; allow_redirection = true; ask_user_to_redirect = true; max_redirections = 5; timer_noanswer = 30; timer_nat_keepalive = DUR_NAT_KEEPALIVE; timer_tcp_ping = DUR_TCP_PING; ext_100rel = EXT_SUPPORTED; ext_replaces = true; speex_nb_payload_type = 97; speex_wb_payload_type = 98; speex_uwb_payload_type = 99; speex_bit_rate_type = BIT_RATE_CBR; speex_abr_nb = 0; speex_abr_wb = 0; speex_dtx = false; speex_penh = true; speex_quality = 6; speex_complexity = 3; speex_dsp_vad = true; speex_dsp_agc = true; speex_dsp_aec = false; speex_dsp_nrd = true; speex_dsp_agc_level = 20; ilbc_payload_type = 96; ilbc_mode = 30; g726_16_payload_type = 102; g726_24_payload_type = 103; g726_32_payload_type = 104; g726_40_payload_type = 105; g726_packing = G726_PACK_RFC3551; dtmf_transport = DTMF_AUTO; dtmf_duration = 100; dtmf_pause = 40; dtmf_payload_type = 101; dtmf_volume = 10; display_useronly_phone = true; numerical_user_is_phone = false; remove_special_phone_symbols = true; special_phone_symbols = SPECIAL_PHONE_SYMBOLS; use_tel_uri_for_phone = false; referee_hold = false; referrer_hold = true; allow_refer = true; ask_user_to_refer = true; auto_refresh_refer_sub = false; attended_refer_to_aor = false; allow_transfer_consultation_inprog = false; send_p_preferred_id = false; sip_transport = SIP_TRANS_AUTO; sip_transport_udp_threshold = 1300; // RFC 3261 18.1.1 ringtone_file.clear(); ringback_file.clear(); script_incoming_call.clear(); script_in_call_answered.clear(); script_in_call_failed.clear(); script_outgoing_call.clear(); script_out_call_answered.clear(); script_out_call_failed.clear(); script_local_release.clear(); script_remote_release.clear(); number_conversions.clear(); zrtp_enabled = false; zrtp_goclear_warning = true; zrtp_sdp = true; zrtp_send_if_supported = false; mwi_sollicited = false; mwi_user.clear(); mwi_via_proxy = false; mwi_subscription_time = 3600; mwi_vm_address.clear(); im_max_sessions = 10; im_send_iscomposing = true; pres_subscription_time = 3600; pres_publication_time = 3600; pres_publish_startup = true; } t_user::t_user(const t_user &u) { u.mtx_user.lock(); config_filename = u.config_filename; name = u.name; domain = u.domain; display = u.display; organization = u.organization; auth_realm = u.auth_realm; auth_name = u.auth_name; auth_pass = u.auth_pass; memcpy(auth_aka_op, u.auth_aka_op, AKA_OPLEN); memcpy(auth_aka_amf, u.auth_aka_amf, AKA_AMFLEN); use_outbound_proxy = u.use_outbound_proxy; outbound_proxy = u.outbound_proxy; all_requests_to_proxy = u.all_requests_to_proxy; non_resolvable_to_proxy = u.non_resolvable_to_proxy; use_registrar = u.use_registrar; reg_add_qvalue = u.reg_add_qvalue; reg_qvalue = u.reg_qvalue; registrar = u.registrar; registration_time = u.registration_time; register_at_startup = u.register_at_startup; codecs = u.codecs; ptime = u.ptime; out_obey_far_end_codec_pref = u.out_obey_far_end_codec_pref; in_obey_far_end_codec_pref = u.in_obey_far_end_codec_pref; speex_nb_payload_type = u.speex_nb_payload_type; speex_wb_payload_type = u.speex_wb_payload_type; speex_uwb_payload_type = u.speex_uwb_payload_type; speex_bit_rate_type = u.speex_bit_rate_type; speex_abr_nb = u.speex_abr_nb; speex_abr_wb = u.speex_abr_wb; speex_dtx = u.speex_dtx; speex_penh = u.speex_penh; speex_quality = u.speex_quality; speex_complexity = u.speex_complexity; speex_dsp_vad = u.speex_dsp_vad; speex_dsp_agc = u.speex_dsp_agc; speex_dsp_agc_level = u.speex_dsp_agc_level; speex_dsp_aec = u.speex_dsp_aec; speex_dsp_nrd = u.speex_dsp_nrd; ilbc_payload_type = u.ilbc_payload_type; ilbc_mode = u.ilbc_mode; g726_16_payload_type = u.g726_16_payload_type; g726_24_payload_type = u.g726_24_payload_type; g726_32_payload_type = u.g726_32_payload_type; g726_40_payload_type = u.g726_40_payload_type; g726_packing = u.g726_packing; dtmf_transport = u.dtmf_transport; dtmf_payload_type = u.dtmf_payload_type; dtmf_duration = u.dtmf_duration; dtmf_pause = u.dtmf_pause; dtmf_volume = u.dtmf_volume; hold_variant = u.hold_variant; check_max_forwards = u.check_max_forwards; allow_missing_contact_reg = u.allow_missing_contact_reg; registration_time_in_contact = u.registration_time_in_contact; compact_headers = u.compact_headers; encode_multi_values_as_list = u.encode_multi_values_as_list; use_domain_in_contact = u.use_domain_in_contact; allow_sdp_change = u.allow_sdp_change; allow_redirection = u.allow_redirection; ask_user_to_redirect = u.ask_user_to_redirect; max_redirections = u.max_redirections; ext_100rel = u.ext_100rel; ext_replaces = u.ext_replaces; referee_hold = u.referee_hold; referrer_hold = u.referrer_hold; allow_refer = u.allow_refer; ask_user_to_refer = u.ask_user_to_refer; auto_refresh_refer_sub = u.auto_refresh_refer_sub; attended_refer_to_aor = u.attended_refer_to_aor; allow_transfer_consultation_inprog = u.allow_transfer_consultation_inprog; send_p_preferred_id = u.send_p_preferred_id; sip_transport = u.sip_transport; sip_transport_udp_threshold = u.sip_transport_udp_threshold; use_nat_public_ip = u.use_nat_public_ip; nat_public_ip = u.nat_public_ip; use_stun = u.use_stun; stun_server = u.stun_server; persistent_tcp = u.persistent_tcp; enable_nat_keepalive = u.enable_nat_keepalive; timer_noanswer = u.timer_noanswer; timer_nat_keepalive = u.timer_nat_keepalive; timer_tcp_ping = u.timer_tcp_ping; display_useronly_phone = u.display_useronly_phone; numerical_user_is_phone = u.numerical_user_is_phone; remove_special_phone_symbols = u.remove_special_phone_symbols; special_phone_symbols = u.special_phone_symbols; use_tel_uri_for_phone = u.use_tel_uri_for_phone; ringtone_file = u.ringtone_file; ringback_file = u.ringback_file; script_incoming_call = u.script_incoming_call; script_in_call_answered = u.script_in_call_answered; script_in_call_failed = u.script_in_call_failed; script_outgoing_call = u.script_outgoing_call; script_out_call_answered = u.script_out_call_answered; script_out_call_failed = u.script_out_call_failed; script_local_release = u.script_local_release; script_remote_release = u.script_remote_release; number_conversions = u.number_conversions; zrtp_enabled = u.zrtp_enabled; zrtp_goclear_warning = u.zrtp_goclear_warning; zrtp_sdp = u.zrtp_sdp; zrtp_send_if_supported = u.zrtp_send_if_supported; mwi_sollicited = u.mwi_sollicited; mwi_user = u.mwi_user; mwi_server = u.mwi_server; mwi_via_proxy = u.mwi_via_proxy; mwi_subscription_time = u.mwi_subscription_time; mwi_vm_address = u.mwi_vm_address; im_max_sessions = u.im_max_sessions; im_send_iscomposing = u.im_send_iscomposing; pres_subscription_time = u.pres_subscription_time; pres_publication_time = u.pres_publication_time; pres_publish_startup = u.pres_publish_startup; u.mtx_user.unlock(); } t_user *t_user::copy(void) const { t_user *u = new t_user(*this); MEMMAN_NEW(u); return u; } string t_user::get_name(void) const { string result; mtx_user.lock(); result = name; mtx_user.unlock(); return result; } string t_user::get_domain(void) const { string result; mtx_user.lock(); result = domain; mtx_user.unlock(); return result; } string t_user::get_display(bool anonymous) const { if (anonymous) return ANONYMOUS_DISPLAY; string result; mtx_user.lock(); result = display; mtx_user.unlock(); return result; } string t_user::get_organization(void) const { string result; mtx_user.lock(); result = organization; mtx_user.unlock(); return result; } string t_user::get_auth_realm(void) const { string result; mtx_user.lock(); result = auth_realm; mtx_user.unlock(); return result; } string t_user::get_auth_name(void) const { string result; mtx_user.lock(); result = auth_name; mtx_user.unlock(); return result; } string t_user::get_auth_pass(void) const { string result; mtx_user.lock(); result = auth_pass; mtx_user.unlock(); return result; } void t_user::get_auth_aka_op(uint8 *aka_op) const { t_mutex_guard guard(mtx_user); memcpy(aka_op, auth_aka_op, AKA_OPLEN); } void t_user::get_auth_aka_amf(uint8 *aka_amf) const { t_mutex_guard guard(mtx_user); memcpy(aka_amf, auth_aka_amf, AKA_AMFLEN); } bool t_user::get_use_outbound_proxy(void) const { bool result; mtx_user.lock(); result = use_outbound_proxy; mtx_user.unlock(); return result; } t_url t_user::get_outbound_proxy(void) const { t_url result; mtx_user.lock(); result = outbound_proxy; mtx_user.unlock(); return result; } bool t_user::get_all_requests_to_proxy(void) const { bool result; mtx_user.lock(); result = all_requests_to_proxy; mtx_user.unlock(); return result; } bool t_user::get_non_resolvable_to_proxy(void) const { bool result; mtx_user.lock(); result = non_resolvable_to_proxy; mtx_user.unlock(); return result; } bool t_user::get_use_registrar(void) const { bool result; mtx_user.lock(); result = use_registrar; mtx_user.unlock(); return result; } t_url t_user::get_registrar(void) const { t_url result; mtx_user.lock(); result = registrar; mtx_user.unlock(); return result; } unsigned long t_user::get_registration_time(void) const { unsigned long result; mtx_user.lock(); result = registration_time; mtx_user.unlock(); return result; } bool t_user::get_register_at_startup(void) const { bool result; mtx_user.lock(); result = register_at_startup; mtx_user.unlock(); return result; } bool t_user::get_reg_add_qvalue(void) const { bool result; mtx_user.lock(); result = reg_add_qvalue; mtx_user.unlock(); return result; } float t_user::get_reg_qvalue(void) const { float result; mtx_user.lock(); result = reg_qvalue; mtx_user.unlock(); return result; } list t_user::get_codecs(void) const { list result; mtx_user.lock(); result = codecs; mtx_user.unlock(); return result; } unsigned short t_user::get_ptime(void) const { unsigned short result; mtx_user.lock(); result = ptime; mtx_user.unlock(); return result; } bool t_user::get_out_obey_far_end_codec_pref(void) const { bool result; mtx_user.lock(); result = out_obey_far_end_codec_pref; mtx_user.unlock(); return result; } bool t_user::get_in_obey_far_end_codec_pref(void) const { bool result; mtx_user.lock(); result = in_obey_far_end_codec_pref; mtx_user.unlock(); return result; } unsigned short t_user::get_speex_nb_payload_type(void) const { unsigned short result; mtx_user.lock(); result = speex_nb_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_speex_wb_payload_type(void) const { unsigned short result; mtx_user.lock(); result = speex_wb_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_speex_uwb_payload_type(void) const { unsigned short result; mtx_user.lock(); result = speex_uwb_payload_type; mtx_user.unlock(); return result; } t_bit_rate_type t_user::get_speex_bit_rate_type(void) const { t_bit_rate_type result; mtx_user.lock(); result = speex_bit_rate_type; mtx_user.unlock(); return result; } int t_user::get_speex_abr_nb(void) const { int result; mtx_user.lock(); result = speex_abr_nb; mtx_user.unlock(); return result; } int t_user::get_speex_abr_wb(void) const { int result; mtx_user.lock(); result = speex_abr_wb; mtx_user.unlock(); return result; } bool t_user::get_speex_dtx(void) const { bool result; mtx_user.lock(); result = speex_dtx; mtx_user.unlock(); return result; } bool t_user::get_speex_penh(void) const { bool result; mtx_user.lock(); result = speex_penh; mtx_user.unlock(); return result; } unsigned short t_user::get_speex_quality(void) const { unsigned short result; mtx_user.lock(); result = speex_quality; mtx_user.unlock(); return result; } unsigned short t_user::get_speex_complexity(void) const { unsigned short result; mtx_user.lock(); result = speex_complexity; mtx_user.unlock(); return result; } bool t_user::get_speex_dsp_vad(void) const { bool result; mtx_user.lock(); result = speex_dsp_vad; mtx_user.unlock(); return result; } bool t_user::get_speex_dsp_agc(void) const { bool result; mtx_user.lock(); result = speex_dsp_agc; mtx_user.unlock(); return result; } unsigned short t_user::get_speex_dsp_agc_level(void) const { unsigned short result; mtx_user.lock(); result = speex_dsp_agc_level; mtx_user.unlock(); return result; } bool t_user::get_speex_dsp_aec(void) const { bool result; mtx_user.lock(); result = speex_dsp_aec; mtx_user.unlock(); return result; } bool t_user::get_speex_dsp_nrd(void) const { bool result; mtx_user.lock(); result = speex_dsp_nrd; mtx_user.unlock(); return result; } unsigned short t_user::get_ilbc_payload_type(void) const { unsigned short result; mtx_user.lock(); result = ilbc_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_ilbc_mode(void) const { unsigned short result; mtx_user.lock(); result = ilbc_mode; mtx_user.unlock(); return result; } unsigned short t_user::get_g726_16_payload_type(void) const { unsigned short result; mtx_user.lock(); result = g726_16_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_g726_24_payload_type(void) const { unsigned short result; mtx_user.lock(); result = g726_24_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_g726_32_payload_type(void) const { unsigned short result; mtx_user.lock(); result = g726_32_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_g726_40_payload_type(void) const { unsigned short result; mtx_user.lock(); result = g726_40_payload_type; mtx_user.unlock(); return result; } t_g726_packing t_user::get_g726_packing(void) const { t_g726_packing result; mtx_user.lock(); result = g726_packing; mtx_user.unlock(); return result; } t_dtmf_transport t_user::get_dtmf_transport(void) const { t_dtmf_transport result; mtx_user.lock(); result = dtmf_transport; mtx_user.unlock(); return result; } unsigned short t_user::get_dtmf_payload_type(void) const { unsigned short result; mtx_user.lock(); result = dtmf_payload_type; mtx_user.unlock(); return result; } unsigned short t_user::get_dtmf_duration(void) const { unsigned short result; mtx_user.lock(); result = dtmf_duration; mtx_user.unlock(); return result; } unsigned short t_user::get_dtmf_pause(void) const { unsigned short result; mtx_user.lock(); result = dtmf_pause; mtx_user.unlock(); return result; } unsigned short t_user::get_dtmf_volume(void) const { unsigned short result; mtx_user.lock(); result = dtmf_volume; mtx_user.unlock(); return result; } t_hold_variant t_user::get_hold_variant(void) const { t_hold_variant result; mtx_user.lock(); result = hold_variant; mtx_user.unlock(); return result; } bool t_user::get_check_max_forwards(void) const { bool result; mtx_user.lock(); result = check_max_forwards; mtx_user.unlock(); return result; } bool t_user::get_allow_missing_contact_reg(void) const { bool result; mtx_user.lock(); result = allow_missing_contact_reg; mtx_user.unlock(); return result; } bool t_user::get_registration_time_in_contact(void) const { bool result; mtx_user.lock(); result = registration_time_in_contact; mtx_user.unlock(); return result; } bool t_user::get_compact_headers(void) const { bool result; mtx_user.lock(); result = compact_headers; mtx_user.unlock(); return result; } bool t_user::get_encode_multi_values_as_list(void) const { bool result; mtx_user.lock(); result = encode_multi_values_as_list; mtx_user.unlock(); return result; } bool t_user::get_use_domain_in_contact(void) const { bool result; mtx_user.lock(); result = use_domain_in_contact; mtx_user.unlock(); return result; } bool t_user::get_allow_sdp_change(void) const { bool result; mtx_user.lock(); result = allow_sdp_change; mtx_user.unlock(); return result; } bool t_user::get_allow_redirection(void) const { bool result; mtx_user.lock(); result = allow_redirection; mtx_user.unlock(); return result; } bool t_user::get_ask_user_to_redirect(void) const { bool result; mtx_user.lock(); result = ask_user_to_redirect; mtx_user.unlock(); return result; } unsigned short t_user::get_max_redirections(void) const { unsigned short result; mtx_user.lock(); result = max_redirections; mtx_user.unlock(); return result; } t_ext_support t_user::get_ext_100rel(void) const { t_ext_support result; mtx_user.lock(); result = ext_100rel; mtx_user.unlock(); return result; } bool t_user::get_ext_replaces(void) const { bool result; mtx_user.lock(); result = ext_replaces; mtx_user.unlock(); return result; } bool t_user::get_referee_hold(void) const { t_mutex_guard guard(mtx_user); return referee_hold; } bool t_user::get_referrer_hold(void) const { t_mutex_guard guard(mtx_user); return referrer_hold; } bool t_user::get_allow_refer(void) const { t_mutex_guard guard(mtx_user); return allow_refer; } bool t_user::get_ask_user_to_refer(void) const { t_mutex_guard guard(mtx_user); return ask_user_to_refer; } bool t_user::get_auto_refresh_refer_sub(void) const { t_mutex_guard guard(mtx_user); return auto_refresh_refer_sub; } bool t_user::get_attended_refer_to_aor(void) const { t_mutex_guard guard(mtx_user); return attended_refer_to_aor; } bool t_user::get_allow_transfer_consultation_inprog(void) const { t_mutex_guard guard(mtx_user); return allow_transfer_consultation_inprog; } bool t_user::get_send_p_preferred_id(void) const { bool result; mtx_user.lock(); result = send_p_preferred_id; mtx_user.unlock(); return result; } t_sip_transport t_user::get_sip_transport(void) const { t_mutex_guard guard(mtx_user); return sip_transport; } unsigned short t_user::get_sip_transport_udp_threshold(void) const { t_mutex_guard guard(mtx_user); return sip_transport_udp_threshold; } bool t_user::get_use_nat_public_ip(void) const { bool result; mtx_user.lock(); result = use_nat_public_ip; mtx_user.unlock(); return result; } string t_user::get_nat_public_ip(void) const { string result; mtx_user.lock(); result = nat_public_ip; mtx_user.unlock(); return result; } bool t_user::get_use_stun(void) const { bool result; mtx_user.lock(); result = use_stun; mtx_user.unlock(); return result; } t_url t_user::get_stun_server(void) const { t_url result; mtx_user.lock(); result = stun_server; mtx_user.unlock(); return result; } bool t_user::get_persistent_tcp(void) const { t_mutex_guard guard(mtx_user); return persistent_tcp; } bool t_user::get_enable_nat_keepalive(void) const { t_mutex_guard guard(mtx_user); return enable_nat_keepalive; } unsigned short t_user::get_timer_noanswer(void) const { unsigned short result; mtx_user.lock(); result = timer_noanswer; mtx_user.unlock(); return result; } unsigned short t_user::get_timer_nat_keepalive(void) const { unsigned short result; mtx_user.lock(); result = timer_nat_keepalive; mtx_user.unlock(); return result; } unsigned short t_user::get_timer_tcp_ping(void) const { t_mutex_guard guard(mtx_user); return timer_tcp_ping; } bool t_user::get_display_useronly_phone(void) const { bool result; mtx_user.lock(); result = display_useronly_phone; mtx_user.unlock(); return result; } bool t_user::get_numerical_user_is_phone(void) const { bool result; mtx_user.lock(); result = numerical_user_is_phone; mtx_user.unlock(); return result; } bool t_user::get_remove_special_phone_symbols(void) const { bool result; mtx_user.lock(); result = remove_special_phone_symbols; mtx_user.unlock(); return result; } string t_user::get_special_phone_symbols(void) const { string result; mtx_user.lock(); result = special_phone_symbols; mtx_user.unlock(); return result; } bool t_user::get_use_tel_uri_for_phone(void) const { t_mutex_guard guard(mtx_user); return use_tel_uri_for_phone; } string t_user::get_ringtone_file(void) const { string result; mtx_user.lock(); result = ringtone_file; mtx_user.unlock(); return result; } string t_user::get_ringback_file(void) const { string result; mtx_user.lock(); result = ringback_file; mtx_user.unlock(); return result; } string t_user::get_script_incoming_call(void) const { string result; mtx_user.lock(); result = script_incoming_call; mtx_user.unlock(); return result; } string t_user::get_script_in_call_answered(void) const { string result; mtx_user.lock(); result = script_in_call_answered; mtx_user.unlock(); return result; } string t_user::get_script_in_call_failed(void) const { string result; mtx_user.lock(); result = script_in_call_failed; mtx_user.unlock(); return result; } string t_user::get_script_outgoing_call(void) const { string result; mtx_user.lock(); result = script_outgoing_call; mtx_user.unlock(); return result; } string t_user::get_script_out_call_answered(void) const { string result; mtx_user.lock(); result = script_out_call_answered; mtx_user.unlock(); return result; } string t_user::get_script_out_call_failed(void) const { string result; mtx_user.lock(); result = script_out_call_failed; mtx_user.unlock(); return result; } string t_user::get_script_local_release(void) const { string result; mtx_user.lock(); result = script_local_release; mtx_user.unlock(); return result; } string t_user::get_script_remote_release(void) const { string result; mtx_user.lock(); result = script_remote_release; mtx_user.unlock(); return result; } list t_user::get_number_conversions(void) const { list result; mtx_user.lock(); result = number_conversions; mtx_user.unlock(); return result; } bool t_user::get_zrtp_enabled(void) const { bool result; mtx_user.lock(); result = zrtp_enabled; mtx_user.unlock(); return result; } bool t_user::get_zrtp_goclear_warning(void) const { bool result; mtx_user.lock(); result = zrtp_goclear_warning; mtx_user.unlock(); return result; } bool t_user::get_zrtp_sdp(void) const { bool result; mtx_user.lock(); result = zrtp_sdp; mtx_user.unlock(); return result; } bool t_user::get_zrtp_send_if_supported(void) const { bool result; mtx_user.lock(); result = zrtp_send_if_supported; mtx_user.unlock(); return result; } bool t_user::get_mwi_sollicited(void) const { bool result; mtx_user.lock(); result = mwi_sollicited; mtx_user.unlock(); return result; } string t_user::get_mwi_user(void) const { string result; mtx_user.lock(); result = mwi_user; mtx_user.unlock(); return result; } t_url t_user::get_mwi_server(void) const { t_url result; mtx_user.lock(); result = mwi_server; mtx_user.unlock(); return result; } bool t_user::get_mwi_via_proxy(void) const { bool result; mtx_user.lock(); result = mwi_via_proxy; mtx_user.unlock(); return result; } unsigned long t_user::get_mwi_subscription_time(void) const { unsigned long result; mtx_user.lock(); result = mwi_subscription_time; mtx_user.unlock(); return result; } string t_user::get_mwi_vm_address(void) const { string result; mtx_user.lock(); result = mwi_vm_address; mtx_user.unlock(); return result; } unsigned short t_user::get_im_max_sessions(void) const { unsigned short result; mtx_user.lock(); result = im_max_sessions; mtx_user.unlock(); return result; } bool t_user::get_im_send_iscomposing(void) const { t_mutex_guard guard(mtx_user); return im_send_iscomposing; } unsigned long t_user::get_pres_subscription_time(void) const { unsigned long result; mtx_user.lock(); result = pres_subscription_time; mtx_user.unlock(); return result; } unsigned long t_user::get_pres_publication_time(void) const { unsigned long result; mtx_user.lock(); result = pres_publication_time; mtx_user.unlock(); return result; } bool t_user::get_pres_publish_startup(void) const { bool result; mtx_user.lock(); result = pres_publish_startup; mtx_user.unlock(); return result; } void t_user::set_name(const string &_name) { mtx_user.lock(); name = _name; mtx_user.unlock(); } void t_user::set_domain(const string &_domain) { mtx_user.lock(); domain = _domain; mtx_user.unlock(); } void t_user::set_display(const string &_display) { mtx_user.lock(); display = _display; mtx_user.unlock(); } void t_user::set_organization(const string &_organization) { mtx_user.lock(); organization = _organization; mtx_user.unlock(); } void t_user::set_auth_realm(const string &realm) { mtx_user.lock(); auth_realm = realm; mtx_user.unlock(); } void t_user::set_auth_name(const string &name) { mtx_user.lock(); auth_name = name; mtx_user.unlock(); } void t_user::set_auth_pass(const string &pass) { mtx_user.lock(); auth_pass = pass; mtx_user.unlock(); } void t_user::set_auth_aka_op(const uint8 *aka_op) { t_mutex_guard guard(mtx_user); memcpy(auth_aka_op, aka_op, AKA_OPLEN); } void t_user::set_auth_aka_amf(const uint8 *aka_amf) { t_mutex_guard guard(mtx_user); memcpy(auth_aka_amf, aka_amf, AKA_AMFLEN); } void t_user::set_use_outbound_proxy(bool b) { mtx_user.lock(); use_outbound_proxy = b; mtx_user.unlock(); } void t_user::set_outbound_proxy(const t_url &url) { mtx_user.lock(); outbound_proxy = url; mtx_user.unlock(); } void t_user::set_all_requests_to_proxy(bool b) { mtx_user.lock(); all_requests_to_proxy = b; mtx_user.unlock(); } void t_user::set_non_resolvable_to_proxy(bool b) { mtx_user.lock(); non_resolvable_to_proxy = b; mtx_user.unlock(); } void t_user::set_use_registrar(bool b) { mtx_user.lock(); use_registrar = b; mtx_user.unlock(); } void t_user::set_registrar(const t_url &url) { mtx_user.lock(); registrar = url; mtx_user.unlock(); } void t_user::set_registration_time(const unsigned long time) { mtx_user.lock(); registration_time = time; mtx_user.unlock(); } void t_user::set_register_at_startup(bool b) { mtx_user.lock(); register_at_startup = b; mtx_user.unlock(); } void t_user::set_reg_add_qvalue(bool b) { mtx_user.lock(); reg_add_qvalue = b; mtx_user.unlock(); } void t_user::set_reg_qvalue(float q) { mtx_user.lock(); reg_qvalue = q; mtx_user.unlock(); } void t_user::set_codecs(const list &_codecs) { mtx_user.lock(); codecs = _codecs; mtx_user.unlock(); } void t_user::set_ptime(unsigned short _ptime) { mtx_user.lock(); ptime = _ptime; mtx_user.unlock(); } void t_user::set_out_obey_far_end_codec_pref(bool b) { mtx_user.lock(); out_obey_far_end_codec_pref = b; mtx_user.unlock(); } void t_user::set_in_obey_far_end_codec_pref(bool b) { mtx_user.lock(); in_obey_far_end_codec_pref = b; mtx_user.unlock(); } void t_user::set_speex_nb_payload_type(unsigned short payload_type) { mtx_user.lock(); speex_nb_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_speex_wb_payload_type(unsigned short payload_type) { mtx_user.lock(); speex_wb_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_speex_uwb_payload_type(unsigned short payload_type) { mtx_user.lock(); speex_uwb_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_speex_bit_rate_type(t_bit_rate_type bit_rate_type) { mtx_user.lock(); speex_bit_rate_type = bit_rate_type; mtx_user.unlock(); } void t_user::set_speex_abr_nb(int abr) { mtx_user.lock(); speex_abr_nb = abr; mtx_user.unlock(); } void t_user::set_speex_abr_wb(int abr) { mtx_user.lock(); speex_abr_wb = abr; mtx_user.unlock(); } void t_user::set_speex_dtx(bool b) { mtx_user.lock(); speex_dtx = b; mtx_user.unlock(); } void t_user::set_speex_penh(bool b) { mtx_user.lock(); speex_penh = b; mtx_user.unlock(); } void t_user::set_speex_quality(unsigned short quality) { mtx_user.lock(); speex_quality = quality; mtx_user.unlock(); } void t_user::set_speex_complexity(unsigned short complexity) { mtx_user.lock(); speex_complexity = complexity; mtx_user.unlock(); } void t_user::set_speex_dsp_vad(bool b) { mtx_user.lock(); speex_dsp_vad = b; mtx_user.unlock(); } void t_user::set_speex_dsp_agc(bool b) { mtx_user.lock(); speex_dsp_agc = b; mtx_user.unlock(); } void t_user::set_speex_dsp_agc_level(unsigned short level) { mtx_user.lock(); speex_dsp_agc_level = level; mtx_user.unlock(); } void t_user::set_speex_dsp_aec(bool b) { mtx_user.lock(); speex_dsp_aec = b; mtx_user.unlock(); } void t_user::set_speex_dsp_nrd(bool b) { mtx_user.lock(); speex_dsp_nrd = b; mtx_user.unlock(); } void t_user::set_ilbc_payload_type(unsigned short payload_type) { mtx_user.lock(); ilbc_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_ilbc_mode(unsigned short mode) { mtx_user.lock(); ilbc_mode = mode; mtx_user.unlock(); } void t_user::set_g726_16_payload_type(unsigned short payload_type) { mtx_user.lock(); g726_16_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_g726_24_payload_type(unsigned short payload_type) { mtx_user.lock(); g726_24_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_g726_32_payload_type(unsigned short payload_type) { mtx_user.lock(); g726_32_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_g726_40_payload_type(unsigned short payload_type) { mtx_user.lock(); g726_40_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_g726_packing(t_g726_packing packing) { mtx_user.lock(); g726_packing = packing; mtx_user.unlock(); } void t_user::set_dtmf_transport(t_dtmf_transport _dtmf_transport) { mtx_user.lock(); dtmf_transport = _dtmf_transport; mtx_user.unlock(); } void t_user::set_dtmf_payload_type(unsigned short payload_type) { mtx_user.lock(); dtmf_payload_type = payload_type; mtx_user.unlock(); } void t_user::set_dtmf_duration(unsigned short duration) { mtx_user.lock(); dtmf_duration = duration; mtx_user.unlock(); } void t_user::set_dtmf_pause(unsigned short pause) { mtx_user.lock(); dtmf_pause = pause; mtx_user.unlock(); } void t_user::set_dtmf_volume(unsigned short volume) { mtx_user.lock(); dtmf_volume = volume; mtx_user.unlock(); } void t_user::set_hold_variant(t_hold_variant _hold_variant) { mtx_user.lock(); hold_variant = _hold_variant; mtx_user.unlock(); } void t_user::set_check_max_forwards(bool b) { mtx_user.lock(); check_max_forwards = b; mtx_user.unlock(); } void t_user::set_allow_missing_contact_reg(bool b) { mtx_user.lock(); allow_missing_contact_reg = b; mtx_user.unlock(); } void t_user::set_registration_time_in_contact(bool b) { mtx_user.lock(); registration_time_in_contact = b; mtx_user.unlock(); } void t_user::set_compact_headers(bool b) { mtx_user.lock(); compact_headers = b; mtx_user.unlock(); } void t_user::set_encode_multi_values_as_list(bool b) { mtx_user.lock(); encode_multi_values_as_list = b; mtx_user.unlock(); } void t_user::set_use_domain_in_contact(bool b) { mtx_user.lock(); use_domain_in_contact = b; mtx_user.unlock(); } void t_user::set_allow_sdp_change(bool b) { mtx_user.lock(); allow_sdp_change = b; mtx_user.unlock(); } void t_user::set_allow_redirection(bool b) { mtx_user.lock(); allow_redirection = b; mtx_user.unlock(); } void t_user::set_ask_user_to_redirect(bool b) { mtx_user.lock(); ask_user_to_redirect = b; mtx_user.unlock(); } void t_user::set_max_redirections(unsigned short _max_redirections) { mtx_user.lock(); max_redirections = _max_redirections; mtx_user.unlock(); } void t_user::set_ext_100rel(t_ext_support ext_support) { mtx_user.lock(); ext_100rel = ext_support; mtx_user.unlock(); } void t_user::set_ext_replaces(bool b) { mtx_user.lock(); ext_replaces = b; mtx_user.unlock(); } void t_user::set_referee_hold(bool b) { t_mutex_guard guard(mtx_user); referee_hold = b; } void t_user::set_referrer_hold(bool b) { mtx_user.lock(); referrer_hold = b; mtx_user.unlock(); } void t_user::set_allow_refer(bool b) { t_mutex_guard guard(mtx_user); allow_refer = b; } void t_user::set_ask_user_to_refer(bool b) { t_mutex_guard guard(mtx_user); ask_user_to_refer = b; } void t_user::set_auto_refresh_refer_sub(bool b) { t_mutex_guard guard(mtx_user); auto_refresh_refer_sub = b; } void t_user::set_attended_refer_to_aor(bool b) { t_mutex_guard guard(mtx_user); attended_refer_to_aor = b; } void t_user::set_allow_transfer_consultation_inprog(bool b) { t_mutex_guard guard(mtx_user); allow_transfer_consultation_inprog = b; } void t_user::set_send_p_preferred_id(bool b) { mtx_user.lock(); send_p_preferred_id = b; mtx_user.unlock(); } void t_user::set_sip_transport(t_sip_transport transport) { t_mutex_guard guard(mtx_user); sip_transport = transport; } void t_user::set_sip_transport_udp_threshold(unsigned short threshold) { t_mutex_guard guard(mtx_user); sip_transport_udp_threshold = threshold; } void t_user::set_use_nat_public_ip(bool b) { mtx_user.lock(); use_nat_public_ip = b; mtx_user.unlock(); } void t_user::set_nat_public_ip(const string &public_ip) { mtx_user.lock(); nat_public_ip = public_ip; mtx_user.unlock(); } void t_user::set_use_stun(bool b) { mtx_user.lock(); use_stun = b; mtx_user.unlock(); } void t_user::set_stun_server(const t_url &url) { mtx_user.lock(); stun_server = url; mtx_user.unlock(); } void t_user::set_persistent_tcp(bool b) { t_mutex_guard guard(mtx_user); persistent_tcp = b; } void t_user::set_enable_nat_keepalive(bool b) { t_mutex_guard guard(mtx_user); enable_nat_keepalive = b; } void t_user::set_timer_noanswer(unsigned short timer) { mtx_user.lock(); timer_noanswer = timer; mtx_user.unlock(); } void t_user::set_timer_nat_keepalive(unsigned short timer) { mtx_user.lock(); timer_nat_keepalive = timer; mtx_user.unlock(); } void t_user::set_timer_tcp_ping(unsigned short timer) { t_mutex_guard guard(mtx_user); timer_tcp_ping = timer; } void t_user::set_display_useronly_phone(bool b) { mtx_user.lock(); display_useronly_phone = b; mtx_user.unlock(); } void t_user::set_numerical_user_is_phone(bool b) { mtx_user.lock(); numerical_user_is_phone = b; mtx_user.unlock(); } void t_user::set_remove_special_phone_symbols(bool b) { mtx_user.lock(); remove_special_phone_symbols = b; mtx_user.unlock(); } void t_user::set_special_phone_symbols(const string &symbols) { mtx_user.lock(); special_phone_symbols = symbols; mtx_user.unlock(); } void t_user::set_use_tel_uri_for_phone(bool b) { t_mutex_guard guard(mtx_user); use_tel_uri_for_phone = b; } void t_user::set_ringtone_file(const string &file) { mtx_user.lock(); ringtone_file = file; mtx_user.unlock(); } void t_user::set_ringback_file(const string &file) { mtx_user.lock(); ringback_file = file; mtx_user.unlock(); } void t_user::set_script_incoming_call(const string &script) { mtx_user.lock(); script_incoming_call = script; mtx_user.unlock(); } void t_user::set_script_in_call_answered(const string &script) { mtx_user.lock(); script_in_call_answered = script; mtx_user.unlock(); } void t_user::set_script_in_call_failed(const string &script) { mtx_user.lock(); script_in_call_failed = script; mtx_user.unlock(); } void t_user::set_script_outgoing_call(const string &script) { mtx_user.lock(); script_outgoing_call = script; mtx_user.unlock(); } void t_user::set_script_out_call_answered(const string &script) { mtx_user.lock(); script_out_call_answered = script; mtx_user.unlock(); } void t_user::set_script_out_call_failed(const string &script) { mtx_user.lock(); script_out_call_failed = script; mtx_user.unlock(); } void t_user::set_script_local_release(const string &script) { mtx_user.lock(); script_local_release = script; mtx_user.unlock(); } void t_user::set_script_remote_release(const string &script) { mtx_user.lock(); script_remote_release = script; mtx_user.unlock(); } void t_user::set_number_conversions(const list &l) { mtx_user.lock(); number_conversions = l; mtx_user.unlock(); } void t_user::set_zrtp_enabled(bool b) { mtx_user.lock(); zrtp_enabled = b; mtx_user.unlock(); } void t_user::set_zrtp_goclear_warning(bool b) { mtx_user.lock(); zrtp_goclear_warning = b; mtx_user.unlock(); } void t_user::set_zrtp_sdp(bool b) { mtx_user.lock(); zrtp_sdp = b; mtx_user.unlock(); } void t_user::set_zrtp_send_if_supported(bool b) { mtx_user.lock(); zrtp_send_if_supported = b; mtx_user.unlock(); } void t_user::set_mwi_sollicited(bool b) { mtx_user.lock(); mwi_sollicited = b; mtx_user.unlock(); } void t_user::set_mwi_user(const string &user) { mtx_user.lock(); mwi_user = user; mtx_user.unlock(); } void t_user::set_mwi_server(const t_url &url) { mtx_user.lock(); mwi_server = url; mtx_user.unlock(); } void t_user::set_mwi_via_proxy(bool b) { mtx_user.lock(); mwi_via_proxy = b; mtx_user.unlock(); } void t_user::set_mwi_subscription_time(unsigned long t) { mtx_user.lock(); mwi_subscription_time = t; mtx_user.unlock(); } void t_user::set_mwi_vm_address(const string &address) { mtx_user.lock(); mwi_vm_address = address; mtx_user.unlock(); } void t_user::set_im_max_sessions(unsigned short max_sessions) { mtx_user.lock(); im_max_sessions = max_sessions; mtx_user.unlock(); } void t_user::set_im_send_iscomposing(bool b) { t_mutex_guard guard(mtx_user); im_send_iscomposing = b; } void t_user::set_pres_subscription_time(unsigned long t) { mtx_user.lock(); pres_subscription_time = t; mtx_user.unlock(); } void t_user::set_pres_publication_time(unsigned long t) { mtx_user.lock(); pres_publication_time = t; mtx_user.unlock(); } void t_user::set_pres_publish_startup(bool b) { mtx_user.lock(); pres_publish_startup = b; mtx_user.unlock(); } bool t_user::read_config(const string &filename, string &error_msg) { string f; string msg; mtx_user.lock(); if (filename.size() == 0) { error_msg = "Cannot read user profile: missing file name."; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } config_filename = filename; f = expand_filename(filename); ifstream config(f.c_str()); if (!config) { error_msg = "Cannot open file for reading: "; error_msg += f; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } log_file->write_header("t_user::read_config"); log_file->write_raw("Reading config: "); log_file->write_raw(filename); log_file->write_endl(); log_file->write_footer(); while (!config.eof()) { string line; getline(config, line); // Check if read operation succeeded if (!config.good() && !config.eof()) { error_msg = "File system error while reading file "; error_msg += f; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } line = trim(line); // Skip empty lines if (line.size() == 0) continue; // Skip comment lines if (line[0] == '#') continue; vector l = split_on_first(line, '='); if (l.size() != 2) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += line; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } string parameter = trim(l[0]); string value = trim(l[1]); if (parameter == FLD_NAME) { name = value; } else if (parameter == FLD_DOMAIN) { domain = value; } else if (parameter == FLD_DISPLAY) { display = value; } else if (parameter == FLD_ORGANIZATION) { organization = value; } else if (parameter == FLD_REGISTRATION_TIME) { registration_time = atol(value.c_str()); } else if (parameter == FLD_REGISTRATION_TIME_IN_CONTACT) { registration_time_in_contact = yesno2bool(value); } else if (parameter == FLD_REGISTRAR) { use_registrar = set_server_value(registrar, USER_SCHEME, value); } else if (parameter == FLD_REGISTER_AT_STARTUP) { register_at_startup = yesno2bool(value); } else if (parameter == FLD_REG_ADD_QVALUE) { reg_add_qvalue = yesno2bool(value); } else if (parameter == FLD_REG_QVALUE) { reg_qvalue = atof(value.c_str()); } else if (parameter == FLD_OUTBOUND_PROXY) { use_outbound_proxy = set_server_value(outbound_proxy, USER_SCHEME, value); } else if (parameter == FLD_ALL_REQUESTS_TO_PROXY) { all_requests_to_proxy = yesno2bool(value); } else if (parameter == FLD_NON_RESOLVABLE_TO_PROXY) { non_resolvable_to_proxy = yesno2bool(value); } else if (parameter == FLD_AUTH_REALM) { auth_realm = value; } else if (parameter == FLD_AUTH_NAME) { auth_name = value; } else if (parameter == FLD_AUTH_PASS) { auth_pass = value; } else if (parameter == FLD_AUTH_AKA_OP) { hex2binary(value, auth_aka_op); } else if (parameter == FLD_AUTH_AKA_AMF) { hex2binary(value, auth_aka_amf); } else if (parameter == FLD_CODECS) { vector l = split(value, ','); if (l.size() > 0) codecs.clear(); for (vector::iterator i = l.begin(); i != l.end(); i++) { string codec = trim(*i); if (codec == "g711a") { codecs.push_back(CODEC_G711_ALAW); } else if (codec == "g711u") { codecs.push_back(CODEC_G711_ULAW); } else if (codec == "gsm") { codecs.push_back(CODEC_GSM); #ifdef HAVE_SPEEX } else if (codec == "speex-nb") { codecs.push_back(CODEC_SPEEX_NB); } else if (codec == "speex-wb") { codecs.push_back(CODEC_SPEEX_WB); } else if (codec == "speex-uwb") { codecs.push_back(CODEC_SPEEX_UWB); #endif #ifdef HAVE_ILBC } else if (codec == "ilbc") { codecs.push_back(CODEC_ILBC); #endif } else if (codec == "g726-16") { codecs.push_back(CODEC_G726_16); } else if (codec == "g726-24") { codecs.push_back(CODEC_G726_24); } else if (codec == "g726-32") { codecs.push_back(CODEC_G726_32); } else if (codec == "g726-40") { codecs.push_back(CODEC_G726_40); } else { msg = "Syntax error in file "; msg += f; msg += "\n"; msg += "Invalid codec: "; msg += value; log_file->write_report(msg, "t_user::read_config", LOG_NORMAL, LOG_WARNING); } } } else if (parameter == FLD_PTIME) { ptime = atoi(value.c_str()); } else if (parameter == FLD_OUT_FAR_END_CODEC_PREF) { out_obey_far_end_codec_pref = yesno2bool(value); } else if (parameter == FLD_IN_FAR_END_CODEC_PREF) { in_obey_far_end_codec_pref = yesno2bool(value); } else if (parameter == FLD_HOLD_VARIANT) { if (value == "rfc2543") { hold_variant = HOLD_RFC2543; } else if (value == "rfc3264") { hold_variant = HOLD_RFC3264; } else { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += "Invalid hold variant: "; error_msg += value; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } else if (parameter == FLD_CHECK_MAX_FORWARDS) { check_max_forwards = yesno2bool(value); } else if (parameter == FLD_ALLOW_MISSING_CONTACT_REG) { allow_missing_contact_reg = yesno2bool(value); } else if (parameter == FLD_USE_DOMAIN_IN_CONTACT) { use_domain_in_contact = yesno2bool(value); } else if (parameter == FLD_ALLOW_SDP_CHANGE) { allow_sdp_change = yesno2bool(value); } else if (parameter == FLD_ALLOW_REDIRECTION) { allow_redirection = yesno2bool(value); } else if (parameter == FLD_ASK_USER_TO_REDIRECT) { ask_user_to_redirect = yesno2bool(value); } else if (parameter == FLD_MAX_REDIRECTIONS) { max_redirections = atoi(value.c_str()); } else if (parameter == FLD_REFEREE_HOLD) { referee_hold = yesno2bool(value); } else if (parameter == FLD_REFERRER_HOLD) { referrer_hold = yesno2bool(value); } else if (parameter == FLD_ALLOW_REFER) { allow_refer = yesno2bool(value); } else if (parameter == FLD_ASK_USER_TO_REFER) { ask_user_to_refer = yesno2bool(value); } else if (parameter == FLD_AUTO_REFRESH_REFER_SUB) { auto_refresh_refer_sub = yesno2bool(value); } else if (parameter == FLD_ATTENDED_REFER_TO_AOR) { attended_refer_to_aor = yesno2bool(value); } else if (parameter == FLD_ALLOW_XFER_CONSULT_INPROG) { allow_transfer_consultation_inprog = yesno2bool(value); } else if (parameter == FLD_SEND_P_PREFERRED_ID) { send_p_preferred_id = yesno2bool(value); } else if (parameter == FLD_SIP_TRANSPORT) { sip_transport = str2sip_transport(value); } else if (parameter == FLD_SIP_TRANSPORT_UDP_THRESHOLD) { sip_transport_udp_threshold = atoi(value.c_str()); } else if (parameter == FLD_NAT_PUBLIC_IP) { if (value.size() == 0) continue; use_nat_public_ip = true; nat_public_ip = value; } else if (parameter == FLD_STUN_SERVER) { use_stun = set_server_value(stun_server, "stun", value); } else if (parameter == FLD_PERSISTENT_TCP) { persistent_tcp = yesno2bool(value); } else if (parameter == FLD_ENABLE_NAT_KEEPALIVE) { enable_nat_keepalive = yesno2bool(value); } else if (parameter == FLD_TIMER_NOANSWER) { timer_noanswer = atoi(value.c_str()); } else if (parameter == FLD_TIMER_NAT_KEEPALIVE) { timer_nat_keepalive = atoi(value.c_str()); } else if (parameter == FLD_TIMER_TCP_PING) { timer_tcp_ping = atoi(value.c_str()); } else if (parameter == FLD_EXT_100REL) { ext_100rel = str2ext_support(value); if (ext_100rel == EXT_INVALID) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += "Invalid value for ext_100rel: "; error_msg += value; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } else if (parameter == FLD_EXT_REPLACES) { ext_replaces = yesno2bool(value); } else if (parameter == FLD_COMPACT_HEADERS) { compact_headers = yesno2bool(value); } else if (parameter == FLD_ENCODE_MULTI_VALUES_AS_LIST) { encode_multi_values_as_list = yesno2bool(value); } else if (parameter == FLD_SPEEX_NB_PAYLOAD_TYPE) { speex_nb_payload_type = atoi(value.c_str()); } else if (parameter == FLD_SPEEX_WB_PAYLOAD_TYPE) { speex_wb_payload_type = atoi(value.c_str()); } else if (parameter == FLD_SPEEX_UWB_PAYLOAD_TYPE) { speex_uwb_payload_type = atoi(value.c_str()); } else if (parameter == FLD_SPEEX_BIT_RATE_TYPE) { speex_bit_rate_type = str2bit_rate_type(value); if (speex_bit_rate_type == BIT_RATE_INVALID) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += "Invalid value for speex bit rate type: "; error_msg += value; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } else if (parameter == FLD_SPEEX_ABR_NB) { speex_abr_nb = atoi(value.c_str()); } else if (parameter == FLD_SPEEX_ABR_WB) { speex_abr_wb = atoi(value.c_str()); } else if (parameter == FLD_SPEEX_DTX) { speex_dtx = yesno2bool(value); } else if (parameter == FLD_SPEEX_PENH) { speex_penh = yesno2bool(value); } else if (parameter == FLD_SPEEX_QUALITY) { speex_quality = atoi(value.c_str()); if (speex_quality > 10) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += "Invalid value for speex quality: "; error_msg += value; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } else if (parameter == FLD_SPEEX_COMPLEXITY) { speex_complexity = atoi(value.c_str()); if (speex_complexity < 1 || speex_complexity > 10) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += "Invalid value for speex complexity: "; error_msg += value; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } else if (parameter == FLD_SPEEX_DSP_VAD) { speex_dsp_vad = yesno2bool(value); } else if (parameter == FLD_SPEEX_DSP_AGC) { speex_dsp_agc = yesno2bool(value); } else if (parameter == FLD_SPEEX_DSP_AEC) { speex_dsp_aec = yesno2bool(value); } else if (parameter == FLD_SPEEX_DSP_NRD) { speex_dsp_nrd = yesno2bool(value); } else if (parameter == FLD_SPEEX_DSP_AGC_LEVEL) { speex_dsp_agc_level = atoi(value.c_str()); if (speex_dsp_agc_level < 1 || speex_dsp_agc_level > 100) { error_msg = "Syntax error in file "; error_msg += f; error_msg += "\n"; error_msg += "Invalid value for automatic gain control level: "; error_msg += value; log_file->write_report(error_msg, "t_user::read_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } else if (parameter == FLD_ILBC_PAYLOAD_TYPE) { ilbc_payload_type = atoi(value.c_str()); } else if (parameter == FLD_ILBC_MODE) { ilbc_mode = atoi(value.c_str()); } else if (parameter == FLD_G726_16_PAYLOAD_TYPE) { g726_16_payload_type = atoi(value.c_str()); } else if (parameter == FLD_G726_24_PAYLOAD_TYPE) { g726_24_payload_type = atoi(value.c_str()); } else if (parameter == FLD_G726_32_PAYLOAD_TYPE) { g726_32_payload_type = atoi(value.c_str()); } else if (parameter == FLD_G726_40_PAYLOAD_TYPE) { g726_40_payload_type = atoi(value.c_str()); } else if (parameter == FLD_G726_PACKING) { g726_packing = str2g726_packing(value); } else if (parameter == FLD_DTMF_TRANSPORT) { dtmf_transport = str2dtmf_transport(value); } else if (parameter == FLD_DTMF_PAYLOAD_TYPE) { dtmf_payload_type = atoi(value.c_str()); } else if (parameter == FLD_DTMF_DURATION) { dtmf_duration = atoi(value.c_str()); } else if (parameter == FLD_DTMF_PAUSE) { dtmf_pause = atoi(value.c_str()); } else if (parameter == FLD_DTMF_VOLUME) { dtmf_volume = atoi(value.c_str()); } else if (parameter == FLD_DISPLAY_USERONLY_PHONE) { display_useronly_phone = yesno2bool(value); } else if (parameter == FLD_NUMERICAL_USER_IS_PHONE) { numerical_user_is_phone = yesno2bool(value); } else if (parameter == FLD_REMOVE_SPECIAL_PHONE_SYM) { remove_special_phone_symbols = yesno2bool(value); } else if (parameter == FLD_SPECIAL_PHONE_SYMBOLS) { special_phone_symbols = value; } else if (parameter == FLD_USE_TEL_URI_FOR_PHONE) { use_tel_uri_for_phone = yesno2bool(value); } else if (parameter == FLD_USER_RINGTONE_FILE) { ringtone_file = value; } else if (parameter == FLD_USER_RINGBACK_FILE) { ringback_file = value; } else if (parameter == FLD_SCRIPT_INCOMING_CALL) { script_incoming_call = value; } else if (parameter == FLD_SCRIPT_IN_CALL_ANSWERED) { script_in_call_answered = value; } else if (parameter == FLD_SCRIPT_IN_CALL_FAILED) { script_in_call_failed = value; } else if (parameter == FLD_SCRIPT_OUTGOING_CALL) { script_outgoing_call = value; } else if (parameter == FLD_SCRIPT_OUT_CALL_ANSWERED) { script_out_call_answered = value; } else if (parameter == FLD_SCRIPT_OUT_CALL_FAILED) { script_out_call_failed = value; } else if (parameter == FLD_SCRIPT_LOCAL_RELEASE) { script_local_release = value; } else if (parameter == FLD_SCRIPT_REMOTE_RELEASE) { script_remote_release = value; } else if (parameter == FLD_NUMBER_CONVERSION) { t_number_conversion c; if (parse_num_conversion(value, c)) { number_conversions.push_back(c); } } else if (parameter == FLD_ZRTP_ENABLED) { zrtp_enabled = yesno2bool(value); } else if (parameter == FLD_ZRTP_GOCLEAR_WARNING) { zrtp_goclear_warning = yesno2bool(value); } else if (parameter == FLD_ZRTP_SDP) { zrtp_sdp = yesno2bool(value); } else if (parameter == FLD_ZRTP_SEND_IF_SUPPORTED) { zrtp_send_if_supported = yesno2bool(value); } else if (parameter == FLD_MWI_SOLLICITED) { mwi_sollicited = yesno2bool(value); } else if (parameter == FLD_MWI_USER) { mwi_user = value; } else if (parameter == FLD_MWI_SERVER) { (void)set_server_value(mwi_server, USER_SCHEME, value); } else if (parameter == FLD_MWI_VIA_PROXY) { mwi_via_proxy = yesno2bool(value); } else if (parameter == FLD_MWI_SUBSCRIPTION_TIME) { mwi_subscription_time = atol(value.c_str()); } else if (parameter == FLD_MWI_VM_ADDRESS) { mwi_vm_address = value; } else if (parameter == FLD_IM_MAX_SESSIONS) { im_max_sessions = atoi(value.c_str()); } else if (parameter == FLD_IM_SEND_ISCOMPOSING) { im_send_iscomposing = yesno2bool(value); } else if (parameter == FLD_PRES_SUBSCRIPTION_TIME) { pres_subscription_time = atol(value.c_str()); } else if (parameter == FLD_PRES_PUBLICATION_TIME) { pres_publication_time = atol(value.c_str()); } else if (parameter == FLD_PRES_PUBLISH_STARTUP) { pres_publish_startup = yesno2bool(value); } else { // Ignore unknown parameters. Only report in log file. log_file->write_header("t_user::read_config", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Unknown parameter in user profile: "); log_file->write_raw(parameter); log_file->write_endl(); log_file->write_footer(); } } // Set parser options t_parser::check_max_forwards = check_max_forwards; t_parser::compact_headers = compact_headers; t_parser::multi_values_as_list = encode_multi_values_as_list; mtx_user.unlock(); return true; } bool t_user::write_config(const string &filename, string &error_msg) { struct stat stat_buf; string f; mtx_user.lock(); if (filename.size() == 0) { error_msg = "Cannot write user profile: missing file name."; log_file->write_report(error_msg, "t_user::write_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } config_filename = filename; f = expand_filename(filename); // Make a backup of the file if we are editing an existing file, so // that can be restored when writing fails. string f_backup = f + '~'; if (stat(f.c_str(), &stat_buf) == 0) { if (rename(f.c_str(), f_backup.c_str()) != 0) { string err = get_error_str(errno); error_msg = "Failed to backup "; error_msg += f; error_msg += " to "; error_msg += f_backup; error_msg += "\n"; error_msg += err; log_file->write_report(error_msg, "t_user::write_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } } ofstream config(f.c_str()); if (!config) { error_msg = "Cannot open file for writing: "; error_msg += f; log_file->write_report(error_msg, "t_user::write_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } log_file->write_header("t_user::write_config"); log_file->write_raw("Writing config: "); log_file->write_raw(filename); log_file->write_endl(); log_file->write_footer(); // Write USER settings config << "# USER\n"; config << FLD_NAME << '=' << name << endl; config << FLD_DOMAIN << '=' << domain << endl; config << FLD_DISPLAY << '=' << display << endl; config << FLD_ORGANIZATION << '=' << organization << endl; config << FLD_AUTH_REALM << '=' << auth_realm << endl; config << FLD_AUTH_NAME << '=' << auth_name << endl; config << FLD_AUTH_PASS << '=' << auth_pass << endl; config << FLD_AUTH_AKA_OP << '=' << binary2hex(auth_aka_op, AKA_OPLEN) << endl; config << FLD_AUTH_AKA_AMF << '=' << binary2hex(auth_aka_amf, AKA_AMFLEN) << endl; config << endl; // Write SIP SERVER settings config << "# SIP SERVER\n"; if (use_outbound_proxy) { config << FLD_OUTBOUND_PROXY << '='; config << outbound_proxy.encode_noscheme() << endl; config << FLD_ALL_REQUESTS_TO_PROXY << '='; config << bool2yesno(all_requests_to_proxy) << endl; config << FLD_NON_RESOLVABLE_TO_PROXY << '='; config << bool2yesno(non_resolvable_to_proxy) << endl; } else { config << FLD_OUTBOUND_PROXY << '=' << endl; config << FLD_ALL_REQUESTS_TO_PROXY << "=no" << endl; } if (use_registrar) { config << FLD_REGISTRAR << '=' << registrar.encode_noscheme(); config << endl; } else { config << FLD_REGISTRAR << '=' << endl; } config << FLD_REGISTER_AT_STARTUP << '='; config << bool2yesno(register_at_startup) << endl; config << FLD_REGISTRATION_TIME << '=' << registration_time << endl; config << FLD_REG_ADD_QVALUE << '=' << bool2yesno(reg_add_qvalue) << endl; config << FLD_REG_QVALUE << '=' << reg_qvalue << endl; config << endl; // Write AUDIO settings config << "# RTP AUDIO\n"; config << FLD_CODECS << '='; for (list::iterator i = codecs.begin(); i != codecs.end(); i++) { if (i != codecs.begin()) config << ','; switch(*i) { case CODEC_G711_ALAW: config << "g711a"; break; case CODEC_G711_ULAW: config << "g711u"; break; case CODEC_GSM: config << "gsm"; break; case CODEC_SPEEX_NB: config << "speex-nb"; break; case CODEC_SPEEX_WB: config << "speex-wb"; break; case CODEC_SPEEX_UWB: config << "speex-uwb"; break; case CODEC_ILBC: config << "ilbc"; break; case CODEC_G726_16: config << "g726-16"; break; case CODEC_G726_24: config << "g726-24"; break; case CODEC_G726_32: config << "g726-32"; break; case CODEC_G726_40: config << "g726-40"; break; default: assert(false); } } config << endl; config << FLD_PTIME << '=' << ptime << endl; config << FLD_OUT_FAR_END_CODEC_PREF << '=' << bool2yesno(out_obey_far_end_codec_pref) << endl; config << FLD_IN_FAR_END_CODEC_PREF << '=' << bool2yesno(in_obey_far_end_codec_pref) << endl; config << FLD_SPEEX_NB_PAYLOAD_TYPE << '=' << speex_nb_payload_type << endl; config << FLD_SPEEX_WB_PAYLOAD_TYPE << '=' << speex_wb_payload_type << endl; config << FLD_SPEEX_UWB_PAYLOAD_TYPE << '=' << speex_uwb_payload_type << endl; config << FLD_SPEEX_BIT_RATE_TYPE << '='; // config << FLD_SPEEX_ABR_NB << '=' << speex_abr_nb << endl; // config << FLD_SPEEX_ABR_WB << '=' << speex_abr_wb << endl; config << bit_rate_type2str(speex_bit_rate_type) << endl; config << FLD_SPEEX_DTX << '=' << bool2yesno(speex_dtx) << endl; config << FLD_SPEEX_PENH << '=' << bool2yesno(speex_penh) << endl; config << FLD_SPEEX_QUALITY << '=' << speex_quality << endl; config << FLD_SPEEX_COMPLEXITY << '=' << speex_complexity << endl; config << FLD_SPEEX_DSP_VAD << '=' << bool2yesno(speex_dsp_vad) << endl; config << FLD_SPEEX_DSP_AGC << '=' << bool2yesno(speex_dsp_agc) << endl; config << FLD_SPEEX_DSP_AEC << '=' << bool2yesno(speex_dsp_aec) << endl; config << FLD_SPEEX_DSP_NRD << '=' << bool2yesno(speex_dsp_nrd) << endl; config << FLD_SPEEX_DSP_AGC_LEVEL << '=' << speex_dsp_agc_level << endl; config << FLD_ILBC_PAYLOAD_TYPE << '=' << ilbc_payload_type << endl; config << FLD_ILBC_MODE << '=' << ilbc_mode << endl; config << FLD_G726_16_PAYLOAD_TYPE << '=' << g726_16_payload_type << endl; config << FLD_G726_24_PAYLOAD_TYPE << '=' << g726_24_payload_type << endl; config << FLD_G726_32_PAYLOAD_TYPE << '=' << g726_32_payload_type << endl; config << FLD_G726_40_PAYLOAD_TYPE << '=' << g726_40_payload_type << endl; config << FLD_G726_PACKING << '=' << g726_packing2str(g726_packing) << endl; config << FLD_DTMF_TRANSPORT << '=' << dtmf_transport2str(dtmf_transport) << endl; config << FLD_DTMF_PAYLOAD_TYPE << '=' << dtmf_payload_type << endl; config << FLD_DTMF_DURATION << '=' << dtmf_duration << endl; config << FLD_DTMF_PAUSE << '=' << dtmf_pause << endl; config << FLD_DTMF_VOLUME << '=' << dtmf_volume << endl; config << endl; // Write SIP PROTOCOL settings config << "# SIP PROTOCOL\n"; config << FLD_HOLD_VARIANT << '='; switch(hold_variant) { case HOLD_RFC2543: config << "rfc2543"; break; case HOLD_RFC3264: config << "rfc3264"; break; default: assert(false); } config << endl; config << FLD_CHECK_MAX_FORWARDS << '='; config << bool2yesno(check_max_forwards) << endl; config << FLD_ALLOW_MISSING_CONTACT_REG << '='; config << bool2yesno(allow_missing_contact_reg) << endl; config << FLD_REGISTRATION_TIME_IN_CONTACT << '='; config << bool2yesno(registration_time_in_contact) << endl; config << FLD_COMPACT_HEADERS << '=' << bool2yesno(compact_headers) << endl; config << FLD_ENCODE_MULTI_VALUES_AS_LIST << '='; config << bool2yesno(encode_multi_values_as_list) << endl; config << FLD_USE_DOMAIN_IN_CONTACT << '='; config << bool2yesno(use_domain_in_contact) << endl; config << FLD_ALLOW_SDP_CHANGE << '=' << bool2yesno(allow_sdp_change) << endl; config << FLD_ALLOW_REDIRECTION << '=' << bool2yesno(allow_redirection); config << endl; config << FLD_ASK_USER_TO_REDIRECT << '='; config << bool2yesno(ask_user_to_redirect) << endl; config << FLD_MAX_REDIRECTIONS << '=' << max_redirections << endl; config << FLD_EXT_100REL << '=' << ext_support2str(ext_100rel) << endl; config << FLD_EXT_REPLACES << '=' << bool2yesno(ext_replaces) << endl; config << FLD_REFEREE_HOLD << '=' << bool2yesno(referee_hold) << endl; config << FLD_REFERRER_HOLD << '=' << bool2yesno(referrer_hold) << endl; config << FLD_ALLOW_REFER << '=' << bool2yesno(allow_refer) << endl; config << FLD_ASK_USER_TO_REFER << '='; config << bool2yesno(ask_user_to_refer) << endl; config << FLD_AUTO_REFRESH_REFER_SUB << '='; config << bool2yesno(auto_refresh_refer_sub) << endl; config << FLD_ATTENDED_REFER_TO_AOR << '='; config << bool2yesno(attended_refer_to_aor) << endl; config << FLD_ALLOW_XFER_CONSULT_INPROG << '='; config << bool2yesno(allow_transfer_consultation_inprog) << endl; config << FLD_SEND_P_PREFERRED_ID << '='; config << bool2yesno(send_p_preferred_id) << endl; config << endl; // Write Transport/NAT settings config << "# Transport/NAT\n"; config << FLD_SIP_TRANSPORT << '=' << sip_transport2str(sip_transport) << endl; config << FLD_SIP_TRANSPORT_UDP_THRESHOLD << '=' << sip_transport_udp_threshold << endl; if (use_nat_public_ip) { config << FLD_NAT_PUBLIC_IP << '=' << nat_public_ip << endl; } else { config << FLD_NAT_PUBLIC_IP << '=' << endl; } if (use_stun) { config << FLD_STUN_SERVER << '=' << stun_server.encode_noscheme() << endl; } else { config << FLD_STUN_SERVER << '=' << endl; } config << FLD_PERSISTENT_TCP << '=' << bool2yesno(persistent_tcp) << endl; config << FLD_ENABLE_NAT_KEEPALIVE << '=' << bool2yesno(enable_nat_keepalive) << endl; config << endl; // Write TIMER settings config << "# TIMERS\n"; config << FLD_TIMER_NOANSWER << '=' << timer_noanswer << endl; config << FLD_TIMER_NAT_KEEPALIVE << '=' << timer_nat_keepalive << endl; config << FLD_TIMER_TCP_PING << '=' << timer_tcp_ping << endl; config << endl; // Write ADDRESS FORMAT settings config << "# ADDRESS FORMAT\n"; config << FLD_DISPLAY_USERONLY_PHONE << '='; config << bool2yesno(display_useronly_phone) << endl; config << FLD_NUMERICAL_USER_IS_PHONE << '='; config << bool2yesno(numerical_user_is_phone) << endl; config << FLD_REMOVE_SPECIAL_PHONE_SYM << '='; config << bool2yesno(remove_special_phone_symbols) << endl; config << FLD_SPECIAL_PHONE_SYMBOLS << '=' << special_phone_symbols << endl; config << FLD_USE_TEL_URI_FOR_PHONE << '=' << bool2yesno(use_tel_uri_for_phone) << endl; config << endl; // Write RING TONE settings config << "# RING TONES\n"; config << FLD_USER_RINGTONE_FILE << '=' << ringtone_file << endl; config << FLD_USER_RINGBACK_FILE << '=' << ringback_file << endl; config << endl; // Write script settings config << "# SCRIPTS\n"; config << FLD_SCRIPT_INCOMING_CALL << '=' << script_incoming_call << endl; config << FLD_SCRIPT_IN_CALL_ANSWERED << '=' << script_in_call_answered << endl; config << FLD_SCRIPT_IN_CALL_FAILED << '=' << script_in_call_failed << endl; config << FLD_SCRIPT_OUTGOING_CALL << '=' << script_outgoing_call << endl; config << FLD_SCRIPT_OUT_CALL_ANSWERED << '=' << script_out_call_answered << endl; config << FLD_SCRIPT_OUT_CALL_FAILED << '=' << script_out_call_failed << endl; config << FLD_SCRIPT_LOCAL_RELEASE << '=' << script_local_release << endl; config << FLD_SCRIPT_REMOTE_RELEASE << '=' << script_remote_release << endl; config << endl; // Write number conversion rules config << "# NUMBER CONVERSION\n"; for (list::iterator i = number_conversions.begin(); i != number_conversions.end(); i++) { config << FLD_NUMBER_CONVERSION << '='; config << escape(i->re.str(), ','); config << ','; config << escape(i->fmt, ','); config << endl; } config << endl; // Write security settings config << "# SECURITY\n"; config << FLD_ZRTP_ENABLED << '=' << bool2yesno(zrtp_enabled) << endl; config << FLD_ZRTP_GOCLEAR_WARNING << '=' << bool2yesno(zrtp_goclear_warning) << endl; config << FLD_ZRTP_SDP << '=' << bool2yesno(zrtp_sdp) << endl; config << FLD_ZRTP_SEND_IF_SUPPORTED << '=' << bool2yesno(zrtp_send_if_supported) << endl; config << endl; // Write MWI settings config << "# MWI\n"; config << FLD_MWI_SOLLICITED << '=' << bool2yesno(mwi_sollicited) << endl; config << FLD_MWI_USER << '=' << mwi_user << endl; if (mwi_server.is_valid()) { config << FLD_MWI_SERVER << '=' << mwi_server.encode_noscheme() << endl; } else { config << FLD_MWI_SERVER << '=' << endl; } config << FLD_MWI_VIA_PROXY << '=' << bool2yesno(mwi_via_proxy) << endl; config << FLD_MWI_SUBSCRIPTION_TIME << '=' << mwi_subscription_time << endl; config << FLD_MWI_VM_ADDRESS << '=' << mwi_vm_address << endl; config << endl; config << "# INSTANT MESSAGE\n"; config << FLD_IM_MAX_SESSIONS << '=' << im_max_sessions << endl; config << FLD_IM_SEND_ISCOMPOSING << '=' << bool2yesno(im_send_iscomposing) << endl; config << endl; // Write presence settings config << "# PRESENCE\n"; config << FLD_PRES_SUBSCRIPTION_TIME << '=' << pres_subscription_time << endl; config << FLD_PRES_PUBLICATION_TIME << '=' << pres_publication_time << endl; config << FLD_PRES_PUBLISH_STARTUP << '=' << bool2yesno(pres_publish_startup) << endl; // Check if writing succeeded if (!config.good()) { // Restore backup config.close(); rename(f_backup.c_str(), f.c_str()); error_msg = "File system error while writing file "; error_msg += f; log_file->write_report(error_msg, "t_user::write_config", LOG_NORMAL, LOG_CRITICAL); mtx_user.unlock(); return false; } // Set parser options t_parser::check_max_forwards = check_max_forwards; t_parser::compact_headers = compact_headers; t_parser::multi_values_as_list = encode_multi_values_as_list; mtx_user.unlock(); return true; } string t_user::get_filename(void) const { string result; mtx_user.lock(); result = config_filename; mtx_user.unlock(); return result; } bool t_user::set_config(string filename) { t_mutex_guard guard(mtx_user); struct stat stat_buf; config_filename = filename; string fullpath = expand_filename(filename); return (stat(fullpath.c_str(), &stat_buf) != 0); } string t_user::get_profile_name(void) const { string result; mtx_user.lock(); string::size_type pos_ext = config_filename.find(USER_FILE_EXT); if (pos_ext == string::npos) { result = config_filename; } else { result = config_filename.substr(0, pos_ext); } mtx_user.unlock(); return result; } string t_user::get_contact_name(void) const { mtx_user.lock(); string s = name; // Some broken proxies expect the contact name to be the same // as the SIP user name. if (!use_domain_in_contact) { mtx_user.unlock(); return s; } // Create a unique contact name from the user name and domain: // // username_domain, where all dots in domain are replace // // This way it is possible to activate 2 profiles that have the // same username, but different domains, e.g. // // michel@domainA // michel@domainB s += '_'; // Cut of port and/or uri-parameters if present in domain string::size_type i = domain.find_first_of(":;"); if (i != string::npos) { // Some broken SIP proxies think that their own address appears // in the contact header when they see the domain in the user part. // By replacing the dots with underscores Twinkle interoperates // with those proxies (yuck). s += replace_char(domain.substr(0, i), '.', '_'); } else { s += replace_char(domain, '.', '_'); } mtx_user.unlock(); return s; } string t_user::get_display_uri(void) const { mtx_user.lock(); string s; s = display; if (!s.empty()) s += ' '; s += '<'; s += USER_SCHEME; s += ':'; s += name; s += '@'; s += domain; s += '>'; mtx_user.unlock(); return s; } bool t_user::check_required_ext(t_request *r, list &unsupported) const { bool all_supported = true; mtx_user.lock(); unsupported.clear(); if (!r->hdr_require.is_populated()) { mtx_user.unlock(); return true; } for (list::iterator i = r->hdr_require.features.begin(); i != r->hdr_require.features.end(); i++) { if (*i == EXT_100REL) { if (ext_100rel != EXT_DISABLED) continue; } else if (*i == EXT_REPLACES) { if (ext_replaces) continue; } else if (*i == EXT_NOREFERSUB) { continue; } // Extension is not supported unsupported.push_back(*i); all_supported = false; } mtx_user.unlock(); return all_supported; } string t_user::create_user_contact(bool anonymous, const string &auto_ip) { string s; mtx_user.lock(); s = USER_SCHEME; s += ':'; if (!anonymous) { s += t_url::escape_user_value(get_contact_name()); s += '@'; } s += USER_HOST(this, auto_ip); if (PUBLIC_SIP_PORT(this) != get_default_port(USER_SCHEME)) { s += ':'; s += int2str(PUBLIC_SIP_PORT(this)); } if (phone->use_stun(this)) { // The port discovered via STUN can only be used for UDP. s += ";transport=udp"; } else { // Add transport parameter if a single transport is provisioned only. switch (sip_transport) { case SIP_TRANS_UDP: s += ";transport=udp"; break; case SIP_TRANS_TCP: s += ";transport=tcp"; break; default: break; } } if (!anonymous && numerical_user_is_phone && looks_like_phone(name, special_phone_symbols)) { // RFC 3261 19.1.1 // If the URI contains a telephone number it SHOULD contain // the user=phone parameter. s += ";user=phone"; } mtx_user.unlock(); return s; } string t_user::create_user_uri(bool anonymous) { if (anonymous) return ANONYMOUS_URI; string s; mtx_user.lock(); s = USER_SCHEME; s += ':'; s += t_url::escape_user_value(name); s += '@'; s += domain; if (numerical_user_is_phone && looks_like_phone(name, special_phone_symbols)) { // RFC 3261 19.1.1 // If the URI contains a telephone number it SHOULD contain // the user=phone parameter. s += ";user=phone"; } mtx_user.unlock(); return s; } string t_user::convert_number(const string &number, const list &l) const { for (list::const_iterator i = l.begin(); i != l.end(); i++) { boost::smatch m; try { if (boost::regex_match(number, m, i->re)) { string result = m.format(i->fmt); log_file->write_header("t_user::convert_number", LOG_NORMAL, LOG_DEBUG); log_file->write_raw("Apply conversion: "); log_file->write_raw(i->str()); log_file->write_endl(); log_file->write_raw(number); log_file->write_raw(" converted to "); log_file->write_raw(result); log_file->write_endl(); log_file->write_footer(); return result; } } catch (std::runtime_error) { log_file->write_header("t_user::convert_number", LOG_NORMAL, LOG_WARNING); log_file->write_raw("Number conversion rule too complex:\n"); log_file->write_raw("Number: "); log_file->write_raw(number); log_file->write_endl(); log_file->write_raw(i->str()); log_file->write_endl(); log_file->write_footer(); return number; } } // No match found return number; } string t_user::convert_number(const string &number) const { return convert_number(number, number_conversions); } t_url t_user::get_mwi_uri(void) const { t_url u(mwi_server); u.set_user(mwi_user); return u; } bool t_user::is_diamondcard_account(void) const { // A profile is a Diamondcard account if the end configured domain // is equal to the DIAMONDCARD_DOMAIN size_t domain_len = strlen(DIAMONDCARD_DOMAIN); if (domain.size() < domain_len) return false; size_t pos = domain.size() - domain_len; return (domain.substr(pos) == DIAMONDCARD_DOMAIN); } twinkle-1.4.2/src/phone.h0000644000175000001440000005666011147573321012202 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PHONE_H #define _PHONE_H #include #include #include #include #include "auth.h" #include "call_history.h" #include "dialog.h" #include "id_object.h" #include "phone_user.h" #include "protocol.h" #include "service.h" #include "transaction_layer.h" #include "im/msg_session.h" #include "mwi/mwi.h" #include "sockets/url.h" #include "parser/request.h" #include "parser/response.h" #include "presence/presence_state.h" // Number of phone lines // One line is used by Twinkle internally to park the call towards a // referrer while the refer is in progress. // Besides the lines for making calls, ephemeral lines will be created // for parking calls that are being released. By parking a releasing // call, the line visible to the user is free for making new calls. #define NUM_CALL_LINES 3 // Total numbers of phone lines for making calls #define NUM_USER_LINES 2 // #lines usable for the user #define LINENO_REFERRER 2 // Internal lineno for referrer // Number of seconds to wait till all lines are idle when terminating // Twinkle #define QUIT_IDLE_WAIT 2 using namespace std; using namespace im; // Forward declarations class t_dialog; class t_client_request; class t_line; class t_call_info; enum t_phone_state { PS_IDLE, PS_BUSY }; enum t_line_state { LS_IDLE, LS_BUSY }; enum t_line_substate { // Idle sub states LSSUB_IDLE, // line is idle LSSUB_SEIZED, // user has seized the line to call // Busy sub states LSSUB_INCOMING_PROGRESS, // incoming call in progress LSSUB_OUTGOING_PROGRESS, // outgoing call in progress LSSUB_ANSWERING, // sent 200 OK, waiting for ACK LSSUB_ESTABLISHED, // call established LSSUB_RELEASING // call is being released (BYE sent) }; class t_transfer_data { private: // The received REFER request t_request *refer_request; // Line number on which REFER was received unsigned short lineno; // Indicates if triggered INVITE must be anonymous bool hide_user; t_phone_user *phone_user; public: t_transfer_data(t_request *r, unsigned short _lineno, bool _hide_user, t_phone_user *pu); ~t_transfer_data(); t_request *get_refer_request(void) const; unsigned short get_lineno(void) const; bool get_hide_user(void) const; t_phone_user *get_phone_user(void) const; }; class t_phone : public t_transaction_layer { private: // Indicates if the phone is active, accepting calls. bool is_active; // Phone users list phone_users; // Phone lines // The first NUM_CALL_LINES are for making phone calls. // The tail of the vector is for releasing lines in the background. vector lines; // Operations like invite, end_call work on the active line unsigned short active_line; // 3-way conference data bool is_3way; // indicates an acitive 3-way t_line *line1_3way; // first line in 3-way conf t_line *line2_3way; // second line in 3-way conf // Call transfer data. When a REFER comes in, the user has // to give permission before the triggered INVITE can be sent. // While the user interface presents the question to the user, // the data related to the incoming REFER is stored here. t_transfer_data *incoming_refer_data; // Time of startup time_t startup_time; // Line release operations // Move a line to the background so it will be released in the // background. void move_line_to_background(unsigned short lineno); // Move all call lines that are in releasing state to the // background. void move_releasing_lines_to_background(void); // Destroy lines in the background that are idle. void cleanup_dead_lines(void); // If a line was part of a 3way, then remove it from the // 3way conference data. void cleanup_3way_state(unsigned short lineno); // If one of the lines of a 3way calls has become idle, then // cleanup the 3way conference data. void cleanup_3way(void); /** @name Actions */ //@{ /** * Send an INVITE * @param pu The phone user making this call. * @param to_uri The URI to be used a request-URI and To header URI * @param to_display Display name for To header. * @param subject If not empty, this string will go into the Subject header. * @param no_fork If true, put a no-fork request disposition in the outgoing INVITE * @param anonymous Inidicates if the INVITE should be sent anonymous. */ void invite(t_phone_user *pu, const t_url &to_uri, const string &to_display, const string &subject, bool no_fork, bool anonymous); void answer(void); void redirect(const list &destinations, int code, string reason = ""); void reject(void); void reject(unsigned short line); void end_call(void); void registration(t_phone_user *pu, t_register_type register_type, unsigned long expires = 0); //@} // OPTIONS outside dialog void options(t_phone_user *pu, const t_url &to_uri, const string &to_display = ""); // OPTIONS inside dialog void options(void); bool hold(bool rtponly = false); // returns false is call cannot be put on hold void retrieve(void); // Transfer a call (send REFER to far-end) void refer(const t_url &uri, const string &display); // Call transfer with consultation (attended) // Transfer the far-end on line lineno_from to the far-end of lineno_to. void refer(unsigned short lineno_from, unsigned short lineno_to); void refer_attended(unsigned short lineno_from, unsigned short lineno_to); void refer_consultation(unsigned short lineno_from, unsigned short lineno_to); // Setup a consultation call for transferring the call on the active // line. The active line is put on-hold and the consultation call is // made on an idle line. void setup_consultation_call(const t_url &uri, const string &display); // Make line l active. If the current line is busy, then that call // will be put on-hold. If line l has a call on-hold, then that // call will be retrieved. void activate_line(unsigned short l); // Send a DTMF digit void send_dtmf(char digit, bool inband, bool info); void set_active_line(unsigned short l); // Handle responses for out-of-dialog requests void handle_response_out_of_dialog(t_response *r, t_tuid tuid, t_tid tid); void handle_response_out_of_dialog(StunMessage *r, t_tuid tuid); // Match an incoming message to a phone user t_phone_user *match_phone_user(t_response *r, t_tuid tuid, bool active_only = false); t_phone_user *match_phone_user(t_request *r, bool active_only = false); t_phone_user *match_phone_user(StunMessage *r, t_tuid tuid, bool active_only = false); /** * Hunt for an idle line to hande an incoming call. * @return The number of the line to handle the call (starting at 0). * @return -1 if there is no line to handle the call. */ int hunt_line(void); protected: /** * Find a phone user that can handle an out-of-dialog request. * If there is no phone user that can handle the request, then this * method will send an appropriate failure response on the request. * @param r [in] The request. * @param tid [in] Transaction id of the request transaction. * @return The phone user, if there is a phone user that can handle the request. * @return NULL, otherwise. */ t_phone_user *find_phone_user_out_dialog_request(t_request *r, t_tid tid); /** * Find a line that can handle an in-dialog request. * If there is no line that can handle the request, then this * method will send an appropriate failure response on the request. * @param r [in] The request. * @param tid [in] Transaction id of the request transaction. * @return The line, if there is a line that can handle the request. * @return NULL, otherwise. */ t_line *find_line_in_dialog_request(t_request *r, t_tid tid); // Events void recvd_provisional(t_response *r, t_tuid tuid, t_tid tid); void recvd_success(t_response *r, t_tuid tuid, t_tid tid); void recvd_redirect(t_response *r, t_tuid tuid, t_tid tid); void recvd_client_error(t_response *r, t_tuid tuid, t_tid tid); void recvd_server_error(t_response *r, t_tuid tuid, t_tid tid); void recvd_global_error(t_response *r, t_tuid tuid, t_tid tid); void post_process_response(t_response *r, t_tuid tuid, t_tid tid); void recvd_invite(t_request *r, t_tid tid); void recvd_initial_invite(t_request *r, t_tid tid); void recvd_re_invite(t_request *r, t_tid tid); void recvd_ack(t_request *r, t_tid tid); void recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid); void recvd_bye(t_request *r, t_tid tid); void recvd_options(t_request *r, t_tid tid); void recvd_register(t_request *r, t_tid tid); void recvd_prack(t_request *r, t_tid tid); void recvd_subscribe(t_request *r, t_tid tid); void recvd_notify(t_request *r, t_tid tid); void recvd_refer(t_request *r, t_tid tid); void recvd_info(t_request *r, t_tid tid); void recvd_message(t_request *r, t_tid tid); void post_process_request(t_request *r, t_tid cancel_tid, t_tid target_tid); void failure(t_failure failure, t_tid tid); void recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid); void recvd_refer_permission(bool permission); /** @name Timeout handlers */ //@{ virtual void handle_event_timeout(t_event_timeout *e); /** * Process expiry of line timer. * @param id [in] Line id of the line associate with the timer. * @param timer [in] Type of line timer. * @param did [in] Dialog id if timer is for a dialog, 0 otherwise. */ void line_timeout(t_object_id id, t_line_timer timer, t_object_id did); /** * Process expiry of a line subscription timer (REFER subscription). * @param id [in] Line id of the line associate with the timer. * @param timer [in] Type of subcription timer. * @param did [in] Dialog id associated with the timer. * @param event_type [in] Event type of the subscription. * @param event_id [in] Event id of the subscription. */ void line_timeout_sub(t_object_id id, t_subscribe_timer timer, t_object_id did, const string &event_type, const string &event_id); /** * Process expiry of a subcription timer. * @param timer [in] Type of subcription timer. * @param id_timer [in] Timer id of expired timer. */ void subscription_timeout(t_subscribe_timer timer, t_object_id id_timer); /** * Process expiry of a publication timer. * @param timer [in] Type of publication timer. * @param id_timer [in] Timer id of expired timer. */ void publication_timeout(t_publish_timer timer, t_object_id id_timer); /** * Process expiry of phone timer. * @param timer [in] Type of phone timer. * @param id_timer [in] Timer id of expired timer. */ void timeout(t_phone_timer timer, unsigned short id_timer); //@} virtual void handle_broken_connection(t_event_broken_connection *e); public: t_phone(); virtual ~t_phone(); // Get line based on object id // Returns NULL if there is no such line. t_line *get_line_by_id(t_object_id id) const; // Get line based on line number t_line *get_line(unsigned short lineno) const; // Get busy/idle state of the phone // PS_IDLE - at least one line is idle // PS_BUSY - all lines are busy t_phone_state get_state(void) const; // Returns true if all lines are in the LSSUB_IDLE state bool all_lines_idle(void) const; // Get an idle user line. // If no line is idle, then false is returned. bool get_idle_line(unsigned short &lineno) const; // Actions to be called by the user interface. // These methods first lock the phone, then call the corresponding // private method and then unlock the phone. // The private methods should only be called by the phone, line, // and dialog objects to avoid deadlocks. void pub_invite(t_user *user, const t_url &to_uri, const string &to_display, const string &subject, bool anonymous); void pub_answer(void); void pub_reject(void); void pub_reject(unsigned short line); void pub_redirect(const list &destinations, int code, string reason = ""); void pub_end_call(void); void pub_registration(t_user *user, t_register_type register_type, unsigned long expires = 0); void pub_options(t_user *user, const t_url &to_uri, const string &to_display = ""); void pub_options(void); bool pub_hold(void); void pub_retrieve(void); void pub_refer(const t_url &uri, const string &display); void pub_refer(unsigned short lineno_from, unsigned short lineno_to); void pub_setup_consultation_call(const t_url &uri, const string &display); void mute(bool enable); void pub_activate_line(unsigned short l); void pub_send_dtmf(char digit, bool inband, bool info); // ZRTP actions void pub_confirm_zrtp_sas(unsigned short line); void pub_confirm_zrtp_sas(void); void pub_reset_zrtp_sas_confirmation(unsigned short line); void pub_reset_zrtp_sas_confirmation(void); void pub_enable_zrtp(void); void pub_zrtp_request_go_clear(void); void pub_zrtp_go_clear_ok(unsigned short line); // Join 2 lines in a 3-way conference. Returns false if 3-way cannot // be setup bool join_3way(unsigned short lineno1, unsigned short lineno2); // Seize the line. // Returns false if seizure failed. bool pub_seize(void); // active line bool pub_seize(unsigned short line); // Unseize the line void pub_unseize(void); // active line void pub_unseize(unsigned short line); /** @name MWI */ //@{ /** * Subscribe to MWI. * @param user [in] The user profile of the subscribing user. */ void pub_subscribe_mwi(t_user *user); /** * Unsubscribe to MWI. * @param user [in] The user profile of the unsubscribing user. */ void pub_unsubscribe_mwi(t_user *user); //@} /** @name Presence */ //@{ /** * Subscribe to presence of buddies in buddy list. * @param user [in] The user profile of the subscribing user. */ void pub_subscribe_presence(t_user *user); /** * Unsubscribe to presence of buddies in buddy list. * @param user [in] The user profile of the unsubscribing user. */ void pub_unsubscribe_presence(t_user *user); /** * Publish presence state. * @param user [in] The user profile of the user publishing. * @param basic_state [in] The basic presence state to publish. */ void pub_publish_presence(t_user *user, t_presence_state::t_basic_state basic_state); /** * Unpublish presence state. * @param user [in] The user profile of the user unpublishing. */ void pub_unpublish_presence(t_user *user); //@} /** @name Instant messaging */ //@{ /** * Send a message. * @param user [in] User profile of user sending the message. * @param to_uri [in] Destination URI of recipient. * @param to_display [in] Display name of recipient. * @param msg [in] Message to send. * @return True if sending succeeded, false otherwise. */ bool pub_send_message(t_user *user, const t_url &to_uri, const string &to_display, const t_msg &msg); /** * Send a message composing state indication. * @param user [in] User profile of user sending the message. * @param to_uri [in] Destination URI of recipient. * @param to_display [in] Display name of recipient. * @param state [in] Message composing state. * @param refresh [in] The refresh interval in seconds (when state is active). * @return True if sending succeeded, false otherwise. * @note For the idle state, the value of refresh has no meaning. */ bool pub_send_im_iscomposing(t_user *user, const t_url &to_uri, const string &to_display, const string &state, time_t refresh); //@} unsigned short get_active_line(void) const; // Authorize the request based on the challenge in the response // Returns false if authorization fails. bool authorize(t_user *user, t_request *r, t_response *resp); // Remove cached credentials for a particular user/realm void remove_cached_credentials(t_user *user, const string &realm); bool get_is_registered(t_user *user); bool get_last_reg_failed(t_user *user); t_line_state get_line_state(unsigned short lineno) const; t_line_substate get_line_substate(unsigned short lineno) const; bool is_line_on_hold(unsigned short lineno) const; bool is_line_muted(unsigned short lineno) const; bool is_line_transfer_consult(unsigned short lineno, unsigned short &transfer_from_line) const; bool line_to_be_transferred(unsigned short lineno, unsigned short &transfer_to_line) const; bool is_line_encrypted(unsigned short lineno) const; bool is_line_auto_answered(unsigned short lineno) const; t_refer_state get_line_refer_state(unsigned short lineno) const; t_user *get_line_user(unsigned short lineno); bool has_line_media(unsigned short lineno) const; bool is_mwi_subscribed(t_user *user) const; bool is_mwi_terminated(t_user *user) const; t_mwi get_mwi(t_user *user) const; /** * Check if all presence subscriptions for a particular user are terminated. * @param user [in] User profile of the user. * @return True if all presence susbcriptions are terminated, otherwise false. */ bool is_presence_terminated(t_user *user) const; // Get remote uri/display of the active call on a line. // If there is no call, then an empty uri/display is returned. t_url get_remote_uri(unsigned short lineno) const; string get_remote_display(unsigned short lineno) const; // Return if a line is part of a 3-way conference bool part_of_3way(unsigned short lineno); // Get the peer line in a 3-way conference t_line *get_3way_peer_line(unsigned short lineno); // Notify progress of a reference. r is the response to the INVITE // caused by a REFER. referee_lineno is the line number of the line // that is setting up there reference call. void notify_refer_progress(t_response *r, unsigned short referee_lineno); // Get call info record for a line. t_call_info get_call_info(unsigned short lineno) const; // Get the call history record for a line t_call_record get_call_hist(unsigned short lineno) const; // Get ring tone for a line string get_ringtone(unsigned short lineno) const; // Get the startup time of the phone time_t get_startup_time(void) const; // Initialize the RTP port values for all lines. void init_rtp_ports(void); /** * Add a phone user. * @param user_config [in] User profile of the user to add. * @param dup_user [out] Profile of duplicate user. * @return false, if there is already a phone user with the same name * and domain. In this case dup_user is a pointer to the user config * of that user. * @return true, if the phone user was added succesfully. * @note if there is already a user with exactly the same user config * then true is returned, but the user is not added again. The user * will be activated if it was inactive though. */ bool add_phone_user(const t_user &user_config, t_user **dup_user); /** * Deactivate the phone user. * @param user_config [in] User profile of the user to deactivate. */ void remove_phone_user(const t_user &user_config); /** * Get a list of user profiles of all phone users. * @return List of user profiles. */ list ref_users(void); /** * Get the user profile of a user for which user->get_display_uri() == * display_uri. * @param display_uri [in] Display URI. * @return User profile. */ t_user *ref_user_display_uri(const string &display_uri); /** * Get the user profile matching the profile name. * @param profile_name [in] User profile name. * @return User profile. */ t_user *ref_user_profile(const string &profile_name); /** * Get service information for a phone user. * @param user [in] User profile of the phone user. * @return Service object. */ t_service *ref_service(t_user *user); /** * Get the buddy list of a phone user. * @param user [in] User profile of the phone user. * @return Buddy list. */ t_buddy_list *ref_buddy_list(t_user *user); /** * Get the presence event publication agent of a phone user. * @param user [in] User profile of the phone user. * @return The presence EPA. */ t_presence_epa *ref_presence_epa(t_user *user); /** * Find active phone user * @param profile_name [in] User profile name. * @return The phone user for the user profile, NULL if there is no active phone user. */ t_phone_user *find_phone_user(const string &profile_name) const; /** * Find active phone user * @param user_uri [in] The user URI (AoR) of the user to find. * @return The phone user for the URI, NULL if there is no active phone user. */ t_phone_user *find_phone_user(const t_url &user_uri) const; /** * Get local IP address for SIP. * @param user [in] The user profile of the user for whom to get the IP address. * @param auto_ip [in] IP address to use if no IP address has been determined through * some NAT procedure. * @return The IP address. */ string get_ip_sip(const t_user *user, const string &auto_ip) const; /** * Get local port for SIP. * @param user [in] User profile for user for whom to get the port. * @return SIP port. */ unsigned short get_public_port_sip(const t_user *user) const; /** Indicates if STUN is used. */ bool use_stun(t_user *user); // Indicates if a NAT keepalive mechanism is used bool use_nat_keepalive(t_user *user); /** Disable STUN for a user. */ void disable_stun(t_user *user); /** Synchronize sending of NAT keep alives with user configuration settings. */ void sync_nat_keepalive(t_user *user); // Perform NAT discovery for all users having STUN enabled. // If NAT discovery indicates that STUN cannot be used for 1 or more // users, then false will be returned and msg_list contains a list // of messages to be shown to the user. bool stun_discover_nat(list &msg_list); // Perform NAT discovery for a single user. bool stun_discover_nat(t_user *user, string &msg); // Create a response to an OPTIONS request // Argument 'in-dialog' indicates if the OPTIONS response is // sent within a dialog. t_response *create_options_response(t_user *user, t_request *r, bool in_dialog = false); // Timer operations void start_timer(t_phone_timer timer, t_phone_user *pu); void stop_timer(t_phone_timer timer, t_phone_user *pu); // Start a timer with the time set in the time-argument. void start_set_timer(t_phone_timer timer, long time, t_phone_user *pu); /** * Initialize the phone functions. * Register all active users with auto register. * Initialize extensions for users without auto register. */ void init(void); /** * Initialize SIP extensions like MWI and presence. * @param user_config [in] User for which the extensions must be initialized. */ void init_extensions(t_user *user_config); /** * Set the signal handler to handler for LinuxThreads. * @return True if succesful, false otherwise. */ bool set_sighandler(void) const; /** * Terminate the phone functions. * Release all calls, don't accept any new calls. * Deregister all active users. */ void terminate(void); }; // Main function for the UAS part of the phone void *phone_uas_main(void *arg); // Entry function of thread catching signals to terminate // the application in a graceful manner if NPLT is used. void *phone_sigwait(void *arg); // Signal handler to process signals if LinuxThreads is used. void phone_sighandler(int sig); #endif twinkle-1.4.2/src/subscription_dialog.h0000644000175000001440000001216511127714051015117 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Subscription dialog (RFC 3265) */ #ifndef _SUBSCRIPTION_DIALOG_H #define _SUBSCRIPTION_DIALOG_H #include "abstract_dialog.h" #include "subscription.h" // Forward declaration class t_phone_user; /** * RFC 3265 * Generic subscription dialog state for subscribers and notifiers. * For each event type this class should be subclassed. */ class t_subscription_dialog : public t_abstract_dialog { protected: /** * The subscription belonging to this dialog. Subclasses must * create the proper subscription. */ t_subscription *subscription; /** * Constructor. This class must be subclassed. The subclass must provide * a public constructor. */ t_subscription_dialog(t_phone_user *_phone_user); virtual void send_request(t_request *r, t_tuid tuid); /** * Process a received SUBSCRIBE request. * @param r [in] The request. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ virtual void process_subscribe(t_request *r, t_tuid tuid, t_tid tid); /** * Process a received NOTIFY request. * @param r [in] The request. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. */ virtual void process_notify(t_request *r, t_tuid tuid, t_tid tid); /** * Process the response to the initial SUBSCRIBE. * @param r [in] The response. * @param tuid [in] Transaction user id. * @param tid [in] Transaction id. * @return true, if no further processing is needed. This happens, when a * 423 Interval too brief response is received. Then this method sends a * new SUBSCRIBE. * @return false, subcalss must do further processing. */ virtual bool process_initial_subscribe_response(t_response *r, t_tuid tuid, t_tid tid); public: /** Destructor. */ virtual ~t_subscription_dialog(); virtual t_request *create_request(t_method m); virtual t_subscription_dialog *copy(void) = 0; virtual bool resend_request_auth(t_response *resp); virtual bool redirect_request(t_response *resp); virtual bool failover_request(t_response *resp); virtual void recvd_response(t_response *r, t_tuid tuid, t_tid tid); virtual void recvd_request(t_request *r, t_tuid tuid, t_tid tid); /** * Match request with dialog and subscription. * @param r [in] The request. * @param partial [out] Indicates if there is a partial match on return. * @return true, if the request matches. * @return false, if the request does not match. In this case the request * may match partially, i.e. the from-tag matches, but the to-tag does not. * In case of a partial match, partial is set to true. */ virtual bool match_request(t_request *r, bool &partial); /** * Get the state of the subscription. * @return The subscription state. */ t_subscription_state get_subscription_state(void) const; /** * Get the reason for termination of the subscription. * @return The termination reason. */ string get_reason_termination(void) const; /** * Get the time after which a resubscription may be tried. * @return The time in seconds. */ unsigned long get_resubscribe_after(void) const; /** * Check if a resubscription may be tried. * @return true, if a resubscription may be tried. * @return false, otherwise. */ bool get_may_resubscribe(void) const; /** * Process timeout. * @param timer [in] The timer that expired. * @return true, if processing is finished. * @return false, if subsclass needs to do further processing. */ virtual bool timeout(t_subscribe_timer timer); /** * Match a timer id with a running timer. * @param timer [in] The running timer. * @param id_timer [in] The timer id. * @return true, if timer id matches with timer. * @return false, otherwise. */ virtual bool match_timer(t_subscribe_timer timer, t_object_id id_timer) const; /** * Subscribe to an event (send SUBSCRIBE). * @param epxires [in] The subscription interval in seconds. * @param req_uri [in] The request-URI for the SUBSCRIBE. * @param to_uri [in] The URI for the To header in the SUBSCRIBE. * @param to_display [in] The display name for the To header in the SUBSCRIBE. */ virtual void subscribe(unsigned long expires, const t_url &req_uri, const t_url &to_uri, const string &to_display); /** Unsubscribe to an event (send SUBSCRIBE). */ virtual void unsubscribe(void); /** Refresh subscription. */ virtual void refresh_subscribe(void); }; #endif twinkle-1.4.2/src/call_history.h0000644000175000001440000001446211127714051013552 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file * Call history */ #ifndef _CALL_HISTORY_H #define _CALL_HISTORY_H #include #include #include #include "parser/request.h" #include "parser/response.h" #include "sockets/url.h" #include "threads/mutex.h" #include "utils/record_file.h" using namespace std; /** Call detail record. */ class t_call_record : public utils::t_record { public: /** Release cause of a call. */ enum t_rel_cause { CS_LOCAL_USER, /**< Released by the local user. */ CS_REMOTE_USER, /**< Released by the remote user. */ CS_FAILURE /**< Call ended due to failure. */ }; /** Direction of the call as seen from the user. */ enum t_direction { DIR_IN, /**< Incoming call. */ DIR_OUT /**< Outgoing call. */ }; private: static t_mutex mtx_class; /**< Protect static members. */ static unsigned short next_id; /**< Next id to be used. */ unsigned short id; /**< Record id. */ public: time_t time_start; /**< Timestamp of start of call. */ time_t time_answer; /**< Timestamp when call got answered. */ time_t time_end; /**< Timestamp of end of call. */ t_direction direction; string from_display; t_url from_uri; string from_organization; string to_display; t_url to_uri; string to_organization; string reply_to_display; t_url reply_to_uri; string referred_by_display; t_url referred_by_uri; string subject; t_rel_cause rel_cause; int invite_resp_code; /**< Response code sent/received on INVITE. */ string invite_resp_reason; /**< Response reason sent/received on INVITE. */ string far_end_device; /**< User-agent/Server description of device. */ string user_profile; /** Constructor. */ t_call_record(); /** * Clear current settings and get a new record id. * So this action creates a brand new call record. */ void renew(); /** * Record call start. * @param invite [in] The INVITE request starting the call. * @param dir [in] Call direction. * @param _user_profile [in] The user profile. */ void start_call(const t_request *invite, t_direction dir, const string &_user_profile); /** * Record call failure. This is also the end of the call. * @param resp [in] The failure response. */ void fail_call(const t_response *resp); /** * Record successful call answer. * @param resp [in] The 2XX INVITE response. */ void answer_call(const t_response *resp); /** * Record end of a successful call with an explicit cause. * @param cause [in] The release cause. */ void end_call(t_rel_cause cause); /** * Record end of a successful call. * If far_end is true, then the far-end ended the call, otherwise * the near-end ended the call. This indication together with the * direction determines the correct cause of the call end. * @param far_end [in] Indicates if the far end released the call. */ void end_call(bool far_end); /** * Get user presentable release cause description. * The release cause is returned in the language of the user. * @return Release cause description. */ string get_rel_cause(void) const; /** * Get release cause description for internal use. * This description is written to file. * @return Release cause description. */ string get_rel_cause_internal(void) const; /** * Get user presentable direction description. * The description is returned in the language of the user. * @return Direction description. */ string get_direction(void) const; /** * Get direction description for internal use. * This description is written to file. * @return Direction description. */ string get_direction_internal(void) const; /** * Set the release cause from an internal description. * @param cause [in] Internal release cause description. * @return Indication if operation succeeded. */ bool set_rel_cause(const string &cause); /** * Set the direction from an internal description. * @param cause [in] Internal direction description. * @return Indication if operation succeeded. */ bool set_direction(const string &dir); virtual bool create_file_record(vector &v) const; virtual bool populate_from_file_record(const vector &v); /** * Check if this call record represents a valid call. * @return Indication if call record is valid. */ bool is_valid(void) const; /** Get the record id. */ unsigned short get_id(void) const; }; /** History of calls. */ class t_call_history : public utils::t_record_file { private: /** Number of missed calls since this counter was cleared. */ int num_missed_calls; public: /** Constructor. */ t_call_history(); /** * Add a call record to the history. * @param call_record [in] The call record to be added. * @param write [in] Indicates if history must be written to file after adding. */ void add_call_record(const t_call_record &call_record, bool write = true); /** * Delete record with a given id. * @param id [in] The record id that must be deleted. * @param write [in] Indicates if history must be written to file after deleting. */ void delete_call_record(unsigned short id, bool write = true); /** * Get list of historic call records. * @param history [out] List of historic call records. */ void get_history(list &history); /** * Clear call history file. * @param write [in] Indicates if history must be written to file after adding. */ void clear(bool write = true); /** Get number of missed calls. */ int get_num_missed_calls(void) const; /** Clear number of missed calls. */ void clear_num_missed_calls(void); }; extern t_call_history *call_history; #endif twinkle-1.4.2/src/events.cpp0000644000175000001440000004223711127714060012716 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "events.h" #include "log.h" #include "userintf.h" #include "util.h" #include "audits/memman.h" string event_type2str(t_event_type t) { switch(t) { case EV_QUIT: return "EV_QUIT"; case EV_NETWORK: return "EV_NETWORK"; case EV_USER: return "EV_USER"; case EV_TIMEOUT: return "EV_TIMEOUT"; case EV_FAILURE: return "EV_FAILURE"; case EV_START_TIMER: return "EV_START_TIMER"; case EV_STOP_TIMER: return "EV_STOP_TIMER"; case EV_ABORT_TRANS: return "EV_ABORT_TRANS"; case EV_STUN_REQUEST: return "EV_STUN_REQUEST"; case EV_STUN_RESPONSE: return "EV_STUN_RESPONSE"; case EV_NAT_KEEPALIVE: return "EV_NAT_KEEPALIVE"; case EV_ICMP: return "EV_ICMP"; case EV_UI: return "EV_UI"; case EV_ASYNC_RESPONSE: return "EV_ASYNC_RESPONSE"; case EV_BROKEN_CONNECTION: return "EV_BROKEN_CONNECTION"; case EV_TCP_PING: return "EV_TCP_PING"; } return "UNKNOWN"; } /////////////////////////////////////////////////////////// // class t_event_network /////////////////////////////////////////////////////////// t_event_network::t_event_network(t_sip_message *m) : t_event() { msg = m->copy(); src_addr = 0; src_port = 0; dst_addr = 0; dst_port = 0; transport.clear(); } t_event_network::~t_event_network() { MEMMAN_DELETE(msg); delete msg; } t_event_type t_event_network::get_type(void) const { return EV_NETWORK; } t_sip_message *t_event_network::get_msg(void) const { return msg; } /////////////////////////////////////////////////////////// // class t_event_quit /////////////////////////////////////////////////////////// t_event_quit::~t_event_quit() {} t_event_type t_event_quit::get_type(void) const { return EV_QUIT; } /////////////////////////////////////////////////////////// // class t_event_user /////////////////////////////////////////////////////////// t_event_user::t_event_user(t_user *u, t_sip_message *m, unsigned short _tuid, unsigned short _tid) : t_event() { msg = m->copy(); tuid = _tuid; tid = _tid; tid_cancel_target = 0; if (u) { user_config = u->copy(); } else { user_config = NULL; } } t_event_user::t_event_user(t_user *u, t_sip_message *m, unsigned short _tuid, unsigned short _tid, unsigned short _tid_cancel_target) : t_event() { msg = m->copy(); tuid = _tuid; tid = _tid; tid_cancel_target = _tid_cancel_target; if (u) { user_config = u->copy(); } else { user_config = NULL; } } t_event_user::~t_event_user() { MEMMAN_DELETE(msg); delete msg; if (user_config) { MEMMAN_DELETE(user_config); delete user_config; } } t_event_type t_event_user::get_type(void) const { return EV_USER; } t_sip_message *t_event_user::get_msg(void) const { return msg; } unsigned short t_event_user::get_tuid(void) const { return tuid; } unsigned short t_event_user::get_tid(void) const { return tid; } unsigned short t_event_user::get_tid_cancel_target(void) const { return tid_cancel_target; } t_user *t_event_user::get_user_config(void) const { return user_config; } /////////////////////////////////////////////////////////// // class t_event_timeout /////////////////////////////////////////////////////////// t_event_timeout::t_event_timeout(t_timer *t) : t_event() { timer = t->copy(); } t_event_timeout::~t_event_timeout() { MEMMAN_DELETE(timer); delete timer; } t_event_type t_event_timeout::get_type(void) const { return EV_TIMEOUT; } t_timer *t_event_timeout::get_timer(void) const { return timer; } /////////////////////////////////////////////////////////// // class t_event_failure /////////////////////////////////////////////////////////// t_event_failure::t_event_failure(t_failure f, unsigned short _tid) : t_event(), failure(f), tid_populated(true), tid(_tid) {} t_event_failure::t_event_failure(t_failure f, const string &_branch, const t_method &_cseq_method) : failure(f), tid_populated(false), branch(_branch), cseq_method(_cseq_method) {} t_event_type t_event_failure::get_type(void) const { return EV_FAILURE; } t_failure t_event_failure::get_failure(void) const { return failure; } unsigned short t_event_failure::get_tid(void) const { return tid; } string t_event_failure::get_branch(void) const { return branch; } t_method t_event_failure::get_cseq_method(void) const { return cseq_method; } bool t_event_failure::is_tid_populated(void) const { return tid_populated; } /////////////////////////////////////////////////////////// // class t_event_start_timer /////////////////////////////////////////////////////////// t_event_start_timer::t_event_start_timer(t_timer *t) : t_event() { timer = t->copy(); } t_event_type t_event_start_timer::get_type(void) const { return EV_START_TIMER; } t_timer *t_event_start_timer::get_timer(void) const { return timer; } /////////////////////////////////////////////////////////// // class t_event_stop_timer /////////////////////////////////////////////////////////// t_event_stop_timer::t_event_stop_timer(unsigned short id) : t_event() { timer_id = id; } t_event_type t_event_stop_timer::get_type(void) const { return EV_STOP_TIMER; } unsigned short t_event_stop_timer::get_timer_id(void) const { return timer_id; } /////////////////////////////////////////////////////////// // class t_event_abort_trans /////////////////////////////////////////////////////////// t_event_abort_trans::t_event_abort_trans(unsigned short _tid) : t_event() { tid = _tid; } t_event_type t_event_abort_trans::get_type(void) const { return EV_ABORT_TRANS; } unsigned short t_event_abort_trans::get_tid(void) const { return tid; } /////////////////////////////////////////////////////////// // class t_event_stun_request /////////////////////////////////////////////////////////// t_event_stun_request::t_event_stun_request(t_user *u, StunMessage *m, t_stun_event_type ev_type, unsigned short _tuid, unsigned short _tid) : t_event() { msg = new StunMessage(*m); MEMMAN_NEW(msg); stun_event_type = ev_type; tuid = _tuid; tid = _tid; dst_addr = 0; dst_port = 0; user_config = u->copy(); } t_event_stun_request::~t_event_stun_request() { MEMMAN_DELETE(msg); delete msg; MEMMAN_DELETE(user_config); delete user_config; } t_event_type t_event_stun_request::get_type(void) const { return EV_STUN_REQUEST; } StunMessage *t_event_stun_request::get_msg(void) const { return msg; } unsigned short t_event_stun_request::get_tuid(void) const { return tuid; } unsigned short t_event_stun_request::get_tid(void) const { return tid; } t_stun_event_type t_event_stun_request::get_stun_event_type(void) const { return stun_event_type; } t_user *t_event_stun_request::get_user_config(void) const { return user_config; } /////////////////////////////////////////////////////////// // class t_event_stun_response /////////////////////////////////////////////////////////// t_event_stun_response::t_event_stun_response(StunMessage *m, unsigned short _tuid, unsigned short _tid) : t_event() { msg = new StunMessage(*m); MEMMAN_NEW(msg); tuid = _tuid; tid = _tid; } t_event_stun_response::~t_event_stun_response() { MEMMAN_DELETE(msg); delete(msg); } t_event_type t_event_stun_response::get_type(void) const { return EV_STUN_RESPONSE; } StunMessage *t_event_stun_response::get_msg(void) const { return msg; } unsigned short t_event_stun_response::get_tuid(void) const { return tuid; } unsigned short t_event_stun_response::get_tid(void) const { return tid; } /////////////////////////////////////////////////////////// // class t_event_nat_keepalive /////////////////////////////////////////////////////////// t_event_type t_event_nat_keepalive::get_type(void) const { return EV_NAT_KEEPALIVE; } /////////////////////////////////////////////////////////// // class t_event_icmp /////////////////////////////////////////////////////////// t_event_icmp::t_event_icmp(const t_icmp_msg &m) : icmp(m) {} t_event_type t_event_icmp::get_type(void) const { return EV_ICMP; } t_icmp_msg t_event_icmp::get_icmp(void) const { return icmp; } /////////////////////////////////////////////////////////// // class t_event_ui /////////////////////////////////////////////////////////// t_event_ui::t_event_ui(t_ui_event_type _type) : t_event(), type(_type) {} t_event_type t_event_ui::get_type(void) const { return EV_UI; } void t_event_ui::set_line(int _line) { line = _line; } void t_event_ui::set_codec(t_audio_codec _codec) { codec = _codec; } void t_event_ui::set_dtmf_event(char _dtmf_event) { dtmf_event = _dtmf_event; } void t_event_ui::set_encrypted(bool on) { encrypted = on; } void t_event_ui::set_cipher_mode(const string &_cipher_mode) { cipher_mode = _cipher_mode; } void t_event_ui::set_zrtp_sas(const string &sas) { zrtp_sas = sas; } void t_event_ui::set_display_msg(const string &_msg, t_msg_priority &_msg_priority) { msg = _msg; msg_priority = _msg_priority; } void t_event_ui::exec(t_userintf *user_intf) { switch (type) { case TYPE_UI_CB_DTMF_DETECTED: ui->cb_dtmf_detected(line, dtmf_event); break; case TYPE_UI_CB_SEND_DTMF: ui->cb_send_dtmf(line, dtmf_event); break; case TYPE_UI_CB_RECV_CODEC_CHANGED: ui->cb_recv_codec_changed(line, codec); break; case TYPE_UI_CB_LINE_STATE_CHANGED: ui->cb_line_state_changed(); break; case TYPE_UI_CB_LINE_ENCRYPTED: ui->cb_line_encrypted(line, encrypted, cipher_mode); break; case TYPE_UI_CB_SHOW_ZRTP_SAS: ui->cb_show_zrtp_sas(line, zrtp_sas); break; case TYPE_UI_CB_ZRTP_CONFIRM_GO_CLEAR: ui->cb_zrtp_confirm_go_clear(line); break; case TYPE_UI_CB_QUIT: ui->cmd_quit(); break; default: assert(false); } } /////////////////////////////////////////////////////////// // class t_event_async_response /////////////////////////////////////////////////////////// t_event_async_response::t_event_async_response(t_response_type type) : t_event(), response_type(type) {} t_event_type t_event_async_response::get_type(void) const { return EV_ASYNC_RESPONSE; } void t_event_async_response::set_bool_response(bool b) { bool_response = b; } t_event_async_response::t_response_type t_event_async_response::get_response_type(void) const { return response_type; } bool t_event_async_response::get_bool_response(void) const { return bool_response; } /////////////////////////////////////////////////////////// // class t_event_broken_connection /////////////////////////////////////////////////////////// t_event_broken_connection::t_event_broken_connection(const t_url &url) : t_event(), user_uri_(url) {} t_event_type t_event_broken_connection::get_type(void) const { return EV_BROKEN_CONNECTION; } t_url t_event_broken_connection::get_user_uri(void) const { return user_uri_; } /////////////////////////////////////////////////////////// // class t_event_tcp_ping /////////////////////////////////////////////////////////// t_event_tcp_ping::t_event_tcp_ping(const t_url &url, unsigned int dst_addr, unsigned short dst_port) : t_event(), user_uri_(url), dst_addr_(dst_addr), dst_port_(dst_port) {} t_event_type t_event_tcp_ping::get_type(void) const { return EV_TCP_PING; } t_url t_event_tcp_ping::get_user_uri(void) const { return user_uri_; } unsigned int t_event_tcp_ping::get_dst_addr(void) const { return dst_addr_; } unsigned short t_event_tcp_ping::get_dst_port(void) const { return dst_port_; } /////////////////////////////////////////////////////////// // class t_event_queue /////////////////////////////////////////////////////////// t_event_queue::t_event_queue() : sema_evq(0), sema_caught_interrupt(0) {} t_event_queue::~t_event_queue() { log_file->write_header("t_event_queue::~t_event_queue", LOG_NORMAL, LOG_INFO); log_file->write_raw("Clean up event queue.\n"); while (!ev_queue.empty()) { t_event *e = ev_queue.front(); ev_queue.pop(); log_file->write_raw("\nDeleting unprocessed event: \n"); log_file->write_raw("Type: "); log_file->write_raw(event_type2str(e->get_type())); log_file->write_raw(", Pointer: "); log_file->write_raw(ptr2str(e)); log_file->write_endl(); MEMMAN_DELETE(e); delete e; } log_file->write_footer(); } void t_event_queue::push(t_event *e) { mutex_evq.lock(); ev_queue.push(e); mutex_evq.unlock(); sema_evq.up(); } void t_event_queue::push_quit(void) { t_event_quit *event = new t_event_quit(); MEMMAN_NEW(event); push(event); } void t_event_queue::push_network(t_sip_message *m, const t_ip_port &ip_port) { t_event_network *event = new t_event_network(m); MEMMAN_NEW(event); event->dst_addr = ip_port.ipaddr; event->dst_port = ip_port.port; event->transport = ip_port.transport; push(event); } void t_event_queue::push_user(t_user *user_config, t_sip_message *m, unsigned short tuid, unsigned short tid) { t_event_user *event = new t_event_user(user_config, m, tuid, tid); MEMMAN_NEW(event); push(event); } void t_event_queue::push_user(t_sip_message *m, unsigned short tuid, unsigned short tid) { push_user(NULL, m, tuid, tid); } void t_event_queue::push_user_cancel(t_user *user_config, t_sip_message *m, unsigned short tuid, unsigned short tid, unsigned short target_tid) { t_event_user *event = new t_event_user(user_config, m, tuid, tid, target_tid); MEMMAN_NEW(event); push(event); } void t_event_queue::push_user_cancel(t_sip_message *m, unsigned short tuid, unsigned short tid, unsigned short target_tid) { push_user_cancel(NULL, m, tuid, tid, target_tid); } void t_event_queue::push_timeout(t_timer *t) { t_event_timeout *event = new t_event_timeout(t); MEMMAN_NEW(event); push(event); } void t_event_queue::push_failure(t_failure f, unsigned short tid) { t_event_failure *event = new t_event_failure(f, tid); MEMMAN_NEW(event); push(event); } void t_event_queue::push_failure(t_failure f, const string &branch, const t_method &cseq_method) { t_event_failure *event = new t_event_failure(f, branch, cseq_method); MEMMAN_NEW(event); push(event); } void t_event_queue::push_start_timer(t_timer *t) { t_event_start_timer *event = new t_event_start_timer(t); MEMMAN_NEW(event); push(event); } void t_event_queue::push_stop_timer(unsigned short timer_id) { t_event_stop_timer *event = new t_event_stop_timer(timer_id); MEMMAN_NEW(event); push(event); } void t_event_queue::push_abort_trans(unsigned short tid) { t_event_abort_trans *event = new t_event_abort_trans(tid); MEMMAN_NEW(event); push(event); } void t_event_queue::push_stun_request(t_user *user_config, StunMessage *m, t_stun_event_type ev_type, unsigned short tuid, unsigned short tid, unsigned long ipaddr, unsigned short port, unsigned short src_port) { t_event_stun_request *event = new t_event_stun_request(user_config, m, ev_type, tuid, tid); MEMMAN_NEW(event); event->dst_addr = ipaddr; event->dst_port = port; event->src_port = src_port; push(event); } void t_event_queue::push_stun_response(StunMessage *m, unsigned short tuid, unsigned short tid) { t_event_stun_response *event = new t_event_stun_response(m, tuid, tid); MEMMAN_NEW(event); push(event); } void t_event_queue::push_nat_keepalive(unsigned long ipaddr, unsigned short port) { t_event_nat_keepalive *event = new t_event_nat_keepalive(); MEMMAN_NEW(event); event->dst_addr = ipaddr; event->dst_port = port; push(event); } void t_event_queue::push_icmp(const t_icmp_msg &m) { t_event_icmp *event = new t_event_icmp(m); MEMMAN_NEW(event); push(event); } void t_event_queue::push_refer_permission_response(bool permission) { t_event_async_response *event = new t_event_async_response( t_event_async_response::RESP_REFER_PERMISSION); MEMMAN_NEW(event); event->set_bool_response(permission); push(event); } void t_event_queue::push_broken_connection(const t_url &user_uri) { t_event_broken_connection *event = new t_event_broken_connection(user_uri); MEMMAN_NEW(event); push(event); } void t_event_queue::push_tcp_ping(const t_url &user_uri, unsigned int dst_addr, unsigned short dst_port) { t_event_tcp_ping *event = new t_event_tcp_ping(user_uri, dst_addr, dst_port); MEMMAN_NEW(event); push(event); } t_event *t_event_queue::pop(void) { t_event *e; bool interrupt; do { interrupt = false; sema_evq.down(); mutex_evq.lock(); if (sema_caught_interrupt.try_down()) { // This pop is non-interruptable, so ignore the interrupt interrupt = true; } else { e = ev_queue.front(); ev_queue.pop(); } mutex_evq.unlock(); } while (interrupt); return e; } t_event *t_event_queue::pop(bool &interrupted) { t_event *e; sema_evq.down(); mutex_evq.lock(); if (sema_caught_interrupt.try_down()) { interrupted = true; e = NULL; } else { interrupted = false; e = ev_queue.front(); ev_queue.pop(); } mutex_evq.unlock(); return e; } void t_event_queue::interrupt(void) { sema_caught_interrupt.up(); sema_evq.up(); } twinkle-1.4.2/src/line.cpp0000644000175000001440000015527711144342761012356 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "exceptions.h" #include "line.h" #include "log.h" #include "sdp/sdp.h" #include "util.h" #include "user.h" #include "userintf.h" #include "audits/memman.h" extern t_event_queue *evq_timekeeper; /////////////// // t_call_info /////////////// t_call_info::t_call_info() { clear(); } void t_call_info::clear(void) { from_uri.set_url(""); from_display.clear(); from_display_override.clear(); from_organization.clear(); to_uri.set_url(""); to_display.clear(); to_organization.clear(); subject.clear(); dtmf_supported = false; hdr_referred_by = t_hdr_referred_by(); last_provisional_reason.clear(); send_codec = CODEC_NULL; recv_codec = CODEC_NULL; refer_supported = false; } string t_call_info::get_from_display_presentation(void) const { if (from_display_override.empty()) { return from_display; } else { return from_display_override; } } /////////// // t_line /////////// /////////// // Private /////////// t_dialog *t_line::match_response(t_response *r, const list &l) const { list::const_iterator i; for (i = l.begin(); i != l.end(); i++) { if ((*i)->match_response(r, 0)) return *i; } return NULL; } t_dialog *t_line::match_response(StunMessage *r, t_tuid tuid, const list &l) const { list::const_iterator i; for (i = l.begin(); i != l.end(); i++) { if ((*i)->match_response(r, tuid)) return *i; } return NULL; } t_dialog *t_line::match_call_id_tags(const string &call_id, const string &to_tag, const string &from_tag, const list &l) const { list::const_iterator i; for (i = l.begin(); i != l.end(); i++) { if ((*i)->match(call_id, to_tag, from_tag)) return *i; } return NULL; } t_dialog *t_line::get_dialog(t_object_id did) const { list::const_iterator i; if (did == 0) return NULL; if (open_dialog && open_dialog->get_object_id() == did) { return open_dialog; } if (active_dialog && active_dialog->get_object_id() == did) { return active_dialog; } for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { if ((*i)->get_object_id() == did) return *i; } for (i = dying_dialogs.begin(); i != dying_dialogs.end(); i++) { if ((*i)->get_object_id() == did) return *i; } return NULL; } void t_line::cleanup(void) { list::iterator i; if (open_dialog && open_dialog->get_state() == DS_TERMINATED) { MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } if (active_dialog && active_dialog->get_state() == DS_TERMINATED) { MEMMAN_DELETE(active_dialog); delete active_dialog; active_dialog = NULL; stop_timer(LTMR_INVITE_COMP); stop_timer(LTMR_NO_ANSWER); // If the call has been ended within 64*T1 seconds // after the reception of the first 2XX response, there // might still be open and pending dialogs. To be nice these // dialogs should be kept till the 64*T1 timer expires. // This complicates the setup of new call however. For // now the dialogs will be killed. If a slow UAS // still responds, it has bad luck and will time out. // // TODO: // A nice solution would be to move the pending and open // dialog to the dying dialog and start a new time 64*T1 // timer to keep the dying dialogs alive. A sequence of // a few short calls would add to the dying dialogs and // keep some dialogs alive longer than necessary. This // only has an impact on resources, not on signalling. // Note that the open dialog must be appended after the // pending dialogs, otherwise all received responses for // a pending dialog will match the open dialog if that // match is tried first by match_response() for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); if (open_dialog) { MEMMAN_DELETE(open_dialog); delete open_dialog; } open_dialog = NULL; } if (active_dialog) { if (active_dialog->get_state() == DS_CONFIRMED_SUB) { // The calls have been released but a subscription is // still active. substate = LSSUB_RELEASING; } else if (active_dialog->will_release()) { substate = LSSUB_RELEASING; } } for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { if ((*i)->get_state() == DS_TERMINATED) { MEMMAN_DELETE(*i); delete *i; *i = NULL; } } pending_dialogs.remove(NULL); for (i = dying_dialogs.begin(); i != dying_dialogs.end(); i++) { if ((*i)->get_state() == DS_TERMINATED) { MEMMAN_DELETE(*i); delete *i; *i = NULL; } } dying_dialogs.remove(NULL); if (!open_dialog && !active_dialog && pending_dialogs.size() == 0) { state = LS_IDLE; if (keep_seized) { substate = LSSUB_SEIZED; } else { substate = LSSUB_IDLE; } is_on_hold = false; is_muted = false; hide_user = false; cleanup_transfer_consult_state(); try_to_encrypt = false; auto_answer = false; call_info.clear(); call_history->add_call_record(call_hist_record); call_hist_record.renew(); phone_user = NULL; user_defined_ringtone.clear(); ui->cb_line_state_changed(); } } void t_line::cleanup_open_pending(void) { if (open_dialog) { MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); if (!active_dialog) { is_on_hold = false; is_muted = false; hide_user = false; cleanup_transfer_consult_state(); try_to_encrypt = false; auto_answer = false; state = LS_IDLE; if (keep_seized) { substate = LSSUB_SEIZED; } else { substate = LSSUB_IDLE; } call_info.clear(); call_history->add_call_record(call_hist_record); call_hist_record.renew(); phone_user = NULL; user_defined_ringtone.clear(); ui->cb_line_state_changed(); } } void t_line::cleanup_forced(void) { list::iterator i; if (open_dialog) { MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } if (active_dialog) { MEMMAN_DELETE(active_dialog); delete active_dialog; active_dialog = NULL; } for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; *i = NULL; } pending_dialogs.remove(NULL); for (i = dying_dialogs.begin(); i != dying_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; *i = NULL; } dying_dialogs.remove(NULL); // TODO: stop running timers? state = LS_IDLE; substate = LSSUB_IDLE; keep_seized = false; is_on_hold = false; is_muted = false; hide_user = false; cleanup_transfer_consult_state(); auto_answer = false; call_info.clear(); call_history->add_call_record(call_hist_record); call_hist_record.renew(); phone_user = NULL; user_defined_ringtone.clear(); ui->cb_line_state_changed(); } void t_line::cleanup_transfer_consult_state(void) { if (is_transfer_consult) { t_line *from_line = phone->get_line(consult_transfer_from_line); from_line->set_to_be_transferred(false, 0); is_transfer_consult = false; } if (to_be_transferred) { t_line *to_line = phone->get_line(consult_transfer_to_line); to_line->set_is_transfer_consult(false, 0); to_be_transferred = false; } } /////////// // Public /////////// t_line::t_line(t_phone *_phone, unsigned short _line_number) : t_id_object() { // NOTE: The rtp_port attribute can only be initialized when // a user profile has been selected. phone = _phone; state = LS_IDLE; substate = LSSUB_IDLE; open_dialog = NULL; active_dialog = NULL; is_on_hold = false; is_muted = false; hide_user = false; is_transfer_consult = false; to_be_transferred = false; try_to_encrypt = false; auto_answer = false; line_number = _line_number; id_invite_comp = 0; id_no_answer = 0; phone_user = NULL; user_defined_ringtone.clear(); keep_seized = false; } t_line::~t_line() { list::iterator i; // Stop timers if (id_invite_comp) stop_timer(LTMR_INVITE_COMP); if (id_no_answer) stop_timer(LTMR_NO_ANSWER); // Delete pointers if (open_dialog) { MEMMAN_DELETE(open_dialog); delete open_dialog; } if (active_dialog) { MEMMAN_DELETE(active_dialog); delete active_dialog; } // Delete dialogs for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } for (i = dying_dialogs.begin(); i != dying_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } } t_line_state t_line::get_state(void) const { return state; } t_line_substate t_line::get_substate(void) const { return substate; } t_refer_state t_line::get_refer_state(void) const { if (active_dialog) return active_dialog->refer_state; return REFST_NULL; } void t_line::start_timer(t_line_timer timer, t_object_id did) { t_tmr_line *t; t_dialog *dialog = get_dialog(did); unsigned long dur; assert(phone_user); switch(timer) { case LTMR_ACK_TIMEOUT: assert(dialog); // RFC 3261 13.3.1.4 if (dialog->dur_ack_timeout == 0) { dialog->dur_ack_timeout = DURATION_T1; } else { dialog->dur_ack_timeout *= 2; if (dialog->dur_ack_timeout > DURATION_T2 ) { dialog->dur_ack_timeout = DURATION_T2; } } t = new t_tmr_line(dialog->dur_ack_timeout , timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_ack_timeout = t->get_object_id(); break; case LTMR_ACK_GUARD: assert(dialog); // RFC 3261 13.3.1.4 t = new t_tmr_line(64 * DURATION_T1, timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_ack_guard = t->get_object_id(); break; case LTMR_INVITE_COMP: // RFC 3261 13.2.2.4 t = new t_tmr_line(64 * DURATION_T1, timer, get_object_id(), did); MEMMAN_NEW(t); id_invite_comp = t->get_object_id(); break; case LTMR_NO_ANSWER: t = new t_tmr_line(DUR_NO_ANSWER(phone_user->get_user_profile()), timer, get_object_id(), did); MEMMAN_NEW(t); id_no_answer = t->get_object_id(); break; case LTMR_RE_INVITE_GUARD: assert(dialog); t = new t_tmr_line(DUR_RE_INVITE_GUARD, timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_re_invite_guard = t->get_object_id(); break; case LTMR_GLARE_RETRY: assert(dialog); if (dialog->is_call_id_owner()) { dur = DUR_GLARE_RETRY_OWN; } else { dur = DUR_GLARE_RETRY_NOT_OWN; } t = new t_tmr_line(dur, timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_glare_retry = t->get_object_id(); break; case LTMR_100REL_TIMEOUT: assert(dialog); // RFC 3262 3 if (dialog->dur_100rel_timeout == 0) { dialog->dur_100rel_timeout = DUR_100REL_TIMEOUT; } else { dialog->dur_100rel_timeout *= 2; } t = new t_tmr_line(dialog->dur_100rel_timeout , timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_100rel_timeout = t->get_object_id(); break; case LTMR_100REL_GUARD: assert(dialog); // RFC 3262 3 t = new t_tmr_line(DUR_100REL_GUARD, timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_100rel_guard = t->get_object_id(); break; case LTMR_CANCEL_GUARD: assert(dialog); t = new t_tmr_line(DUR_CANCEL_GUARD, timer, get_object_id(), did); MEMMAN_NEW(t); dialog->id_cancel_guard = t->get_object_id(); break; default: assert(false); } evq_timekeeper->push_start_timer(t); MEMMAN_DELETE(t); delete t; } void t_line::stop_timer(t_line_timer timer, t_object_id did) { t_object_id *id; t_dialog *dialog = get_dialog(did); switch(timer) { case LTMR_ACK_TIMEOUT: assert(dialog); dialog->dur_ack_timeout = 0; id = &dialog->id_ack_timeout; break; case LTMR_ACK_GUARD: assert(dialog); id = &dialog->id_ack_guard; break; case LTMR_INVITE_COMP: id = &id_invite_comp; break; case LTMR_NO_ANSWER: id = &id_no_answer; break; case LTMR_RE_INVITE_GUARD: assert(dialog); id = &dialog->id_re_invite_guard; break; case LTMR_GLARE_RETRY: assert(dialog); id = &dialog->id_glare_retry; break; case LTMR_100REL_TIMEOUT: assert(dialog); dialog->dur_100rel_timeout = 0; id = &dialog->id_100rel_timeout; break; case LTMR_100REL_GUARD: assert(dialog); id = &dialog->id_100rel_guard; break; case LTMR_CANCEL_GUARD: assert(dialog); id = &dialog->id_cancel_guard; // KLUDGE if (*id == 0) { // Cancel is always sent on the open dialog. // The timer is probably stopped from a pending dialog, // therefore the timer is stopped on the wrong dialog. // Check if the open dialog has a CANCEL guard timer. if (open_dialog) id = &open_dialog->id_cancel_guard; } break; default: assert(false); } if (*id != 0) evq_timekeeper->push_stop_timer(*id); *id = 0; } void t_line::invite(t_phone_user *pu, const t_url &to_uri, const string &to_display, const string &subject, bool no_fork, bool anonymous) { t_hdr_request_disposition hdr_request_disposition; if (no_fork) { hdr_request_disposition.set_fork_directive( t_hdr_request_disposition::NO_FORK); } invite(pu, to_uri, to_display, subject, t_hdr_referred_by(), t_hdr_replaces(), t_hdr_require(), hdr_request_disposition, anonymous); } void t_line::invite(t_phone_user *pu, const t_url &to_uri, const string &to_display, const string &subject, const t_hdr_referred_by &hdr_referred_by, const t_hdr_replaces &hdr_replaces, const t_hdr_require &hdr_require, const t_hdr_request_disposition &hdr_request_disposition, bool anonymous) { assert(pu); // Ignore if line is not idle if (state != LS_IDLE) { return; } assert(!open_dialog); // Validate speaker and mic string error_msg; if (!sys_config->exec_audio_validation(false, true, true, error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); return; } phone_user = pu; t_user *user_config = pu->get_user_profile(); call_info.from_uri = create_user_uri(); // NOTE: hide_user is not set yet call_info.from_display = user_config->get_display(false); call_info.from_organization = user_config->get_organization(); call_info.to_uri = to_uri; call_info.to_display = to_display; call_info.to_organization.clear(); call_info.subject = subject; call_info.hdr_referred_by = hdr_referred_by; try_to_encrypt = user_config->get_zrtp_enabled(); state = LS_BUSY; substate = LSSUB_OUTGOING_PROGRESS; hide_user = anonymous; ui->cb_line_state_changed(); open_dialog = new t_dialog(this); MEMMAN_NEW(open_dialog); open_dialog->send_invite(to_uri, to_display, subject, hdr_referred_by, hdr_replaces, hdr_require, hdr_request_disposition, anonymous); cleanup(); } void t_line::answer(void) { // Ignore if line is idle if (state == LS_IDLE) return; assert(active_dialog); // Validate speaker and mic string error_msg; if (!sys_config->exec_audio_validation(false, true, true, error_msg)) { ui->cb_show_msg(error_msg, MSG_CRITICAL); return; } stop_timer(LTMR_NO_ANSWER); try { substate = LSSUB_ANSWERING; ui->cb_line_state_changed(); active_dialog->answer(); } catch (t_exception x) { // TODO: there is no call to answer } cleanup(); } void t_line::reject(void) { // Ignore if line is idle if (state == LS_IDLE) return; assert(active_dialog); stop_timer(LTMR_NO_ANSWER); try { active_dialog->reject(R_603_DECLINE); } catch (t_exception x) { // TODO: there is no call to reject } cleanup(); } void t_line::redirect(const list &destinations, int code, string reason) { // Ignore if line is idle if (state == LS_IDLE) return; assert(active_dialog); stop_timer(LTMR_NO_ANSWER); try { active_dialog->redirect(destinations, code, reason); } catch (t_exception x) { // TODO: there is no call to redirect } cleanup(); } void t_line::end_call(void) { // Ignore if phone is idle if (state == LS_IDLE) return; if (active_dialog) { substate = LSSUB_RELEASING; ui->cb_line_state_changed(); ui->cb_stop_call_notification(line_number); active_dialog->send_bye(); // If the line was part of a transfer with consultation, // then clean the consultation state as the transfer cannot // proceed anymore. cleanup_transfer_consult_state(); cleanup(); return; } // Always send the CANCEL on the open dialog. // The pending dialogs will be cleared when the INVITE gets // terminated. // CANCEL is send on the open dialog as the CANCEL must have // the same tags as the INVITE. if (open_dialog) { substate = LSSUB_RELEASING; ui->cb_line_state_changed(); ui->cb_stop_call_notification(line_number); open_dialog->send_cancel(!pending_dialogs.empty()); // Make sure dialog is terminated if CANCEL glares with // 2XX on INVITE. for (list::iterator i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { (*i)->set_end_after_2xx_invite(true); } cleanup(); return; } // NOTE: // The call is only ended for real when the dialog reaches // the DS_TERMINATED state, i.e. a 200 OK on BYE is received // or a 487 TERMINATED on INVITE is received. } void t_line::send_dtmf(char digit, bool inband, bool info) { // DTMF may be sent on an early media session, so find // a dialog that has an RTP session. There can be at most 1. t_dialog *d = get_dialog_with_active_session(); if (d) { d->send_dtmf(digit, inband, info); cleanup(); return; } } void t_line::options(void) { if (active_dialog && active_dialog->get_state() == DS_CONFIRMED) { active_dialog->send_options(); cleanup(); return; } } bool t_line::hold(bool rtponly) { if (is_on_hold) return true; if (active_dialog && active_dialog->get_state() == DS_CONFIRMED) { active_dialog->hold(rtponly); is_on_hold = true; ui->cb_line_state_changed(); cleanup(); return true; } return false; } void t_line::retrieve(void) { if (!is_on_hold) return; if (active_dialog && active_dialog->get_state() == DS_CONFIRMED) { active_dialog->retrieve(); is_on_hold = false; ui->cb_line_state_changed(); cleanup(); return; } } void t_line::kill_rtp(void) { if (active_dialog) active_dialog->kill_rtp(); for (list::iterator i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { (*i)->kill_rtp(); } for (list::iterator i = dying_dialogs.begin(); i != dying_dialogs.end(); i++) { (*i)->kill_rtp(); } } void t_line::refer(const t_url &uri, const string &display) { if (active_dialog && active_dialog->get_state() == DS_CONFIRMED) { active_dialog->send_refer(uri, display); ui->cb_line_state_changed(); cleanup(); return; } } void t_line::mute(bool enable) { is_muted = enable; } void t_line::recvd_provisional(t_response *r, t_tuid tuid, t_tid tid) { t_dialog *d; if (active_dialog && active_dialog->match_response(r, 0)) { active_dialog->recvd_response(r, tuid, tid); cleanup(); return; } d = match_response(r, pending_dialogs); if (d) { d->recvd_response(r, tuid, tid); cleanup(); return; } d = match_response(r, dying_dialogs); if (d) { d->recvd_response(r, tuid, tid); cleanup(); return; } if (open_dialog && open_dialog->match_response(r, tuid)) { if (r->hdr_cseq.method == INVITE) { if (r->hdr_to.tag.size() > 0) { // Create a new pending dialog d = open_dialog->copy(); pending_dialogs.push_back(d); d->recvd_response(r, tuid, tid); } else { open_dialog->recvd_response(r, tuid, tid); } } else { open_dialog->recvd_response(r, tuid, tid); } cleanup(); return; } // out-of-dialog response // Provisional responses should only be given for INVITE. // A response for an INVITE is always in a dialog. // Ignore provisional responses for other requests. } void t_line::recvd_success(t_response *r, t_tuid tuid, t_tid tid) { t_dialog *d; if (active_dialog && active_dialog->match_response(r, 0)) { active_dialog->recvd_response(r, tuid, tid); cleanup(); return; } d = match_response(r, pending_dialogs); if (d) { d->recvd_response(r, tuid, tid); if (r->hdr_cseq.method == INVITE) { if (!active_dialog) { // Make the dialog the active dialog active_dialog = d; pending_dialogs.remove(d); start_timer(LTMR_INVITE_COMP); substate = LSSUB_ESTABLISHED; ui->cb_line_state_changed(); } else { // An active dialog already exists. // Terminate this dialog by sending BYE d->send_bye(); } } cleanup(); return; } d = match_response(r, dying_dialogs); if (d) { d->recvd_response(r, tuid, tid); if (r->hdr_cseq.method == INVITE) { d->send_bye(); } cleanup(); return; } if (open_dialog && open_dialog->match_response(r, tuid)) { if (r->hdr_cseq.method == INVITE) { // Create a new dialog d = open_dialog->copy(); if (!active_dialog) { active_dialog = d; active_dialog->recvd_response(r, tuid, tid); start_timer(LTMR_INVITE_COMP); substate = LSSUB_ESTABLISHED; ui->cb_line_state_changed(); } else { pending_dialogs.push_back(d); d->recvd_response(r, tuid, tid); // An active dialog already exists. // Terminate this dialog by sending BYE d->send_bye(); } } else { open_dialog->recvd_response(r, tuid, tid); } cleanup(); return; } // Response does not match with any pending request. Discard. } void t_line::recvd_redirect(t_response *r, t_tuid tuid, t_tid tid) { t_dialog *d; assert(phone_user); t_user *user_config = phone_user->get_user_profile(); if (active_dialog) { // If an active dialog exists then non-2XX should // only be for this dialog. if (active_dialog->match_response(r, 0)) { // Redirection of mid-dialog request if (!user_config->get_allow_redirection() || !active_dialog->redirect_request(r)) { // Redirection not allowed/failed active_dialog->recvd_response(r, tuid, tid); } // Retrieve a held line after a REFER failure if (r->hdr_cseq.method == REFER && active_dialog->out_refer_req_failed) { active_dialog->out_refer_req_failed = false; if (phone->get_active_line() == line_number && user_config->get_referrer_hold()) { retrieve(); } } } cleanup(); return; } d = match_response(r, pending_dialogs); if (d) { d->recvd_response(r, tuid, tid); if (r->hdr_cseq.method == INVITE) { pending_dialogs.remove(d); MEMMAN_DELETE(d); delete d; // RFC 3261 13.2.2.3 // All early dialogs are considered terminated // upon reception of the non-2xx final response. list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); if (open_dialog) { if (!user_config->get_allow_redirection() || !open_dialog->redirect_invite(r)) { MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } } } cleanup(); return; } d = match_response(r, dying_dialogs); if (d) { d->recvd_response(r, tuid, tid); cleanup(); return; } if (open_dialog && open_dialog->match_response(r, tuid)) { if (r->hdr_cseq.method != INVITE) { // TODO: can there be a non-INVITE response for an // open dialog?? open_dialog->recvd_response(r, tuid, tid); } if (r->hdr_cseq.method == INVITE) { if (!user_config->get_allow_redirection() || !open_dialog->redirect_invite(r)) { // Redirection failed/not allowed open_dialog->recvd_response(r, tuid, tid); MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } // RFC 3261 13.2.2.3 // All early dialogs are considered terminated // upon reception of the non-2xx final response. list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); } cleanup(); return; } // out-of-dialog responses should be handled by the phone } void t_line::recvd_client_error(t_response *r, t_tuid tuid, t_tid tid) { t_dialog *d; assert(phone_user); t_user *user_config = phone_user->get_user_profile(); if (active_dialog) { // If an active dialog exists then non-2XX should // only be for this dialog. if (active_dialog->match_response(r, 0)) { bool response_processed = false; if (r->must_authenticate()) { // Authentication for mid-dialog request if (active_dialog->resend_request_auth(r)) { // Authorization successul. // The response does not need to be // processed any further response_processed = true; } } if (!response_processed) { // The request failed, redirect it if there // are other destinations available. if (!user_config->get_allow_redirection() || !active_dialog->redirect_request(r)) { // Request failed active_dialog-> recvd_response(r, tuid, tid); } } // Retrieve a held line after a REFER failure if (r->hdr_cseq.method == REFER && active_dialog->out_refer_req_failed) { active_dialog->out_refer_req_failed = false; if (phone->get_active_line() == line_number && user_config->get_referrer_hold()) { retrieve(); } } } cleanup(); return; } d = match_response(r, pending_dialogs); if (d) { if (r->hdr_cseq.method != INVITE) { if (r->must_authenticate()) { // Authentication for non-INVITE request in pending dialog if (!d->resend_request_auth(r)) { // Could not authorize, send response to dialog // where it will be handle as a client failure. d->recvd_response(r, tuid, tid); } } else { d->recvd_response(r, tuid, tid); } } else { d->recvd_response(r, tuid, tid); pending_dialogs.remove(d); MEMMAN_DELETE(d); delete d; // RFC 3261 13.2.2.3 // All early dialogs are considered terminated // upon reception of the non-2xx final response. list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); if (open_dialog) { bool response_processed = false; if (r->must_authenticate()) { // INVITE authentication if (open_dialog->resend_invite_auth(r)) { // Authorization successul. // The response does not need to // be processed any further response_processed = true; } } // Resend INVITE if the response indicated that // required extensions are not supported. if (!response_processed && open_dialog->resend_invite_unsupported(r)) { response_processed = true; } if (!response_processed) { // The request failed, redirect it if there // are other destinations available. if (!user_config->get_allow_redirection() || !open_dialog->redirect_invite(r)) { // Request failed MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } } } } cleanup(); return; } d = match_response(r, dying_dialogs); if (d) { d->recvd_response(r, tuid, tid); cleanup(); return; } if (open_dialog && open_dialog->match_response(r, tuid)) { // If the response is a 401/407 then do not send the // response to the dialog as the request must be resent. // For an INVITE request, the transaction layer has already // sent ACK for a failure response. if (r->hdr_cseq.method != INVITE) { if (r->must_authenticate()) { // Authenticate non-INVITE request if (!open_dialog->resend_request_auth(r)) { // Could not authorize, handle as other client // errors. open_dialog->recvd_response(r, tuid, tid); } } else { open_dialog->recvd_response(r, tuid, tid); } } if (r->hdr_cseq.method == INVITE) { bool response_processed = false; if (r->must_authenticate()) { // INVITE authentication if (open_dialog->resend_invite_auth(r)) { // Authorization successul. // The response does not need to // be processed any further response_processed = true; } } // Resend INVITE if the response indicated that // required extensions are not supported. if (!response_processed && open_dialog->resend_invite_unsupported(r)) { response_processed = true; } if (!response_processed) { // The request failed, redirect it if there // are other destinations available. if (!user_config->get_allow_redirection() || !open_dialog->redirect_invite(r)) { // Request failed open_dialog->recvd_response(r, tuid, tid); MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } } // RFC 3261 13.2.2.3 // All early dialogs are considered terminated // upon reception of the non-2xx final response. list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); } cleanup(); return; } // out-of-dialog responses should be handled by the phone } void t_line::recvd_server_error(t_response *r, t_tuid tuid, t_tid tid) { t_dialog *d; assert(phone_user); t_user *user_config = phone_user->get_user_profile(); if (active_dialog) { // If an active dialog exists then non-2XX should // only be for this dialog. if (active_dialog->match_response(r, 0)) { bool response_processed = false; if (r->code == R_503_SERVICE_UNAVAILABLE) { // RFC 3263 4.3 // Failover to next destination if (active_dialog->failover_request(r)) { // Failover successul. // The response does not need to be // processed any further response_processed = true; } } if (!response_processed) { // The request failed, redirect it if there // are other destinations available. if (!user_config->get_allow_redirection() || !active_dialog->redirect_request(r)) { // Request failed active_dialog-> recvd_response(r, tuid, tid); } } // Retrieve a held line after a REFER failure if (r->hdr_cseq.method == REFER && active_dialog->out_refer_req_failed) { active_dialog->out_refer_req_failed = false; if (phone->get_active_line() == line_number && user_config->get_referrer_hold()) { retrieve(); } } } cleanup(); return; } d = match_response(r, pending_dialogs); if (d) { d->recvd_response(r, tuid, tid); if (r->hdr_cseq.method == INVITE) { pending_dialogs.remove(d); MEMMAN_DELETE(d); delete d; // RFC 3261 13.2.2.3 // All early dialogs are considered terminated // upon reception of the non-2xx final response. list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); if (open_dialog) { bool response_processed = false; if (r->code == R_503_SERVICE_UNAVAILABLE) { // INVITE failover if (open_dialog->failover_invite()) { // Failover successul. // The response does not need to // be processed any further response_processed = true; } } if (!response_processed) { // The request failed, redirect it if there // are other destinations available. if (!user_config->get_allow_redirection() || !open_dialog->redirect_invite(r)) { // Request failed MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } } } } cleanup(); return; } d = match_response(r, dying_dialogs); if (d) { d->recvd_response(r, tuid, tid); cleanup(); return; } if (open_dialog && open_dialog->match_response(r, tuid)) { // If the response is a 503 then do not send the // response to the dialog as the request must be resent. // For an INVITE request, the transaction layer has already // sent ACK for a failure response. if (r->code != R_503_SERVICE_UNAVAILABLE && r->hdr_cseq.method != INVITE) { open_dialog->recvd_response(r, tuid, tid); } if (r->hdr_cseq.method == INVITE) { bool response_processed = false; if (r->code == R_503_SERVICE_UNAVAILABLE) { // INVITE failover if (open_dialog->failover_invite()) { // Failover successul. // The response does not need to // be processed any further response_processed = true; } } if (!response_processed) { // The request failed, redirect it if there // are other destinations available. if (!user_config->get_allow_redirection() || !open_dialog->redirect_invite(r)) { // Request failed open_dialog->recvd_response(r, tuid, tid); MEMMAN_DELETE(open_dialog); delete open_dialog; open_dialog = NULL; } } // RFC 3261 13.2.2.3 // All early dialogs are considered terminated // upon reception of the non-2xx final response. list::iterator i; for (i = pending_dialogs.begin(); i != pending_dialogs.end(); i++) { MEMMAN_DELETE(*i); delete *i; } pending_dialogs.clear(); } cleanup(); return; } // out-of-dialog responses should be handled by the phone } void t_line::recvd_global_error(t_response *r, t_tuid tuid, t_tid tid) { recvd_redirect(r, tuid, tid); } void t_line::recvd_invite(t_phone_user *pu, t_request *r, t_tid tid, const string &ringtone) { t_user *user_config = NULL; switch (state) { case LS_IDLE: assert(!active_dialog); assert(r->hdr_to.tag == ""); /* // TEST ONLY // Test code to test INVITE authentication if (!r->hdr_authorization.is_populated()) { resp = r->create_response(R_401_UNAUTHORIZED); t_challenge c; c.auth_scheme = AUTH_DIGEST; c.digest_challenge.realm = "mtel.nl"; c.digest_challenge.nonce = "0123456789abcdef"; c.digest_challenge.opaque = "secret"; c.digest_challenge.algorithm = ALG_MD5; c.digest_challenge.qop_options.push_back(QOP_AUTH); c.digest_challenge.qop_options.push_back(QOP_AUTH_INT); resp->hdr_www_authenticate.set_challenge(c); send_response(resp, 0, tid); return; } */ assert(pu); phone_user = pu; user_config = phone_user->get_user_profile(); user_defined_ringtone = ringtone; call_info.from_uri = r->hdr_from.uri; call_info.from_display = r->hdr_from.display; call_info.from_display_override = r->hdr_from.display_override; if (r->hdr_organization.is_populated()) { call_info.from_organization = r->hdr_organization.name; } else { call_info.from_organization.clear(); } call_info.to_uri = r->hdr_to.uri; call_info.to_display = r->hdr_to.display; call_info.to_organization.clear(); call_info.subject = r->hdr_subject.subject; try_to_encrypt = user_config->get_zrtp_enabled(); // Check for REFER support // If the Allow header is not present then assume REFER // is supported. if (!r->hdr_allow.is_populated() || r->hdr_allow.contains_method(REFER)) { call_info.refer_supported = true; } active_dialog = new t_dialog(this); MEMMAN_NEW(active_dialog); active_dialog->recvd_request(r, 0, tid); state = LS_BUSY; substate = LSSUB_INCOMING_PROGRESS; ui->cb_line_state_changed(); start_timer(LTMR_NO_ANSWER); cleanup(); // Answer if auto answer mode is activated if (auto_answer) { // Validate speaker and mic string error_msg; if (!sys_config->exec_audio_validation(false, true, true, error_msg)) { ui->cb_display_msg(error_msg, MSG_CRITICAL); } else { answer(); } } break; case LS_BUSY: // Only re-INVITEs can be sent to a busy line assert(r->hdr_to.tag != ""); /* // TEST ONLY // Test code to test re-INVITE authentication if (!r->hdr_authorization.is_populated()) { resp = r->create_response(R_401_UNAUTHORIZED); t_challenge c; c.auth_scheme = AUTH_DIGEST; c.digest_challenge.realm = "mtel.nl"; c.digest_challenge.nonce = "0123456789abcdef"; c.digest_challenge.opaque = "secret"; c.digest_challenge.algorithm = ALG_MD5; c.digest_challenge.qop_options.push_back(QOP_AUTH); c.digest_challenge.qop_options.push_back(QOP_AUTH_INT); resp->hdr_www_authenticate.set_challenge(c); send_response(resp, 0, tid); return; } */ if (active_dialog && active_dialog->match_request(r)) { // re-INVITE active_dialog->recvd_request(r, 0, tid); cleanup(); return; } // Should not get here as phone already checked that // the request matched with this line assert(false); break; default: assert(false); } } void t_line::recvd_ack(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); substate = LSSUB_ESTABLISHED; ui->cb_line_state_changed(); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid) { // A CANCEL matches a dialog if the target tid equals the tid // of the INVITE request. This will be checked by // dialog::recvd_cancel() itself. if (active_dialog) { active_dialog->recvd_cancel(r, cancel_tid, target_tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_bye(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_options(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_prack(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_subscribe(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_notify(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_info(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } void t_line::recvd_message(t_request *r, t_tid tid) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); } bool t_line::recvd_refer(t_request *r, t_tid tid) { bool retval = false; if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_request(r, 0, tid); retval = active_dialog->refer_accepted; } else { // Should not get here as phone already checked that // the request matched with this line assert(false); } cleanup(); return retval; } void t_line::recvd_refer_permission(bool permission, t_request *r) { if (active_dialog && active_dialog->match_request(r)) { active_dialog->recvd_refer_permission(permission, r); } cleanup(); } void t_line::recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid) { t_dialog *d; if (active_dialog && active_dialog->match_response(r, tuid)) { active_dialog->recvd_stun_resp(r, tuid, tid); cleanup(); return; } if (open_dialog && open_dialog->match_response(r, tuid)) { open_dialog->recvd_stun_resp(r, tuid, tid); cleanup(); return; } d = match_response(r, tuid, pending_dialogs); if (d) { d->recvd_stun_resp(r, tuid, tid); cleanup(); return; } d = match_response(r, tuid, dying_dialogs); if (d) { d->recvd_stun_resp(r, tuid, tid); cleanup(); return; } } void t_line::failure(t_failure failure, t_tid tid) { // TODO } void t_line::timeout(t_line_timer timer, t_object_id did) { t_dialog *dialog = get_dialog(did); list cf_dest; // call forwarding destinations switch (timer) { case LTMR_ACK_TIMEOUT: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_ack_timeout = 0; dialog->timeout(timer); } break; case LTMR_ACK_GUARD: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_ack_guard = 0; dialog->dur_ack_timeout = 0; dialog->timeout(timer); } break; case LTMR_INVITE_COMP: id_invite_comp = 0; // RFC 3261 13.2.2.4 // The UAC core considers the INVITE transaction completed // 64*T1 seconds after the reception of the first 2XX // response. // Cleanup all open and pending dialogs cleanup_open_pending(); break; case LTMR_NO_ANSWER: // User did not answer the call. // Reject call or redirect it if CF_NOANSWER is active. // If there is no active dialog then ignore the timeout. // The timer should have been stopped already. log_file->write_report("No answer timeout", "t_line::timeout"); if (active_dialog) { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); t_service *srv = phone->ref_service(user_config); if (srv->get_cf_active(CF_NOANSWER, cf_dest)) { log_file->write_report("Call redirection no answer", "t_line::timeout"); active_dialog->redirect(cf_dest, R_302_MOVED_TEMPORARILY); } else { active_dialog->reject(R_480_TEMP_NOT_AVAILABLE, REASON_480_NO_ANSWER); } ui->cb_answer_timeout(get_line_number()); } break; case LTMR_RE_INVITE_GUARD: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_re_invite_guard = 0; dialog->timeout(timer); } break; case LTMR_GLARE_RETRY: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_glare_retry = 0; dialog->timeout(timer); } break; case LTMR_100REL_TIMEOUT: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_100rel_timeout = 0; dialog->timeout(timer); } break; case LTMR_100REL_GUARD: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_100rel_guard = 0; dialog->dur_100rel_timeout = 0; dialog->timeout(timer); } break; case LTMR_CANCEL_GUARD: // If there is no dialog then ignore the timeout if (dialog) { dialog->id_cancel_guard = 0; dialog->timeout(timer); } break; default: assert(false); } cleanup(); } void t_line::timeout_sub(t_subscribe_timer timer, t_object_id did, const string &event_type, const string &event_id) { t_dialog *dialog = get_dialog(did); if (dialog) dialog->timeout_sub(timer, event_type, event_id); cleanup(); } bool t_line::match(t_response *r, t_tuid tuid) const { if (open_dialog && open_dialog->match_response(r, tuid)) { return true; } if (active_dialog && active_dialog->match_response(r, 0)) { return true; } if (match_response(r, pending_dialogs)) { return true; } if (match_response(r, dying_dialogs)) { return true; } return false; } bool t_line::match(t_request *r) const { assert(r->method != CANCEL); return (active_dialog && active_dialog->match_request(r)); } bool t_line::match_cancel(t_request *r, t_tid target_tid) const { assert(r->method == CANCEL); // A CANCEL matches a dialog if the target tid equals the tid // of the INVITE request. return (active_dialog && active_dialog->match_cancel(r, target_tid)); } bool t_line::match(StunMessage *r, t_tuid tuid) const { if (open_dialog && open_dialog->match_response(r, tuid)) { return true; } if (active_dialog && active_dialog->match_response(r, tuid)) { return true; } if (match_response(r, tuid, pending_dialogs)) { return true; } if (match_response(r, tuid, dying_dialogs)) { return true; } return false; } bool t_line::match_replaces(const string &call_id, const string &to_tag, const string &from_tag, bool no_fork_req_disposition, bool &early_matched) const { if (active_dialog && active_dialog->match(call_id, to_tag, from_tag)) { early_matched = false; return true; } // RFC 3891 3 // An early dialog only matches when it was created by the UA // As an exception to this rule we accept a match when the incoming // request contained a no-fork request disposition. This disposition // indicated that the request did not fork. The reason why RFC 3891 3 // does not allow a match is to avoid problems with forked requests. // With this exception, call transfer scenario's during ringing can // be implemented. t_dialog *d; if ((d = match_call_id_tags(call_id, to_tag, from_tag, pending_dialogs)) != NULL && (d->is_call_id_owner() || no_fork_req_disposition)) { early_matched = true; return true; } return false; } bool t_line::is_invite_retrans(t_request *r) { assert(r->method == INVITE); return (active_dialog && active_dialog->is_invite_retrans(r)); } void t_line::process_invite_retrans(void) { if (active_dialog) active_dialog->process_invite_retrans(); } string t_line::create_user_contact(const string &auto_ip) const { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); return user_config->create_user_contact(hide_user, auto_ip); } string t_line::create_user_uri(void) const { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); return user_config->create_user_uri(hide_user); } t_response *t_line::create_options_response(t_request *r, bool in_dialog) const { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); return phone->create_options_response(user_config, r, in_dialog); } void t_line::send_response(t_response *r, t_tuid tuid, t_tid tid) { if (hide_user) { r->hdr_privacy.add_privacy(PRIVACY_ID); } phone->send_response(r, tuid, tid); } void t_line::send_request(t_request *r, t_tuid tuid) { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); phone->send_request(user_config, r, tuid); } t_phone *t_line::get_phone(void) const { return phone; } unsigned short t_line::get_line_number(void) const { return line_number; } bool t_line::get_is_on_hold(void) const { return is_on_hold; } bool t_line::get_is_muted(void) const { return is_muted; } bool t_line::get_hide_user(void) const { return hide_user; } bool t_line::get_is_transfer_consult(unsigned short &lineno) const { lineno = consult_transfer_from_line; return is_transfer_consult; } void t_line::set_is_transfer_consult(bool enable, unsigned short lineno) { is_transfer_consult = enable; consult_transfer_from_line = lineno; } bool t_line::get_to_be_transferred(unsigned short &lineno) const { lineno = consult_transfer_to_line; return to_be_transferred; } void t_line::set_to_be_transferred(bool enable, unsigned short lineno) { to_be_transferred = enable; consult_transfer_to_line = lineno; } bool t_line::get_is_encrypted(void) const { t_audio_session *as = get_audio_session(); if (as) return as->get_is_encrypted(); return false; } bool t_line::get_try_to_encrypt(void) const { return try_to_encrypt; } bool t_line::get_auto_answer(void) const { return auto_answer; } void t_line::set_auto_answer(bool enable) { auto_answer = enable; } bool t_line::is_refer_succeeded(void) const { if (active_dialog) return active_dialog->refer_succeeded; return false; } bool t_line::has_media(void) const { t_session *session = get_session(); return (session && !session->receive_host.empty() && !session->dst_rtp_host.empty()); } t_url t_line::get_remote_target_uri(void) const { if (!active_dialog) return t_url(); return active_dialog->get_remote_target_uri(); } t_url t_line::get_remote_target_uri_pending(void) const { if (pending_dialogs.empty()) return t_url(); return pending_dialogs.front()->get_remote_target_uri(); } string t_line::get_remote_target_display(void) const { if (!active_dialog) return ""; return active_dialog->get_remote_target_display(); } string t_line::get_remote_target_display_pending(void) const { if (pending_dialogs.empty()) return ""; return pending_dialogs.front()->get_remote_target_display(); } t_url t_line::get_remote_uri(void) const { if (!active_dialog) return t_url(); return active_dialog->get_remote_uri(); } t_url t_line::get_remote_uri_pending(void) const { if (pending_dialogs.empty()) return t_url(); return pending_dialogs.front()->get_remote_uri(); } string t_line::get_remote_display(void) const { if (!active_dialog) return ""; return active_dialog->get_remote_display(); } string t_line::get_remote_display_pending(void) const { if (pending_dialogs.empty()) return ""; return pending_dialogs.front()->get_remote_display(); } string t_line::get_call_id(void) const { if (!active_dialog) return ""; return active_dialog->get_call_id(); } string t_line::get_call_id_pending(void) const { if (pending_dialogs.empty()) return ""; return pending_dialogs.front()->get_call_id(); } string t_line::get_local_tag(void) const { if (!active_dialog) return ""; return active_dialog->get_local_tag(); } string t_line::get_local_tag_pending(void) const { if (pending_dialogs.empty()) return ""; return pending_dialogs.front()->get_local_tag(); } string t_line::get_remote_tag(void) const { if (!active_dialog) return ""; return active_dialog->get_remote_tag(); } string t_line::get_remote_tag_pending(void) const { if (pending_dialogs.empty()) return ""; return pending_dialogs.front()->get_remote_tag(); } bool t_line::remote_extension_supported(const string &extension) const { if (!active_dialog) return false; return active_dialog->remote_extension_supported(extension); } bool t_line::seize(void) { // Only an idle line can be seized. if (substate != LSSUB_IDLE) return false; substate = LSSUB_SEIZED; ui->cb_line_state_changed(); return true; } void t_line::unseize(void) { // Only a seized line can be unseized. if (substate != LSSUB_SEIZED) return; substate = LSSUB_IDLE; ui->cb_line_state_changed(); } t_session *t_line::get_session(void) const { if (!active_dialog) return NULL; return active_dialog->get_session(); } t_audio_session *t_line::get_audio_session(void) const { if (!active_dialog) return NULL; return active_dialog->get_audio_session(); } void t_line::notify_refer_progress(t_response *r) { if (active_dialog) active_dialog->notify_refer_progress(r); } void t_line::failed_retrieve(void) { // Call retrieve failed, so line is still on-hold is_on_hold = true; ui->cb_line_state_changed(); } void t_line::failed_hold(void) { // Call hold failed, so line is not on-hold is_on_hold = false; ui->cb_line_state_changed(); } void t_line::retry_retrieve_succeeded(void) { // Retry of retrieve succeeded, so line is not on-hold anymore is_on_hold = false; ui->cb_line_state_changed(); } t_call_info t_line::get_call_info(void) const { return call_info; } void t_line::ci_set_dtmf_supported(bool supported, bool inband, bool info) { call_info.dtmf_supported = supported; call_info.dtmf_inband = inband; call_info.dtmf_info = info; } void t_line::ci_set_last_provisional_reason(const string &reason) { call_info.last_provisional_reason = reason; } void t_line::ci_set_send_codec(t_audio_codec codec) { call_info.send_codec = codec; } void t_line::ci_set_recv_codec(t_audio_codec codec) { call_info.recv_codec = codec; } void t_line::ci_set_refer_supported(bool supported) { call_info.refer_supported = supported; } void t_line::init_rtp_port(void) { rtp_port = sys_config->get_rtp_port() + line_number * 2; } unsigned short t_line::get_rtp_port(void) const { return rtp_port; } t_user *t_line::get_user(void) const { t_user *user_config = NULL; if (phone_user) { user_config = phone_user->get_user_profile(); } return user_config; } t_phone_user *t_line::get_phone_user(void) const { return phone_user; } string t_line::get_ringtone(void) const { assert(phone_user); t_user *user_config = phone_user->get_user_profile(); if (!user_defined_ringtone.empty()) { // Ring tone returned by incoming call script return user_defined_ringtone; } else if (!user_config->get_ringtone_file().empty()) { // Ring tone from user profile return user_config->get_ringtone_file(); } else if (!sys_config->get_ringtone_file().empty()) { // Ring tone from system settings return sys_config->get_ringtone_file(); } else { // Twinkle default return FILE_RINGTONE; } } void t_line::confirm_zrtp_sas(void) { t_audio_session *as = get_audio_session(); if (as && !as->get_zrtp_sas_confirmed()) { as->confirm_zrtp_sas(); ui->cb_zrtp_sas_confirmed(line_number); ui->cb_line_state_changed(); log_file->write_header("t_line::confirm_zrtp_sas"); log_file->write_raw("Line "); log_file->write_raw(line_number + 1); log_file->write_raw(": User confirmed ZRTP SAS\n"); log_file->write_footer(); } } void t_line::reset_zrtp_sas_confirmation(void) { t_audio_session *as = get_audio_session(); if (as && as->get_zrtp_sas_confirmed()) { as->reset_zrtp_sas_confirmation(); ui->cb_zrtp_sas_confirmation_reset(line_number); ui->cb_line_state_changed(); log_file->write_header("t_line::reset_zrtp_sas_confirmation"); log_file->write_raw("Line "); log_file->write_raw(line_number + 1); log_file->write_raw(": User reset ZRTP SAS confirmation\n"); log_file->write_footer(); } } void t_line::enable_zrtp(void) { t_audio_session *as = get_audio_session(); if (as) { as->enable_zrtp(); } } void t_line::zrtp_request_go_clear(void) { t_audio_session *as = get_audio_session(); if (as) { as->zrtp_request_go_clear(); } } void t_line::zrtp_go_clear_ok(void) { t_audio_session *as = get_audio_session(); if (as) { as->zrtp_go_clear_ok(); } } void t_line::force_idle(void) { cleanup_forced(); } void t_line::set_keep_seized(bool seize) { keep_seized = seize; cleanup(); } bool t_line::get_keep_seized(void) const { return keep_seized; } t_dialog *t_line::get_dialog_with_active_session(void) const { if (open_dialog && open_dialog->has_active_session()) { return open_dialog; } if (active_dialog && active_dialog->has_active_session()) { return active_dialog; } for (list::const_iterator it = pending_dialogs.begin(); it != pending_dialogs.end(); ++it) { if ((*it)->has_active_session()) { return *it; } } for (list::const_iterator it = dying_dialogs.begin(); it != dying_dialogs.end(); ++it) { if ((*it)->has_active_session()) { return *it; } } return NULL; } twinkle-1.4.2/src/util.cpp0000644000175000001440000003465711134642145012400 00000000000000/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "twinkle_config.h" string month_abbrv[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; string month_full[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; string day_abbrv[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; string random_token(int length) { string s; for (int i = 0; i < length; i++) { s += char(rand() % 26 + 97); } return s; } string random_hexstr(int length) { string s; int x; for (int i = 0; i < length; i++) { x = rand() % 16; if (x <= 9) s += '0' + x; else s += 'a' + x - 10; } return s; } string float2str(float f, int precision) { ostringstream s; // Force the locale to POSIX, such that a dot is used for // the decimal point. s.imbue(locale("POSIX")); s.setf(ios::fixed,ios::floatfield); s.precision(precision); s << f; return s.str(); } string int2str(int i, const char *format) { char buf[32]; snprintf(buf, 32, format, i); return string(buf); } string int2str(int i) { return int2str(i, "%d"); } string ulong2str(unsigned long i, const char *format) { char buf[32]; snprintf(buf, 32, format, i); return string(buf); } string ulong2str(unsigned long i) { return ulong2str(i, "%u"); } string ptr2str(void *p) { char buf[32]; snprintf(buf, 32, "%p", p); return string(buf); } string bool2str(bool b) { return (b ? "true" : "false"); } string time2str(time_t t, const char *format) { struct tm tm; char buf[64]; localtime_r(&t, &tm); strftime(buf, 64, format, &tm); return string(buf); } string current_time2str(const char *format) { struct timeval t; gettimeofday(&t, NULL); return time2str(t.tv_sec, format); } string weekday2str(int wkday) { if (wkday >= 0 && wkday <= 6) return day_abbrv[wkday]; return "XXX"; } string month2str(int month) { if (month >= 0 && month <= 11) return month_abbrv[month]; return "XXX"; } int str2month_full(const string &month) { for (int i = 0; i < 12; i++) { if (cmp_nocase(month_full[i], month) == 0) { return i; } } return 0; } string duration2str(unsigned long seconds) { string result; long remainder, h, m, s; h = seconds / 3600; remainder = seconds % 3600; m = remainder / 60; s = remainder % 60; if (h > 0) { result = ulong2str(h); result += "h "; } if (!result.empty() || m > 0) { result += ulong2str(m); result += "m "; } result += ulong2str(s); result += "s"; return result; } string timer2str(unsigned long seconds) { string result; unsigned long remainder, h, m, s; h = seconds / 3600; remainder = seconds % 3600; m = remainder / 60; s = remainder % 60; char buf[16]; snprintf(buf, 16, "%01lu:%02lu:%02lu", h, m, s); return string(buf); } static uint8 hexdig2value(char hexdig) { uint8 val = 0; if (hexdig >= '0' && hexdig <= '9') val = hexdig - '0'; else if (hexdig >= 'a' && hexdig <= 'f') val = hexdig - 'a' + 10; else if (hexdig >= 'A' && hexdig <= 'F') val = hexdig - 'A' + 10; return val; } static char value2hexdig(uint8 val) { char c = '0'; if (val <= 9) { c = '0' + val; } else if (val <= 15) { c = 'a' + val - 10; } return c; } unsigned long hex2int(const string &h) { unsigned long u = 0; int power = 1; for (string::const_reverse_iterator i = h.rbegin(); i != h.rend(); ++i) { u += hexdig2value(*i) * power; power = power * 16; } return u; } void hex2binary(const string &h, uint8 *buf) { uint8 *p = buf; bool hi_nibble = true; for (string::const_iterator i = h.begin() ; i != h.end(); ++i) { if (hi_nibble) { *p = hexdig2value(*i) << 4; } else { *(p++) |= hexdig2value(*i); } hi_nibble = !hi_nibble; } } string binary2hex(uint8 *buf, unsigned long len) { string s; for (uint8 *p = buf; p < buf + len; ++p) { s += value2hexdig((*p >> 4) & 0xf); s += value2hexdig(*p & 0xf); } return s; } string tolower(const string &s) { string result; for (string::const_iterator i = s.begin(); i != s.end(); ++i) { result += tolower(*i); } return result; } string toupper(const string &s) { string result; for (string::const_iterator i = s.begin(); i != s.end(); ++i) { result += toupper(*i); } return result; } string rtrim(const string &s) { string::size_type i; i = s.find_last_not_of(' '); if (i == string::npos) return ""; if (i == s.size()-1) return s; return s.substr(0, i+1); } string ltrim(const string &s) { string::size_type i; i = s.find_first_not_of(' '); if (i == string::npos) return ""; if (i == 0) return s; return s.substr(i, s.size()-i+1); } string trim(const string &s) { return ltrim(rtrim(s)); } string padleft(const string &s, char c, unsigned long len) { string result(c, len); result += s; return result.substr(result.size() - len); } int cmp_nocase(const string &s1, const string &s2) { string::const_iterator i1 = s1.begin(); string::const_iterator i2 = s2.begin(); while (i1 != s1.end() && i2 != s2.end()) { if (toupper(*i1) != toupper(*i2)) { return (toupper(*i1) < toupper(*i2)) ? -1 : 1; } ++i1; ++i2; } if (s1.size() == s2.size()) return 0; if (s1.size() < s2.size()) return -1; return 1; } bool must_quote(const string &s) { string special("()<>@,;:\\\"/[]?={} \t"); if (s.size() == 0) return true; return (s.find_first_of(special) != string::npos); } string escape(const string &s, char c) { string result; for (string::size_type i = 0; i < s.size(); i++) { if (s[i] == '\\' || s[i] == c) { result += '\\'; } result += s[i]; } return result; } string unescape(const string &s) { string result; for (string::size_type i = 0; i < s.size(); i++) { if (s[i] == '\\' && i < s.size() - 1) { i++; } result += s[i]; } return result; } string escape_hex(const string &s, const string &unreserved) { string result; for (string::size_type i = 0; i < s.size(); i++) { if (unreserved.find(s[i], 0) != string::npos) { // Unreserved symbol result += s[i]; } else { // Reserved symbol result += int2str((int)s[i], "%%%02x"); } } return result; } string unescape_hex(const string &s) { string result; for (string::size_type i = 0; i < s.size(); i++) { if (s[i] == '%' && i < s.size() - 2 && isxdigit(s[i+1]) && isxdigit(s[i+2])) { // Escaped hex-value string hexval = s.substr(i+1, 2); result += static_cast(hex2int(hexval)); i += 2; } else { result += s[i]; } } return result; } string replace_char(const string &s, char from, char to) { string result = s; for (string::size_type i = 0; i < result.size(); i++) { if (result[i] == from) result[i] = to; } return result; } string replace_first(const string &s, const string &from, const string &to) { string result = s; string::size_type i = result.find(from, 0); if (i != string::npos) { result.replace(i, from.size(), to); } return result; } vector split(const string &s, char c) { string::size_type i; string::size_type j = 0; vector l; while (true) { i = s.find(c, j); if (i == string::npos) { l.push_back(s.substr(j)); return l; } if (i == j) l.push_back(""); else l.push_back(s.substr(j, i-j)); j = i+1; if (j == s.size()) { l.push_back(""); return l; } } } vector split(const string &s, const string& separator) { string::size_type i; string::size_type j = 0; vector l; while (true) { i = s.find(separator, j); if (i == string::npos) { l.push_back(s.substr(j)); return l; } if (i == j) l.push_back(""); else l.push_back(s.substr(j, i-j)); j = i + separator.size(); if (j == s.size()) { l.push_back(""); return l; } } } vector split_linebreak(const string &s) { if (s.find("\r\n") != string::npos) { return split(s, "\r\n"); } else if (s.find("\r") != string::npos) { return split(s, "\r"); } return split(s, "\n"); } vector split_on_first(const string &s, char c) { vector l; string::size_type i = s.find(c); if (i == string::npos) { l.push_back(s); } else { if (i == 0) { l.push_back(""); } else { l.push_back(s.substr(0, i)); } if (i == s.size() - 1) { l.push_back(""); } else { l.push_back(s.substr(i + 1)); } } return l; } vector split_on_last(const string &s, char c) { vector l; string::size_type i = s.find_last_of(c); if (i == string::npos) { l.push_back(s); } else { if (i == 0) { l.push_back(""); } else { l.push_back(s.substr(0, i)); } if (i == s.size() - 1) { l.push_back(""); } else { l.push_back(s.substr(i + 1)); } } return l; } vector split_escaped(const string &s, char c) { vector l; string::size_type start_pos = 0; for (string::size_type i = 0; i < s.size(); i++) { if (s[i] == '\\') { // Skip escaped character if (i < s.size()) i++; continue; } if (s[i] == c) { l.push_back(unescape(s.substr(start_pos, i - start_pos))); start_pos = i + 1; } } if (start_pos < s.size()) { l.push_back(unescape(s.substr(start_pos, s.size() - start_pos))); } else if (start_pos == s.size()) { l.push_back(""); } return l; } vector split_ws(const string &s, bool quote_sensitive) { vector l; bool in_quotes = false; string::size_type start_pos = 0; for (string::size_type i = 0; i < s.size(); i++ ) { if (quote_sensitive && s[i] == '"') { in_quotes = !in_quotes; continue; } if (in_quotes) continue; if (s[i] == ' ' || s[i] == '\t') { // Skip consecutive white space if (start_pos != i) { l.push_back(s.substr(start_pos, i - start_pos)); } start_pos = i + 1; } } if (start_pos < s.size()) { l.push_back(s.substr(start_pos, s.size() - start_pos)); } return l; } string join_strings(const vector &v, const string &separator) { string text; for (vector::const_iterator it = v.begin(); it != v.end(); ++it) { if (it != v.begin()) { text += separator; } text += *it; } return text; } string unquote(const string &s) { if (s.size() <= 1) return s; if (s[0] == '"' && s[s.size() - 1] == '"') return s.substr(1, s.size() - 2); return s; } bool is_number(const string &s) { if (s.empty()) return false; for (string::size_type i = 0; i < s.size(); i++ ) { if (!isdigit(s[i])) return false; } return true; } bool is_ipaddr(const string &s) { vector l = split(s, '.'); if (l.size() != 4) return false; for (vector::iterator i = l.begin(); i != l.end(); ++i) { if (!is_number(*i) || atoi(i->c_str()) > 255) return false; } return true; } bool yesno2bool(const string &yesno) { return (yesno == "yes" ? true : false); } string bool2yesno(bool b) { return (b ? "yes" : "no"); } string str2dtmf(const string &s) { string result; string to_convert = tolower(s); for (string::size_type i = 0; i < to_convert.size(); i++) { switch (to_convert[i]) { case '1': result += '1'; break; case '2': case 'a': case 'b': case 'c': result += '2'; break; case '3': case 'd': case 'e': case 'f': result += '3'; break; case '4': case 'g': case 'h': case 'i': result += '4'; break; case '5': case 'j': case 'k': case 'l': result += '5'; break; case '6': case 'm': case 'n': case 'o': result += '6'; break; case '7': case 'p': case 'q': case 'r': case 's': result += '7'; break; case '8': case 't': case 'u': case 'v': result += '8'; break; case '9': case 'w': case 'x': case 'y': case 'z': result += '9'; break; case '0': case ' ': result += '0'; break; case '#': case '*': result += to_convert[i]; break; } } return result; } bool looks_like_phone(const string &s, const string &special_symbols) { string phone_symbols= special_symbols + "0123456789*#+ \t"; string t; for (string::const_iterator i = s.begin(); i != s.end(); ++i) { if (phone_symbols.find(*i) == string::npos) return false; } return true; } string remove_symbols(const string &s, const string &special_symbols) { string result; for (string::const_iterator i = s.begin(); i != s.end(); ++i) { if (special_symbols.find(*i) == string::npos) { result += *i; } } return result; } string remove_white_space(const string &s) { string result; for (string::const_iterator i = s.begin(); i != s.end(); ++i) { if (*i != ' ' && *i != '\t') { result += *i; } } return result; } string dotted_truncate(const string &s, string::size_type len) { if (len >= s.size()) return s; return s.substr(0, len) + "..."; } string to_printable(const string &s) { string result; for (string::const_iterator i = s.begin(); i != s.end(); ++i) { if (isprint(*i) || *i == '\n' || *i == '\r') { result += *i; } else { result += '.'; } } return result; } string get_error_str(int errnum) { #if HAVE_STRERROR_R char buf[81]; memset(buf, 0, sizeof(buf)); #if STRERROR_R_CHAR_P string errmsg(strerror_r(errnum, buf, sizeof(buf)-1)); #else string errmsg; if (strerror_r(errnum, buf, sizeof(buf)-1) == 0) { errmsg = buf; } else { errmsg = "unknown error: "; errmsg += int2str(errnum); } #endif #else string errmsg("strerror_r is not available: "); errmsg += int2str(errnum); #endif return errmsg; } twinkle-1.4.2/NEWS0000644000175000001440000007616511151327447010633 0000000000000025 february 2009 - 1.4.2 ======================== - Integration with Diamondcard Worldwide Communication Service (worldwide calls to regular and cell phones and SMS). - Show number of calls and total call duration in call history. - Show message size while typing an instant message. - Show "referred by" party for an incoming transferred call in systray popup. - Option to allow call transfer while consultation call is still in progress. - Improved lock file checking. No more stale lock files. Bug fixes: ---------- - Opening an IM attachment did not work anymore. Build fixes: ------------ - Link with ncurses library 31 january 2009 - 1.4.1 ======================= Bug fixes: ---------- - No sound when Twinkle is compiled without speex support. Build fixes: ------------ - Compiling without KDE sometimes failed (cannot find -lqt-mt). - Configure script did not correctly check for the readline-devel package. 25 january 2009 - 1.4 ===================== - Service route discovery during registration. - Codec preprocessing: automatic gain control, voice activation detection, noise reduction, acoustic echo cancellation (experimental). - Support tel-URI as destination address for a call or instant message. - User profile option to expand a telephone number to a tel-URI instead of a sip-URI. - Add descending q-value to contacts in 3XX responses for the redirection services. - AKAv1-MD5 authentication. - Command line editing, history, auto-completion. - Ignore wrong formatted domain-parameter in digest challenge. - Match tel-URI in incoming call to address book. - Determine RTP IP address for SDP answer from RTP IP address in SDP offer. - Show context menu's when pressing the right mouse button instead of after clicking. - Swedish translation - Resampled ringback tone from 8287 Hz to 8000 Hz Bug fixes --------- - Text line edit in the message form looses focus after sending an IM. - Twinkle does not escape reserved symbols when dialing. - Deregister all function causes a crash. - Twinkle crashes at startup in CLI mode. - Twinkle may freeze when an ALSA error is detected when starting the ringback tone and the outgoing call gets answered very fast. - User profile editor did not allow spaces in a user name. New RFC's --------- RFC 3608 - Session Initiation Protocol (SIP) Extension Header Field for Service Route Discovery During Registration 24 august 2008 - 1.3.2 ====================== - Fix in non-KDE version for gcc 4.3 23 august 2008 - 1.3.1 ====================== - Disable file attachment button in message window when destination address is not filled in - Updated russian translation Build fixes ----------- - Fixes for gcc 4.3 (missing includes) - non-KDE version failed to build 18 august 2008 - 1.3 ==================== - Send file attachment with instant message. - Show timestamp with instant messages. - Instant message composition indication (RFC 3994). - Persistent TCP connections with keep alive. - Do not try to send SIP messages larger than 64K via UDP. - Integration with libzrtcpp-1.3.0 - Xsession support to restore Twinkle after system shutdown/startup. - Call snd_pcm_state to determine jitter buffer exhaustion (some ALSA implementations gave problems with the old method). - SDP parser allows SDP body without terminating CRLF. - Russian translation. Bug fixes --------- - SIP parser did not allow white space between header name and colon. - With "send in-dialog requests to proxy" enabled and transport mode set to "auto", in-dialog requests are wrongly sent via TCP. - Crash when a too large message is received. - Comparison of authentication parameters (e.g. algorithm) were case-sensitive. These comparisons must be case-insensitive. - SDP parser could not parse other media transports than RTP/AVP. - Twinkle sent 415 response instead of 200 OK on in-dialog INFO without body. - Twinkle responds with 513 Message too large on an incoming call. - ICMP error on STUN request causes Twinkle to crash. - Add received-parameter to Via header of an incoming request if it contains an empty rport parameter (RFC 3581) - Twinkle did not add Contact header and copy Record-Route header to 180 response. New RFC's --------- RFC 3994 - Indication of Message Composition for Instant Messaging 8 march 2008 - 1.2 ================== - SIP over TCP - Automatic selection of IP address. * On a multi-homed machine you do not have to select an IP address/NIC anymore. - Support for sending a q-value in a registration contact. - Send DTMF on an early media stream. - Choose auth over auth-int qop when server supports both for authentication. This avoids problems with SIP ALGs. - Support tel-URI in From and To headers in incoming SIP messages. - Print a log rotation message at end of log when a log file is full. - Remove 20 character limit on profile names. - Reject an incoming MESSAGE with 603 if max. sessions == 0 - Delivery notification when a 202 response is received on a MESSAGE. Bug fixes --------- - When you deactivate a profile that has MWI active, but MWI subscription failed, and subsequently activate this profile again, then Twinkle does not subscribe to MWI. - The max redirection value was always set to 1. - Leading space in the body of a SIP message causes a parse failure - Twinkle crashes with SIGABRT when it receives an INVITE with a CSeq header that contains an invalid method. - Latest release of lrelease corrupted translation files. - Twinkle crashes on 'twinkle --cmd line' - If an MWI NOTIFY does not contain a voice msg summary, twinkle shows a random number for the amount of messages waiting. - Depending on the locale Twinkle encoded a q-value with a comma instead of a dot as decimal point. Build changes ------------- - Modifications for gcc 4.3. - Remove fast sequence of open/close calls for ALSA to avoid problems with bluez. 21 july 2007 - 1.1 ================== - French translation - Presence - Instant messaging - New CLI commands: presence, message Bug fixes --------- - If a session was on-hold and Twinkle received a re-INVITE without SDP, it would offer SDP on-hold in the 200 OK, instead of a brand new SDP offer. - Twinkle refused to change to another profile with the same user name as the current active profile. - ICMP processing did not work most times (uninitialized data). - Replace strerror by strerror_r (caused rare SIGSEGV crashes) - Fix deadlock in timekeeper (caused rare freezes) New RFC's --------- RFC 3428 - Session Initiation Protocol (SIP) Extension for Instant Messaging RFC 3856 - A Presence Event Package for the Session Initiation Protocol (SIP) RFC 3863 - Presence Information Data Format (PIDF) RFC 3903 - Session Initiation Protocol (SIP) Extension for Event State Publication 19 may 2007 - 1.0.1 =================== - Czech translation - Check on user profiles having the same contact name at startup. - When comparing an incoming INVITE request-URI with the contact-name, ignore the host part to avoid NAT problems. - A call to voice mail will not be attached to the "redial" button. - Added voice mail entry to services and systray menu. - New command line options: --show, --hide - TWINKLE_LINE environment variable in scripts. This variable contains the line number (starting at 1) associated with a trigger. - Preload KAddressbook at startup. - Allow multiple occurrences of the display_msg parameter in the incoming call script to create multi-line messages. - Handle SIP forking and early media interaction Bug fixes --------- - Fix conference call - If lock file still exists when you start Twinkle, Twinkle asks if it should start anyway. When you click 'yes', Twinkle does not start. - Audio validation opened soundcard in stereo instead of mono - When quitting Twinkle while the call history window is open, a segfault occurs - When an incoming call is rejected when only unsupported codecs are offered, it does not show as a missed call in the call history. - Segfault when the remote party establishes an early media session without sending a to-tag in the 1XX response (some Cisco devices). - in_call_failed trigger was not called when the call failed before ringing. - Escape double quote with backslash in display name. - On some system Twinkle occasionally crashed at startup with the following error: Xlib: unexpected async reply Build Changes ------------- - Remove AC_CHECK_HEADERS([]) from configure.in - Configure checks for lrelease. Other ----- - Very small part of the comments has been formatted now for automatic documentation generation with doxygen. 22 jan 2007 - 1.0 ================= - Local address book - Message waiting indication (MWI) * Sollicted MWI as specified by RFC 3842 * Unsollicited MWI as implemented by Asterisk - Voice mail speed dial - Call transfer with consultation * This is a combination of a consultation call on the other line followed by a blind transfer. - Attended call transfer * This is a combination of a consultation call on the other line followed by a replacement from B to C of the call on the first line. This is only possible if the C-party supports "replaces". If "replaces" is not supported, then twinkle automatically falls back to "transfer with consultation". - User identity hiding - Multi language support This version contains Dutch and German translations - Send BYE when a CANCEL/2XX INVITE glare occurs. - When call release was not immediate due to network problems or protocol errors, the line would be locked for some time. Now Twinkle releases a call in the background immediately freeing the line for new calls. - Escape reserved symbols in a URI by their hex-notation (%hex). - Changed key binding for Bye from F7 to ESC - When a lock file exists at startup, Twinkle asks if you want to override it - New command line options: --force, --sip-port, --rtp-port - Ring tone and speaker device list now also shows playback only devices - Microphone device list now also shows capture only devices - Validate audio device settings on startup, before making a call, before answering a call. - SIP_FROM_USER, SIP_FROM_HOST, SIP_TO_USER, SIP_TO_HOST variables for call scripts. - display_msg parameter added to incoming call script - User profile options to indicate which codec preference to follow - Twinkle now asks permission for an incoming REFER asynchronously. This prevents blocking of the transaction layer. - Highlight missed calls in call history - Support for G.726 ATM AAL2 codeword packing - replaces SIP extension (RFC 3891) - norefesub SIP extension (RFC 4488) - SIP parser supports IPv6 addresses in SIP URI's and Via headers (Note: Twinkle does not support transport over IPv6) - Support mid-call change of SSRC - Handling of SIGCHLD, SIGTERM and SIGINT on platforms implementing LinuxThreads instead of NPTL threading (e.g. sparc) Bug fixes --------- - Invalid speex payload when setting ptime=30 for G.711 - When editing the active user profile via File -> Change User -> Edit QObject::connect: No such slot MphoneForm::displayUser(t_user*) - 32 s after call setup the DTMF button gets disabled. - 4XX response on INVITE does not get properly handled. From/To/Subject labels are not cleared. No call history record is made. - The dial combobox accepted a newline through copy/past. This corrupted the system settings. - When a far-end responds with no supported codecs, Twinkle automatically releases the call. If the far-end sends an invalid response on this release and the user pressed the BYE button, Twinkle crashed. - When using STUN the private port was put in the Via header instead of the public port. - Twinkle crashes once in a while, while it is just sitting idle. Build changes ------------- - If libbind exists then link with libbind, otherwise link with libresolv This solves GLIBC_PRIVATE errors on Fedora - Link with libboost_regex or libboost_regex-gcc New RFC's --------- RFC 3323 - A Privacy Mechanism for the Session Initiation Protocol (SIP) RFC 3325 - Private Extensions to the Session Initiation Protocol (SIP) for Asserted Identity within Trusted Networks RFC 3842 - A Message Summary and Message Waiting Indication Event Package for the Session Initiation Protocol (SIP) RFC 3891 - The Session Initiation Protocol (SIP) "Replaces" Header RFC 4488 - Suppression of Session Initiation Protocol (SIP) REFER Method Implicit Subscription 01 oct 2006 - Release 0.9 ========================= - Supports Phil Zimmermann's ZRTP and SRTP for secure voice communication. ZRTP/SRTP is provided by the latest version (1.5.0) of the GNU ccRTP library. The implementation is interoperable with Zfone beta2 - SIP INFO method (RFC 2976) - DTMF via SIP INFO - G.726 codec (16, 24, 32 and 48 kbps modes) - Option to hide display - CLI command "answerbye" to answer an incoming or hangup an established call - Switch lines from system tray menu - Answer or reject a call from the KDE systray popup on incoming call - Icons to indicate line status - Default NIC option in system settings - Accept SDP offer without m= lines (RFC 3264 section 5, RFC 3725 flow IV) Bug fixes --------- - t_audio::open did not return a value - segmentation fault when quitting Twinkle in transient call state - Twinkle did not accept message/sipfrag body with a single CRLF at the end - user profile could not be changed on service redirect dialog - Twinkle did not react to 401/407 authentication challenges for PRACK, REFER, SUBSCRIBE and NOTIFY Build changes ------------- - For ZRTP support you need to install libzrtpcpp first. This library comes as an extension library with ccRTP. 09 jul 2006 - Release 0.8.1 =========================== - Removed iLBC source code from Twinkle. To use iLBC you can link Twinkle with the ilbc library (ilbc package). When you have the ilbc library installed on your system, then Twinkle's configure script will automatically setup the Makefiles to link with the library. Bug fixes --------- - Name and photo lookups in KAddressbook on incoming calls may freeze Twinkle. Build improvements ------------------ - Added missing includes to userprofile.ui and addressfinder.h - Configure has new --without-speex option 01 jul 2006 - Release 0.8 ========================= - iLBC - Make supplementary service settings persistent - Lookup name in address book for incoming call - Display photo from address book of caller on incoming call - Number conversion rules - Always popup systray notification (KDE only) on incoming call - Add organization and subject to incoming call popup - New call script trigger points: incoming call answered, incoming call failed, outgoing call, outgoing call answered, outgoing call failed, local release, remote release. - Added 'end' parameter for the incoming call script - Option to provision ALSA and OSS devices that are not in the standard list of devices. - Option to auto show main window on incoming call - Resized the user profile window such that it fits on an 800x600 display - Popup the user profile selection window, when the SIP UDP port is occupied during startup of Twinkle, so the user can change to another port. - Skip unsupported codecs in user profile during startup Bug fixes --------- - Sometimes the NAT discovery window never closed - When RTP timestamps wrap around some RTP packets may be discarded - When the dial history contains an entry of insane length, the main window becomes insanely large on next startup - On rare occasions, Twinkle could respond to an incoming call for a deactivated user profile. - Credentials cache did not get erased when a failure response other than 401/407 was received on a REGISTER with credentials. - G.711 enocders amplified soft noise from the microphone. Newly supported RFC's --------------------- RFC 3951 - Internet Low Bit Rate Codec (iLBC) RFC 3952 - Real-time Transport Protocol (RTP) Payload Format for internet Low Bit Rate Codec (iLBC) Speech Build notes ----------- - New dependency on libboost-regex (boost package) 07 may 2006 - Release 0.7.1 =========================== - Check that --call and --cmd arguments are not empty - When DTMF transport is "inband", then do not signal RFC2833 support in SDP Bug fixes --------- - CLI and non-KDE version hang when stopping ring tone - The GUI allowed payload type 96-255 for DTMF and Speex, while maximum value is only 127 - When a dynamic codec change takes place at the same time as a re-INVITE Twinkle sometimes freezes. - Sending RFC 2833 DTMF events fails when codec is speex-wb or speex-uwb 29 apr 2006 - Release 0.7 ========================= - Speex support (narrow, wide and ultra wide band) - Support for dynamic payload numbers for audio codecs in SDP - Inband DTMF (option for DTMF transport in user profile) - UTF-8 support to properly display non-ASCII characters - --cmd command line option to remotely execute CLI commands - --immediate command line option to perform --call and --cmd without user confirmation. - --set-profile command line option to set the active profile. - Support "?subject=" as part of address for --call - The status icon are always displayed: gray -> inactive, full color -> active - Clicking the registration status icon fetches current registration status - Clicking the service icons enables/disables the service - Fancier popup from KDE system tray on incoming call. - Popup from system tray shows as long as the phone is ringing. - Reload button on address form - Remove special phone number symbols from dialed strings. This option can be enabled/disabled via the user profile. - Remove duplicate entries from the dial history drop down box - Specify in the user profile what symbols are special symbols to remove. - Changed default for "use domain to create unique contact header value" to "no" - New SIP protocol option: allow SDP change in INVITE responses - Do not ask username and password when authentication for an automatic re-regsitration fails. The user may not be at his desk, and the authentication dialog stalls Twinkle. - Ask authentication password when user profile contains authentication name, but no password. - Improved handling of socket errors when interface goes down temporarily. Bug fixes --------- - If the far end holds a call and then resumes a call while Twinkle has been put locally on-hold, then Twinkle will start recording sound from the mic and send it to the far-end while indicating that the call is still on-hold. - Crash on no-op SDP in re-INVITE - Twinkle exits when it receives SIGSTOP followed by SIGCONT - call release cause in history is incorrect for incoming calls. Build improvements ------------------ - Break dependency on X11/xpm.h 26 feb 2006 - Release 0.6.2 =========================== - Graceful termination on reception of SIGINT and SIGTERM Bug fixes --------- - If the URI in a received To-header is not enclosed by '<' and '>', then the tag parameter is erronesouly parsed as a URI parameter instead of a header parameter. This causes failing call setup, tear down, when communicating with a far-end that does not enclose the URI in angle brackets in the To-header. - Function to flush OSS buffers flushed a random amount of samples that could cause sound clipping (at start of call and after call hold) when using OSS. - In some cases Twinkle added "user=phone" to a URI when the URI already had a user parameter. 11 feb 2006 - Release 0.6.1 =========================== - action=autoanswer added to call script actions - Performance improvement of --call parameter - Synchronized dial history drop downs on main window and call dialog - Dial history drop down lists are stored persistently - Redial information is stored persistently Bug fixes --------- - When using STUN Twinkle freezes when making a call and the STUN server does not respond within 200 ms (since version 0.2) - Some malformed SIP messages triggered a memory leak in the parser code generated by bison (since version 0.1) - The lexical scanner jammed on rubbish input (since version 0.1) 05 feb 2006 - Release 0.6 ========================= - Custom ring tones (package libsndfile is needed) - Twinkle can call a user defineable script for each incoming call. With this script the user can: * reject, redirect or accept a call * define a specific ring tone (distinctive ringing) - Missed call indication - Call directly from the main window - DTMF keys can by typed directly from the keyboard at the main window. Letters are converted to the corresponding digits. - Letters can be typed in the DTMF window. They are converted to digits. - Call duration in call history - Call duration timer while call is established - Added --call parameter to command line to instruct Twinkle to make a call - Increased expiry timer for outgoing RTP packets to 160 ms With this setting slow sound cards should give better sound quality for the mic. - System setting to disable call waiting. - System setting to modify hangup behaviour of 3-way call. Hang up both lines or only the active line. - Replace dots with underscores in contact value - Silently discard packets on the SIP port smaller than 10 bytes - User profile option to disable the usage of the domain name in the contact header. - Graceful release of calls when quitting Twinkle - Changed call hold default from RFC2543 to RFC3264 Bug fixes --------- - An '=' in a value of a user profile or system settings parameter caused a syntax error - If a default startup profile was renamed, the default startup list was not updated - When call was put on-hold using RFC2543 method, the host in the SDP o= line was erroneously set to 0.0.0.0 - When a response with wrong tags but correct branch was received, a line would hang forever (RFC 3261 did not specify this scenario). - If far end responds with 200 OK to CANCEL, but never sends 487 on INVITE as mandated by RFC 3261, then a line would hang forever - CPU load was sometimes excessive when using ALSA 01 jan 2006 - Release 0.5 ========================= - Run multiple user profiles in parallel - Add/remove users while Twinkle is running - The SIP UDP port and RTP port settings have been moved from the user profile to system settings. Changes of the default values in the user profile will be lost. - DNS SRV support for SIP and STUN - ICMP processing - SIP failover on 503 response - SIP and STUN failover on ICMP error - When a call is originated from the call history, copy the subject to the call window (prefixed with "Re:" when replying to a call). - Remove '/' from a phone number taken from KAddressbook. / is used in Germany to separate the area code from the local number. - Queue incoming in-dialog request if ACK has not been received yet. - Clear credentials cache when user changes realm, username or password - Added micro seconds to timestamps in log - Detecting a soundcard playing out at slightly less than 8000 samples per second is now done on the RTP queue status. This seems to be more reliable than checking the ALSA sound buffer filling. - OSS fragment size and ALSA period size are now changeable via the system settings. Some soundcard problems may be solved by changing these values. - Default ALSA period size for capturing lowered from 128 to 32. This seems to give better performance on some sound cards. Bug fixes --------- - With certain ALSA settings (eg. mic=default, speaker=plughw), the ALSA device got locked up after 1 call. - The ports used for NAT discovery via STUN stayed open. - When a STUN transaction for a media port failed, the GUI did not clear the line information fields. - Sending DTMF events took many unnecessary CPU cycles - Parse failure when Server or User-Agent header contained comment only Newly supported RFC's --------------------- RFC 2782 - A DNS RR for specifying the location of services (DNS SRV) RFC 3263 - Session Initiation Protocol (SIP): Locating SIP Servers 28 nov 2005 - Release 0.4.2 =========================== - Microphone noise reduction (can be disabled in system settings) - System tray icon shows status of active line and enabled services - Call history option added to system tray menu Bug fixes --------- - Twinkle crashes at startup when the systray icon is disabled in the system settings. - Line stays forever in dialing state when pressing ESC in the call window 19 nov 2005 - Release 0.4.1 =========================== - Fixed build problems with gcc-4.0.2 and qt3-3.4.4 18 nov 2005 - Release 0.4 ========================= - Interface to KAddressbook - History of incoming and outgoing calls (successful and missed calls) - History of 10 last calls on call dialog window for redialling - Call and service menu options added to KDE sys tray icon - Allow a missing mandatory Expires header in a 2XX response on SUBSCRIBE - Big Endian support for sound playing (eg. PPC platforms) - System setting to start Twinkle hidden in system tray - System setting to start with a default profile - System setting to start on a default IP address - Command line option (-i) for IP address Bug fixes --------- - send a 500 failure response on a request that is received out of order instead of discarding the request. - 64bit fix in events.cpp - race condition on starting/stopping audio threads could cause a crash - segmentation fault when RTP port could not be opened. - CLI looped forever on reaching EOF - 64bit fix in events.cpp - ALSA lib pcm_hw.c:590:(snd_pcm_hw_pause) SNDRV_PCM_IOCTL_PAUSE failed - sometimes when quitting Twinkle a segmentation fault occurred Build improvements ------------------ - Removed platform dependent code from stunRand() in stun.cxx - It should be possible to build Twinkle without the KDE addons on a non-KDE system - new option --without-kde added to configure to build a non-KDE version of Twinkle 22 oct 2005 - Release 0.3.2 =========================== - Fixed several build problams with KDE include files and libraries. If you already succesfully installed release 0.3.1 then there is no need to upgrade to 0.3.2 as there is no new functionality. 16 oct 2005 - Release 0.3.1 =========================== This is a minor bug fix release. Bug fixes: ---------- - Command line options -f and -share were broken in release 0.3 This release fixes the command line options. 09 oct 2005 - Release 0.3 ========================= New functionality: ------------------ - ALSA support - System tray icon - Send NAT keep alive packets when Twinkle sits behind a symmetric firewall (discovered via STUN) - Allow missing or wrong Contact header in a 200 OK response on a REGISTER Bug fixes: ---------- - Hostnames in Via and Warning headers were erroneously converted to lower case. - t_ts_non_invite::timeout assert( t==TIMER_J ) when ACK is received for a non-INVITE request that had INVITE as method in the CSeq header. - The SIP/SDP parser accepted a port number > 65535. This caused an assert - Segmentation fault on some syntax errors in SIP headers - Line got stuck when CSeq sequence nr 0 was received. RFC 3261 allows 0. - With 100rel required, every 1XX after the first 1XX response were discarded. - Fixed build problems on 64-bit architectures. - Dead lock due to logging in UDP sender. - Segmentation fault when packet loss occurred while the sequence number in the RTP packets wrapped around. - Route set was not recomputed on reception of a 2XX response, when a 1XX repsonse before already contained a Record-Route header. 30 jul 2005 - Release 0.2.1 =========================== New functionality: ------------------ - Clear button on log view window. Bug fixes: ---------- - The system settings window confused the speaker and mic settings. - Log view window sometimes opened behind other windows. - Segmentation fault when SUBSCRIBE with expires=0 was received to end a refer subscription. - When a call transfer fails, the original call is received. If the line for this call is not the active call however, the call should stay on-hold. - On rare occasions a segmentation fault occurred when the ring tone was stopped. - Log view window sometimes caused deadlock. 24 jul 2005 - Release 0.2 ========================= New functionality: ------------------ - STUN support for NAT traversal - Blind call transfer service - Reject call transfer request - Auto answer service - REFER, NOTIFY and SUBSCRIBE support for call transfer scenario's * REFER is sent for blind call transfer. Twinkle accpets incoming NOTIFY messages about the transfer progress. Twinkle can send SUBSCRIBE to extend refer event subscription * Incoming REFER within dialog is handled by Twinkle Twinkle sends NOTIFY messages during transfer. Incoming SUBSCRIBE to extend refer event subscription is granted. - Retry re-INVITE after a glare (491 response, RFC 3261 14.1) - Respond with 416 if a request with a non-sip URI is received - Multiple sound card support for playing ring tone to a different device than speech - The To-tag in a 200 OK on a CANCEL was different than the To-tag in a provisional response on the INVITE. RFC 3261 recommends that these To-tags are the same. Twinkle now uses the same To-tag. - Show error messages to user when trying to submit invalid values on the user profile - DTMF volume configurable via user profile - Log viewer - User profile wizard - Help texts for many input fields (e.g. in user profile). Help can be accessed by pressing Ctrl+F1 or using the question mark from the title bar. Bug fixes: ---------- - A retransmission of an incoming INVITE after a 2XX has been sent was seen as a new INVITE. - If an OPTIONS request timed out then the GUI did not release its lock causing a deadlock. - If the URI in a To, From, Contact or Reply-To header is not enclosed by < and >, then the parameters (separated by a semi-colon) belong to the header, NOT to the URI. They were parsed as parameters of the URI. This could cause the loss of a tag-parameter causing call setup failures. - Do not resize window when setting a long string in to, from or subject Newly supported RFC's --------------------- RFC 3265 - Session Initiation Protocol (SIP)-Specific Event Notification RFC 3420 - Internet Media Type message/sipfrag RFC 3489 - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs) RFC 3515 - The Session Initiation Protocol (SIP) Refer Method RFC 3892 - The Session Initiation Protocol (SIP) Referred-By Mechanism 27 apr 2005 - Release 0.1 ========================= First release of Twinkle, a SIP VoIP client. - Basic calls - 2 call appearances (lines) - Call Waiting - Call Hold - 3-way conference calling - Mute - Call redirection on demand - Call redirection unconditional - Call redirection when busy - Call redirection no answer - Reject call redirection request - Call reject - Do not disturb - Send DTMF digits to navigate IVR systems - NAT traversal through static provisioning - Audio codecs: G.711 A-law, G.711 u-law, GSM Supported RFC's --------------- - RFC 2327 - SDP: Session Description Protocol - RFC 2833 - RTP Payload for DTMF Digits - RFC 3261 - SIP: Session Initiation Protocol - RFC 3262 - Reliability of Provisional Responses in SIP - RFC 3264 - An Offer/Answer Model with the Session Description Protocol (SDP) - RFC 3581 - An extension to SIP for Symmetric Response Routing - RFC 3550 - RTP: A Transport Protocol for Real-Time Applications RFC 3261 is not fully implemented yet. - No TCP transport support, only UDP - No DNS SRV support, only DNS A-record lookup - Only plain SDP bodies are supported, no multi-part MIME or S/MIME - Only sip: URI support, no sips: URI support twinkle-1.4.2/data/0000777000175000001440000000000011151327717011112 500000000000000twinkle-1.4.2/data/providers.csv0000644000175000001440000000037410503576710013563 00000000000000# provider;domain;sip proxy;stun server FreeWorld Dialup;fwd.pulver.com;;stun.fwdnet.net sipgate.at;sipgate.at;;sipgate.at sipgate.co.uk;sipgate.co.uk;;sipgate.co.uk sipgate.de;sipgate.de;;sipgate.de SIPphone!;proxy01.sipphone.com;;stun01.sipphone.com twinkle-1.4.2/data/ringback.wav0000644000175000001440000004075611130204570013325 00000000000000RIFFæAWAVEfmt @@dataÂA‡Š‹†€}†y„…‡…ƒŽž¤•Š~~„‚ƒ‡†~‚’Ÿ´Ê²s?=d|•ªÀÝèïþÿÿüìÔ¶‘J -Ut‚umw~„{fM71AXr–¹É×éøÿÿþÿþÿûá´„T6$%548@DDKROA+"/?BAHF3(.;Tkt‚–¡¥¢Ÿ¡¬¾Ïâ÷ÿþþÿþÿþÿþÿþþÿþÿúêÕÀ±§—†ykaI&   )5AC?BOf›¯½ÆÊµ°°¸Îâëîô÷ðåÓÇÌÚëùýøëÙ¼ ‘‡‚ŽœŸ“~o]MNZguyjaP7,05AQWXcfXRPM]t~‡‘‘‘‘…{z}„’Ÿ¥­¸·«¦¢£±ÉàñõòîãϺ¯°³ÁÐËÁ±–€q_Zk}„…t_G1,=MX\]UGDEJa~“Ÿ¤ª¥”†zx‡š«¾ÉËȾ²¨¤®ÀÑÚÙÕЬ˜ˆ‰”šž•Šrb[boy|unql\NDEP_o{zsrps ³·±ª˜ƒurx”©µµª•†|…™¨¶ÄÊÈÀ¬}€†Ž’“’ŒkbgixŒ“–˜–“Ž~j__er}€‚‡†ƒ‡…y|ŠŽŒ•—}k``kyŽ›œ˜• ¤ ¦²º½³¥–‚qgfm{‰™£šŒ†‡ˆ‡Œ’–—’ƒsms}€Š†uopt}€ƒˆ–œ–…xsyƒ‡••’Žˆ†„€†‘”–ž©±¬–‡‚~€‚€ˆ—£¬±µ¯–’~l`Z\gv|{~~†ŒŽ‹ŒŽ…~}wmq~~y‡††ƒ„’ž£¨¦  ž—‘‹„ƒˆŽŒš ¢›””“‹‡†‚~ŒŒƒ~~yvuwzz|ˆ“ž¥¤™Œ„{yx|~{•›¦ª¯´°¤™•’˜˜’‡|toosv¦­¢™šobeotuplqˆŒ‘””‘’“‰~~‚‰“¡ª£•‹Œ–œ›˜™˜¡¯­ž‘†yry€„…€xnjkrwz€ƒ„Ž•Œ‚|}‘ §®¥zngjy†›­¶¼»­’…}…‰rsy„•˜”›¤¥¤€yrp|‡ˆˆ„wpw~‚‰ŒŠ”¨±§“Š{d\_o€†ˆ}x€‡‰’‘—¥©šŠ„|€¤±­£•€nntux~‚¦¨—“Ž€{€‹›¦¥Ÿ›“‡‰“’‡€…”¡„|oqz}ƒŒ‹{m_RWepxƒ—¨³­œ‚tsx|‚††‚‰˜ž›¥µÀÉÀ®¢•‘•𢦍¥—…tmrwx~Š’“|fVVY^jqv€€~}{}€€†“›š‹~€…ˆŽ•™¡©žŒ‹’¤¨°ºÁºŸ…‚ƒ}|~‡†{wuv‰ˆ‰•ž™ˆ‚ƒ~{w{}shfgl{‡‡Š”Ÿ¤”x|}z{‚‰“  ”Ž’˜™˜œž¢¢–Œ…‡ŽŠŠ‰’Ž„ƒ–›œ™šŸšŠ}wsopy…ƒuks}|}ƒ’˜“’Ž‹ŒŠ„€€†Š…zw†“˜Ÿ¢ž¢£™•ˆ‹‹†€š”ˆ‚ŠŽ“’‘“ˆ€~}ut|…Œ‰€‰•¡¤Ÿš”‰‚‚ywy~€€|spv~‚ƒŒšž•‘Žƒ~€‰—˜‹„œœœœŸ¢¥¥™ŸŸŒ——†xsyƒ…ƒ|{~}{unnrrlowvxyv|Œœ¡š•–—”–›œ–‘•“ˆ‰ŽŒ‰„€Šœ¤¢žœ˜“–œ“Š‹‰}y~upuz†Ž‡}~€€ˆ•“‹Ž‰ƒ€~|„–¢”’’‘Ž…€†‡‚…ˆƒ€€’¤¨Ÿ•‘ŽŒŽˆƒ•’‹‚z{z‚—©³³¢Œ‚‚ƒpYPUNBGMKTk©ÈÛßÒÅÍâóþÿýûòÖ­ŠiD 5I]z¨Ôðþÿþÿþþÿþÿþþÿ軟‡iF,*./,%#"(;K]wŒ•ššœ¡¢„ƒ†‰‹‡wngfgo‚Œ†„‡™Ÿ¡¥´ÂÈÈÁ¸ªž¡£ ¦­®«¦£¢Ÿ ›Šƒ‰•“ˆpcbddfjha_[URME>BQ]imibXRXgy„Žœ£¨«ª­µ´©­¼ÄÌÐÍÉý½ÂÆÊʼ¿¾¶®ªž‘–”“ƒtfdgjh]WY\[VQQM>03ALSUSG?K_q~}}ˆ•¡¤¤«¯«­·ÀÈÎÎǺ²·½ÃÇÄÈÓÝÜι§”‹–£§£–‡s`^dlmfcflhYPMKLOWdmniaZ_n{€}}‰––‘”‡Š˜¤¤¡’–¨°°­ª«±¶±¨Ÿ”Œ“›¢›qv€ƒ†‡‹‘™¡œŽ†tr}‹••‰|pgfkrx|€ƒ†Šwwqns~“žœ‘‚|~‰•—•–šž¤¥—Š‚z{‚˜˜–ŽˆŽš¡¢ ¡ ¡ª§—Œ‚yvsv~vmdcgilt|‚‰’–‡„¡®®¤’ƒ~ƒˆ’šœ‘„€€‚‹š¬··¬œ’•–“”™¡¤¥ }yumeait|€{xww{~‚‰’šš“‹Š‡~ysr{ƒˆ„~}{~Œ›¤¢œ˜—˜•Ž“¦¯±§”„€€ƒ‹š£ “ƒzw{‡“ž¡’„~„Š’š™…{wumddn{Ž˜Œ~zxrot~ž£¢œ’Šˆ†ƒ…Œ–¡£›’‰„ˆ“ ¡ •…~ƒ‡Œ‹yyyx{‚‹“˜”‰€‰’™™–‹zwzyz~ˆ“˜‘‚ztruy€Œ™ ¡™‹ˆ†ˆ”«¶²žŒ‚ywyx{…ކ€|wrt{€Š¤š†xpy‡ŽŽ“”Œ„‚€€ƒˆšš‘‘Ž˜œ–‘‘Іƒ|x{‚‰‘Ž…xqx‡Ž’’‰‚‡‘¨³¶¬˜…{y|€†‡|vqpx‰–¡©©ª›ƒ~|~ˆ‡†—–ކ€zyˆ’“‘‡|z}…Œ‰ˆŒ™œ •ˆ‹Œ‹‡‚ƒ„€~‚…„†Œ‹‡…zw‚‰šŸœ™•Š‚€ƒ‰ŠxmenŽš£¤œ”…ƒ„‡•”މ~zo}Ž‘”•‘Šˆˆ‚~‚†‰‘£¢ ™•š›–—–„…ˆ€wvwy|„‡…€|}ƒ‰Ž“’„€ƒ}}„‚ƒ€xv|€ƒ™›•Žš¡žŸ¤«´¶­ƒxs}Œ“™”…zw|}}€‚‚†–Ÿ›——“‹„ƒ‰‹‚|vrsy}|uv{†“’މƒ‡Š‡ˆ‰‹“¡›”‰œ¥§©§˜‡|zš™’›¡›Ž}rnq|ˆŒ‡xomr}‡ŽŠƒ‰…‚€xv|„“‡‚€~x€‘š œ”˜žš…~}ƒ‘¢««£œ™ˆŽŠ‹‚yƒŠŠ‹‡‰”œš•““Œ†ŽŒ†€‚‹‹ƒzjYYn‚‡†ƒ|vnip‹–›–™¥£ž™‘–ª¶­›ˆ~zŒ•œ—‘•œ™’†xquŒœ˜–‹‘‹…ƒ‚€‰‹p_[hzƒ‚‚ywy~†‡‡’——˜Œ}z|‹ ¤œ•Ž‘“‘–ž§ª¥—„x–¡¢˜„~}|€~„‹‘˜žŸšŽ{mhn‘†{uyyuz}Œšœ”‹€uv{†™¡š—£¤Ÿ–Œ‰Œ•¡¥Ÿ–Švfagy‹‹ˆŽ›”ˆ„‡•¥«¦¢›‹~†“™Š}yojd_gvƒŽŠ‰…{}Š™¡›Œ˜˜‘ŒˆŽœ©­§¡˜Œohs‚‡ƒ|~~~~~‡­¬§¢—Œ~mn€—˜’“’‹…{z•Šˆ}sj[e}‹’‰†‰Œˆ‚€Š˜—’•“Š…‰š¦¢œš–‘’Ž€x{Š•‘Ž‹ƒ~€ œŽƒ€‚‚}w~‹•—Žˆ‚}snv}ƒ…|}€„xx€Žž©ª —‘‹„ƒ‹™ž˜“Ž‘‰ƒ‚Œ—𗑉ƒ‚‚†ŒŽ‹†…„ˆ†{uz„Œ‚~„‡…‚†‡ƒ„‚‚‰†|vrqzŠ“‘‹ˆ“•˜œ™”’”‘“˜Ž†‡ˆ˜¬­ž’‘•”Žˆ…|oijpuyzvru|‰•“Šˆ™š™•Š€|‡Š”‘Š€y‚‘•ƒ€„ŠŽ‹„|}Š™¡¢£ ••—’Ž…„’—•Œ„zx„‡„€{qjq€ƒ€~‡–ž¡š’……˜–’‡y‰‹Œ—¢ªªŸ‹yru}~|~xsz‰”“”›š˜ž•Švgkx…‘𠢤¤œ’Œ€‰‹ˆmfnx€‡Œ…€}{~}{‚†™›™‰Š–Ÿ§¥™‹slor|‰Žš¬»Àµ¤—’‘’“Œ€ztjhilx€€„‡„{rljny‰‘ŒŠŒ’›¦ª®·¼·®ž‹‚}{‚’’”†€‚‰Ž‘”‰‡}oic_l|‚ƒ‚}tnlpx~ƒ‰‘šžŸž˜–“Œ‘œ˜–—‘†‚†‘˜–šœ›–‹Ž–ž•Œ„vnlmv…‰‡„…‚{tljms{„…„ƒ„”Ÿ®³²­«¨šŒ†€~„Œ”˜…|tonv~‡Ž‹‘‚~ƒˆ‘˜”’“ˆ‡“••“Œˆ‰†€ƒ…†‹‘Š„vmnsx~Вމƒ€„•”’’‘Œ……š©´«¡¡’‡ƒ‡‰~{tnmv‚Š•”“™œ”‰‚~}{xw~†‡|€„…‡†‚~|zxz€Œ——–¡¢ •ŽŽ”‰Œ——ˆ„†‹‰ƒ„ˆ‘ކ€€„‹‡€‚y{~„Žˆ‰ˆ†ƒ~‚˜¡££«¯¥œœžœ‘‚zz{~~zxzƒ‚‚€~…€ƒˆ‘–—›Ÿœ•Љ‰‹Š‹Ž„yvw{{}…”’‘‘’–œ™Œ„€|xtv|†Œ‘™”Œ‹‰†ƒ~|ˆˆŒ˜˜™›œ ›“Œ‰‡„‚†‰‡ˆŠ…€€€€€†‹Š‡„ƒ‚~~~|~…†Š˜Ÿ›’Ї…ƒ€‚†ˆ‹“— ¨ª«¨›‘‹}pqux‡†‹‘‘‹Œ‰†ˆ‹ŽŽ‘’‰€„„…ˆˆ…ƒ~€|zyqpupo{†‘¡¤ª¦œ’ŽŽˆˆ‹—–›¤¡ž¢œ’Š‚€}vx}…‹“œ›—–“Š|qpuz†‹Š…~yxv~‹“œ •†}vtxƒ€~€†Œ›§«ª¦™‹ˆ|uy…‘“– £Ÿ—Œ‚{utx|xw€‡‰ˆ‡Œ’–•‘‘މ‰–ž¡Ÿœ–‹‚‚ƒ~{}€~}|vonoqu}‹—›œ§®¥–Ž–›“„€~{Š‘™¦µ½¶¢ˆƒtjlqz„ˆ‡ƒ|}‡Š‡†Š†{y†‚{~ƒ…€Žœ”ŽŽ…xv|prz‚¢ ™“•–ŒŒ–¢œ‹”Ÿ˜‹—˜“ŒoacmxƒŠ˜¢œ’‘‚|z{‚‰’’vy}€~|Œœ™š–ƒ~}~„ˆŒ}v~…—¨©¦ª©œ‘‹xvssx‰”“Ž—£¦š‘Œ‡‰…€|xz€…•‡vqy‡ŒŠ‹‘˜™”…vsz}ƒŠ’ ¡Œtkv}zˆŠ•šž–””‘•™ž•„xx†“˜™™žž•ƒtqmfgn|ŠŠ‚ƒƒ†—–•˜œ¡|wy…Œ†yuz…‘šŸ›–””•‰xwusz~‹¡§ ”†€„Š‹‘•˜„~z€Žš§®¥–†qixŠ–š˜•“’‹{sjp{ˆ‹‡}}‚…Œ”•”˜¨®¤–„wuy€‡†€zqr{…—¦¨¦¦¨ž‹€vnsƒ”¡¤›‡|y}…”𓋇ˆ„|rhn~Œ—›—‰€vw‚“¡¤““”ˆ}o_f{Šš£¢ ›Œ{sw„“›š–›¥¢—ˆ{}‹˜š‘І€vlp}Žž¥¡›Ÿ¡•‡{rouŠ–”†tfdn‘’–“ˆyoq{ Ÿ˜™•‡wq|˜¸Ã·¨œ‘‡|k`dq~‹— ”vw~™“’–˜‡|z~ˆ‘”–š”kbhw’£™’“‰tpv~‡™¢¡¢™…rkp”—Œ›¢¡˜Ž‹‘‹Š…sgp™±­ž›ž˜…sjhmv‹‡xilzžŸ–’”•ƒ€~~‚†‡ˆˆ‹‰‰•¤¨¢Ÿ¡£šˆ{vtxƒ’Ÿ§§ “|ghv€‚Œ•‘‡ƒ‚„‘ˆ‚ysv„–¡•އ~~€€‡Œ“Žˆ€xyƒ–—––Ÿ¨¡“ˆƒ„…‚~|z{‚ž¤ ™–’‹‚wnqz€„Š””މ‚~€ƒ‚„Œ–ž”‰ŒŒŒŒ‡„‰†~|z|zvw{ƒŒ’‘”šœž ¢£œ—–—Ÿª¦™Œxrh\ST]ciu~ƒˆŒŽ‘˜œ™˜šœ£«¦˜•š“Š†„…ƒ‚~~‰‡€|wv{~zy‹•Ÿ£¢Ÿ›•Œƒ~‡Œƒ‚ƒ‚ƒ~„‰Ž…~~€‹Ÿ©¡“‰…ƒƒ€}‹”™œ›—–”’ƒ„•“‹†‹‹„|yz||~~}~„„‰•¤ŸŠƒ‚yv~ˆ—˜“Ž‹ˆ€yz‚Ž“Œƒ{w{€†”•”‹’“’•Ÿ˜Žƒ€€‚ˆ’—š™ˆƒ~vnr€‰Ž„~~~‚‹Œˆ‡„€…‹Ž˜Ÿ¡šˆ…ˆ‰‚ˆ‘“’‘Œƒ{yš¡ž„ƒ‡†ˆ˜œ–‰„‡ŽŠ‘—”ƒqeiu|‚Œ’އˆ‰‰‘˜ œŠ‰Š†ƒ€…Œ„†‡‚‹“šŽ|xˆŒ‘“–”‹~€€‚†‹”–‰}~†ŒŒŠ†…ˆ‹Ž‹ŠŒŽ‹‡ˆŠ‹‚{y‚Œ‘“˜›”‘”—’‡~~€€„‡Ž—‘ƒ|€Š‹‰……ŠŒŒ‹ŠŒŠ‡ˆŠŽ‡~yz‡‘‘“š™ˆ€ƒ‹’—šœ•‘’Œƒ…‹†„„€}zzyx‹˜Ÿ¢ ™“‰€~‚ˆŒŒŠ†…†}€‚†’އ†~…Š‹ŽŽŽŠ…„…‰”“‘‰€{vuy„…†‡ˆ‹‡…‹ŠŽœ–™”‹‡ƒƒˆŒ„€€€ƒ‡Ž—œ ¢œ“†…“‘ƒ‡Œ‡„|vxvzŠ“–™–‰}qu„“™“Ї‚†Š–Ÿž›–Ž…|tou‚‹‡€„ˆ‹Š‹Š••˜žžœ˜Šwrx†‚ƒ†ƒƒ€{xz†‘˜žœ–‡zt|Š•˜‘Іz{|zƒ•œ›™“‘Š}z‡š š“‹‹‰ƒˆ•™›œ•ŠƒymlvƒŠŒŒ…€~{„”ž¦¨¡œ”†vmr|‚‡Š‡{}y{†”¡§£˜–”ƒz}ƒŒ‘“•„~yz„‹“œš’އ{uz‚‹™£¢™‹€}{…Ž”ž ”…zspw~†“Ž„~}ƒˆ–œ§­©¡’€vvxy‚‹‘Š~xvx~‡œ¦§ •‡{z‚ˆ“š–„{x|„Š•™•‡y|ƒ„Š•™˜–“Œˆˆ‰‡ƒŠ’‹uqv€‚•‹‚~„Ž›¤¨ªœ‡|z}€…‹‘…|}€‡˜š˜›—Š‚‚‹‹ŠŠ†€‚€ƒ—–“…}z‡”’’“’•’Œ‡‡ˆ…‡‹Š‰‚||€‚ƒˆŠˆ‰‹‰Ž˜•Œ‹‰‰’”•˜„ƒˆˆ‚ŠŽ‹‰‰ƒ€‹‘“–Œƒ†‰Ž…~€~y|€€†Ž“–™™‹‹ŠŒ‹‹Ž“¦¤šŽ…€~…†Žwz|zz~‚Œ˜™–“Š€„ˆŽ•”šŒ{xvx‰˜˜’Œ‰…€{vy„‘ž¡Ÿžš’‰„‚€‚ŠŽ„{wy}}„“Ÿ£™‹Ž‹„ƒ‹“›Ÿ™’Š~{xx{ƒ”Œ††€‚‰˜‘ˆ†‚€ˆ‘˜¢«§–†}tosw}Š™¤¡’†~~x{†•§¦œŸ —ˆ~€|€Š‹ˆ‚xutvz€‰•žœ–—“‰†ˆ¡™Œƒ|sszЉ‹ˆ„ƒ‚…ŒŽ†~…‰‹•œŸ¥ †~{x{ƒ†’˜—‹‚€€ƒ‹– ¢ž›™“Œ‰ƒ~~€‚wtw||~‚„Œ”š œ•’…~‚›œ–‘ˆ{uvy~†–¢Ÿšƒ{|~ƒŒ•™™•‹Šƒ~‚€€€‚‚‡‘–ŠŠ‡ƒˆ”›Ÿ¢ž”Š€{|}}~‰Œ‰ˆ‰‰Ž™œ’…‚‡Œ‘–”‰wqlpy‰›¢žœ”„{{xv|„‰‘–š›•Œ‰‰ˆŒŒŒŽ‡{usnnsz„Ž•›žœ‚ƒŒš¥¦§¡‘…|trw~†’—–›”zx{‡’”“†„‘£¤˜Žˆwhlu}Ÿ¡Ÿ”‡wvuz†’—•‡~‡‰”ŽŒ‹‚|wps~ˆ•ž£¨¦—x~…’¡¥¤ “‚obagp€Ž–Ÿ•‹t‚“–›š‰‡zw}ƒ“¢¦¦¢”ƒ|stz€ŒŽ„€€|z}‡‘’™£›—˜†ƒ„ŠŽ‡vpvŒ›¢¥£™†xnt‚¢¨¤©ƒwkaiyˆ™ š˜”ˆ}wxƒššŠ}ukpzˆ¢¬©¤”‰‚sho€‡Ž‘„}}{|†” £œ—š‘„€ƒ‚}{€~~Œ˜¡¥¤¥¡‘ƒzvˆˆ’¢£šƒxomuˆ–•’’‹‚xqx†‘˜žŸ•†€Š—¥¯¦–’ŠyruzƒŠ‰Š‹†}|~~„‘—”“–‡ˆ†…ŠŠ‡‚~{z}€…”¤©¦¢ š‹zu|‚„ŠŒ‹…€yw‹“•ˆ|ˆ’™œ™—„€†—¡¤¦¤•ƒwmis}…“‰~€…‹“–š•”Š‘’‡€|xttv}ˆŽ‘—–”šœ•††…ƒ††„…ƒ‚„„†‹ŽŽ‹‡…„„‘“•‹€||…’š™£Ÿ˜Œ~wsr{€ˆ‘ŽŒ†ƒ‰ƒŒ’‘”“’’‘‹…|wtsz‰–“™š“—‘•˜‚~~€ƒŒŠ€€…ƒˆŒ‘•”‰‰…€~zwxŒ¥§¤ª«¡’„ysz€€}}‚„ƒ|x~—’‘‘‰†‡…†“œ–‰†„|uu€–˜˜•“Œ‹‰‹•™‹~€€„ƒ}|ƒ‰ˆƒ~‚ˆ…ˆš©§œ„{zysz’¡¥«§Ÿ›Ž‚|‰‡~{|}|~|yš¢£œ™“Šƒ…”›•‹ƒ}yrkmt}£«¦Ÿ—Œƒ…‘’ˆ‚‡†‡‰‡ƒ„ˆˆ‚€~ƒŠ˜œ›…ƒ~wy|{„–§«©¤š‰ƒ†ŽŠ€|{uw}}ƒ”›–—•Š€ˆ‘˜™”Ž€rmiksx~Œ ­®¬¨œ‰†„††…„‚ˆŠˆƒ‚‹‡†ƒ~€‰ŽŽŽ„~€„…ˆŽ–¡ª¨£—„…{|ƒ„€zz€ƒˆˆŒ”—†‚Ššž–š„zkjuvw‡–š¡©§Ÿ—Œ„}|}}|}~ƒŽ‡„„…›˜Š‰‘–™ƒ„‚‚}z|‚…Œ’š¨±¨–‰ƒ‚xuwy|€……‚‹“’”’Ž•—„‡‘•’‰‚{vtutt|ˆŽ‘—Ÿ¦«¨š•™}{y|…‹ŒŠ‹Œ„€…‰‰‹‰†Ž“Š€~}~€|z€Œ”’–¨¯¯¯ž‘‡|vojp|‚„ƒ€„’’—•“”‘“–Žˆ‰„||{y||{‚Ž“™¢§¨§¡Ÿž€yoeiu|„ˆ††‹‘ŒˆŽ’Ž‹––…ƒ~{~€ƒ‡„ƒˆ’—𡦦¡–‘Žƒwsmdfns}ƒƒ‰’–˜Ÿš“””ˆ‡ƒ~zxzvrw€…› ¤¦˜™†‚}xwvy‚‰‰’‘’—œ™•’‘…€ywusuxyˆŒ˜¦©¨¦ ˜ˆ‚~vonpu|€†”ž£©ª¨¢—Œƒ~€}~†yywrsvz‹—£«±¯¨ž‡‚€‚„‚~€€€‚†Œ”–—𙉄{|‚††ƒ|z}„Žœ§«¬­¬¥™Œƒ€‚{tojlppz‹™¦ª§££›‰€~‡‡}sqtpv†™©³´±°¨•ƒytt~€{|zuxyy„”¢ª«¦¡œ‚|xs{‹Œ‹‚~ƒ{‚’¢¨§¢Ÿ¢žŽzvy€|yx{~€‹ ®®ª§ –‹…z|‚‹Œƒ{shbfmz’£¥¤¥¡ŸšŠ{w{€€€€~{yz~…•«±«¨¤•‰zkjt|ƒ‰†€€~|}ލ³¬«°¬¥š…spx{ƒŠ‚~‚ˆ‘Ÿ«¬¥Ÿ™‘‡€xkkx…Œ‚xuqw~€¢£ §©¥•‚{zy|ƒƒ~yw{~Š™¡ —”›™‹}mdlx‚Œ‹ƒ„œ¦©¨«²°Ÿ…qggouxyuw€„„œ ¥ª¥¡ šŒzmisŠ‹†…‡†Š“•›Ÿ¤©§’znhjw|z|€…•™›Ÿ¡ ¡—~kfiuƒ‡†…„†ˆ‰…„‹’˜¡©±·¤‚mdcltwy}„Š‘’𣍩¨©¤’zgdp|~~€ƒ…ŠŽ‡„‹“𣬳°„vomrwy€‡–™Š˜›› ¢—€dRWjw|…Ž‘‘Š„ˆ•£ª±µ°¢Œsgirutz€€…Їޙœ›œŸ‘€ofksuz„”š™‘Š…‡Œ–¦¯²¯ž†pcfknx„‰Œ‘‘‰†•™Ÿ¤¢špcdow}‚Š”™—’˜Ÿ¨©¤ š‹whfikr|ƒ‰ˆ‡‰ˆ’• ««ž™›„mjmszƒˆ”މƒˆŠŠ“¡£žŸ™†tjggr€ˆ“•Œ“•‘‘“¡«ŸŽ‡sgdclx€ˆ“—ކ›™›£¤•™’ztppw{w€…‚Œ˜Ÿ›•šŸ›ŠŒ‰€sihqŠ‘—”ˆ…ˆŒ˜¥¡š–Œ‚ynlt‡Œ‹ƒŠ—›œŸ£™Šˆ„}{ypiq}„‰’’›¢¤”›¡™’“’‹†oiort}‚€ƒŒ’œ¡Ÿž‡†„†ˆ€us|…ŽŽ”˜˜”’“—“‰†„„„zrv‚†Š‡‚…‹’Ÿ§ª¢”Œ‚{}}xtv†‰‹ˆŒ””˜ž¤¦—…€†‹Œ†}uprty~…‘™œ›¡¦ž“‰ƒ…‡…~ulo}Ž‘ŒŒœ •‹…‚€„‰‹‡„‚†‚~Š•˜ ¬±¥zrrx~|wvwЉ‹™ Ÿ¥¦œˆ…‡‹‰‡†~}|~}v{‰Ž¬­¡‹zvz€€€€ƒˆˆ‰Š˜Ÿ£§£‘ƒ€}{€„ƒ€~ƒ‚x|‰Œ«¯¥’€uquyxy~ƒ”Š——œ¥¦£Ÿ‚€}|‚ƒ€€yx‚‰™§¬¦ž……wv}„ŠŽ‘€…‚ƒ•§¥šŽƒ~zrqz‡‹‡z‡˜©¶¯¡‘}ykcix€ƒ‡Œ‰„…‡ˆ‹‘›¡ ›•Žˆ€qjvƒŠ““„}€€‹• «§š‹|ndjv…–šŒ~}†‰ž§¨ ƒ~{tt|…“ Ÿy{~†™ŸŸ œŒwjacju…”œ—‹„‡Š‰ˆ“Ÿ¥¨¦Ÿ“ƒvnlq{‰—šŽƒ}{~€‡–œŸ¥Ÿ~qimu}‰™¢‘‡‚†Œ”œž™–„{tu{|}…‘„~†‘›¡ £•‚wmlru{‡•œ–Šƒƒ„„‰‘™Ÿ ”ƒztrru|‚Œ”‘‹‰‡ˆ‹‘˜œ¢¨¤’tqpry‰•›‘ˆ…€†‘•™˜Šywy|€„…‡ˆ‰‹Ž•˜šœžŸ—‰zsw{xy{{‡‡ˆŒŒˆ‡‰•¢Ÿ—Œ‚~}zy}€ˆ””‡€€‚ˆ’ ª§˜…vkjqw|ˆ‹Œ’˜ž™ˆ„‚€€}yx€Œ’“’‘‹Š–ž˜‘‡}xtvzyxy~Š’‘’’ŽŒ— ¡œ•‰€€€‚}vvz‚‰‹Œ‹†…Š”ž¡ ›ƒ~}~|‚Š”›–Œ†ƒ‡‘£ž”†}xqpx~}z|~‰“•—šŸ¦¡”„{}€~zop{„–š”Š‰‹’•‘‘„~}{}„Ž••Œ€‰‘–Ÿ˜‰||€‚€€†Œ‰ƒ†Ž—š™“ŒŠ‡~€€|‹’Ž•¡¤¢ —Œ†‚{ronmqtu|‰Œ†‡Ž”Ÿ¥¡Ÿž•ŽŒƒxz~}€ˆ“„€…‹“ŽŠˆ…„{su~„‡‡‰’™”‰…Š“œ”Œˆ„}z{~‚ƒ€„††‘Ÿž˜‰Œƒxty‚ƒzw~……‰—¢¤¦¢–Œ†{upq{}z~€~†˜ŸžŸ™‰{yz€Š‹Š“’‹‡ŠŽ—œ•‡~~yssx}„Š…‡Œ‹‘“£œ•‘‹ˆ†‚zv|€€}|}zvz~€Žœœ›™”‰€~„‰‹Š‡„‚{vx~‡’›Ÿžš’ˆ€ytw}€„ˆ‡ƒ„Ž—Ÿš•xqt~‚„‰Œ‹‡ˆ“œ¡Ÿ–‰ƒƒ}rnqy~~‚ˆ‰ƒ‚‡Ž•œŸŸ–“”Œ~‚‡‡…‡‰†{mlsy€†‹‘’‚{|ƒŒ–ž”ƒ}ƒ‹”š›š’†tntyz|~ƒ‡…~…‘›¡Ÿ›˜“’•Ž}qtury†Ž‡‡‹”‘’“‰zwz|‡”†~‚…ˆŽ‘”z~„‹™¢Ÿ’…~{{‚†‰ˆ‰†|zz{}‚š•Š†ˆ‡‹’‘”š••¡Ÿ€xnefn|‰ˆ„‡„…ˆ‹“›£¬¦’†~plt—„†…‚ƒ€‚…‡Ž’‹~vqms’¡£—ŠŒ‰„ƒ‡’†€|upv†–žšŽ†‡…€}{Œ™ž›”†zsjq…“ˆ…††ƒ€„Ÿª¯­žŠ|qkr†…€~€~Œ™Ÿ¤¡’†}xzƒŒ‘•›œ•‹‚…ˆŠŠ…|rght}‡ŽŽ–ž˜‹ˆŽ–›•‚wrw„‹…„†ƒ~yw}‡Ž˜˜„{{€„ˆˆ†‹„~yz‰š¢£œ’ˆƒ‚|{|tu…’•”“Œ†…†Š’™—Ž…}zzyzz|‡˜¢£•Œ†…ƒƒŒ“‹„~tqtwwtv˜˜–•‘ŒŽ’…€~†Ž‹‡ˆ‹’Ž‚€}vtvz€‰“—˜”‰…{z€ˆ—™š“…|||“¤¡–Š{slnw‚Œ’•–‘†€€ˆ’œ¥£”‡zsnikw„Ž—£¦ž™‡…„‡Œ‹‚{{xuuyˆ“˜›‘‚|yv}‰˜›•„{x|˜™š—ƒ}upu~†‹Œ‹‡{v{…—›š—“‰}{z„”¢ª©Šzodbiry€‰’•—”‹‡ƒ†—œ™Ž†{vwy„Š‚ƒ’—”Š‚…–š”‰~solly„‰˜¤¥‘‚~€…’ˆ~ww|‰’—–•™—Šyuvz‚Žš›’‡€}yv{{{‰›£ž“‰‚ƒ‰Ž•—”Žˆ{|||„‹Œ‡~€Œ™¡¡—Œ‡vuwy|›š—•‘‹…„…~|x}{uƒ}…‘–˜–‘Š…‚„ˆŒ‘‰ƒƒ}wyyy—››˜‰‚~|{~‚†ˆ‹…~‚Š’’‰ƒ~†™œŸž•Œvokqw~ˆ‰‘‹ˆŒŒ†‚‚ƒˆŠˆ‰†€€‚‹’™”މ„ˆ†‹‘‰~ymeks}˜Ÿ¦¤—ˆƒ~}€„ˆ‹‡‚€xtŠ”“ŽŽŠ€}|}†“™˜†{stx{ˆ’——Ž„‚}x}„Š‘‰‚‚‚‚ƒˆ‰ƒƒ€‡‘˜œ–Š€yrlpw~Œ™¢«§—‰~‡‰†‚{snqx„‰Ž”˜—†ƒ‡ˆ‰“œš•~vvuvzƒŒ—ž‘…€|vsx€…ˆŠ†„†„ƒ†‰‰Œ—œ”ˆ€~Œ™š—„}uljpz‚š—‡…„‚ƒ‰’ˆ€{|}|}‚„‰“‘Œ‹”—•“•–ˆ€xqlgiry€’¡Ÿ—‹Š…‚…ˆ„€€{y€‡“—šœ”…€‚ƒ€‚†‰†€€~uos{€‡”Ÿœ’”}‚†‡…†…}x{~…‰‹ˆ‚’ŽŽ“™š™‘…zpovy|‚Š’—“‘—•‹††ƒ„zywqy„†‡‡Š’—“•—††…†…‚}vmip}…‡ž¥¤š’Žy|}|}{yyy|…ŒŠ…‡Ž”•Ž’‘‰…‰Œ‘‘‰€{z}~{wޑދ†ƒ‚€„‡ˆˆ…‚€„‹‰ƒƒ‹‘“”“‘‹ˆzwsoquy|}œ¡  Ÿ˜†ƒ€~yxzxy}…‘œ›•”‘†‚ƒ†ˆ~|wz~‚†‹’˜š˜’Œˆƒ~}~‚z|„ˆ‰‹ŽŠƒ‰Œ‹Š‰†ƒƒ„…{‚‚~‡’”™Ÿž›š’ˆ…„‚|sr{ww{‰ŒŒ”››™•ˆzw}€xv‡†œ™“’“†zvxwtrsz†ˆŒ”—’Ž‘‰Œ–™‹}ury~€ƒ„…†‰‰‡‰‘“•‘ˆ~xy|zx€†„„ŠŠ……„€~€Š™žš—’‹Œ‹‚xy{w†‡††ˆ‰‰Ž„}}{xy€„ˆŽ“’މˆŒ“™•‡|yyvqrtuxz€‹‘‘’‘™ œ•ˆzsvyy|~€„ˆŽ•Ž{’‹ˆŠƒ‚‡…€~„†‚ˆ‰€ƒ†Œ’”‡‚~~|~~ŠŽ‹‚}ƒŒ“—‘Š„ƒ‰ˆ}xxwy„…‰ŽŒŒ˜¢Ÿ–“~vuywppx}~†‹†‰‡‡™˜‘‰€~…„€~‚†„†ŽŠ€€…Šˆ‚{rw|wy||†”—–•‡ƒŠŽŒ‹‡}€‹Š€€}|„‚€ˆ“›˜’Ž…|}„…~{~~…ƒ‚‰•š˜‡~€…‰‚|~€~€€}|‚•˜š™Žyzyz~~‚™”ŒŠ‡„‹’Ž…xw}€€‚’‰…‡‰•—‡{w|~}~…ŽŽƒ{}„…†Ž“‘Šƒ€€„Š‘‘ˆ€ƒ‰‡‚|wy…‹Ž”˜”‰~yx€|{ƒŒ…ƒƒ„‰Ž“”‘’‹€~†„‡‘‰~ƒƒˆ‘••†zstwx|ƒŒ‘‹†ŽŽ‘•”‰€~…Š‹‰‡ˆ‰ƒ{wy~…‹Š‰‹Šƒƒ€~‚ƒ‚ˆ’ˆ‡……ŠŒŠ‹†‚„|{ƒ†‡ˆ…€{z}€‡”˜‘ˆ…‚~~{z}‚…‡ˆ„†ŽŒ‹ŽŽ‰„ƒ}}€‚…‡‰†z|„ŠŽ‘ˆ„€}{|~‚†„ƒ‡…†Š‹‹„…†…„ƒ}‚‰‰ŒŠ‰‰…ƒ‚ƒƒ†Œ‡~ztow~†‰„„…ƒ‡ŒŽŒ‘Œ…€‚ƒ……„„€}~€ƒ‡Š‰†…†ƒ†Œ…€~|{{~ƒ‰ŽŽ‰…‡‹‹Š†}xy|‚‡ŠŠ‡†…€ƒ†‡†‡ŠŠˆ„{y{~ƒ‡‹ŒŽŠ‰‰ŠŽŒ‡…ƒ~~€†………~ƒ††……‡‰Š‰„…†~€…‰Š“Œ†€€€€}}€ƒ‡ŠŒ‹‰‹‹‡…„ˆŽŠ…€yrw~|}ƒ†‡†‚„ŒŒŒ‰ƒ|}†ˆ†…„‚„ˆ†Š“Žƒ€€€„†‡…ƒƒ~y{€…‹Šˆ‘‹†„„†…€€‚‰‡ƒƒ„‡ˆ‡ˆŒŒˆ…††„„€~}zxz…ˆŠŽ““ŒŠ†‚€€ƒ†…ƒ…‚€‚…††ƒ‚‡†€~~~†‰Š†~}‚ˆ‰Š‘–—“‹‰ˆ}}}~€…ˆ†‚}}…‹‹‰‡††‚‡‰…‚‚ƒ€~…†|z~„†„‡ŠŒŽŽŽ‰|z{ƒŠ‹†~€…„…ˆ‡‡ˆ‰‰…€€‚‚‚ŠŽ‡€}|€„‚‰‹Š†{v{€…Š…€€„‹ˆ†‰ŠˆŠ‰†€‚‚|y}€‚‚†‹Š‹’‘‹ˆ„~‚„†‰‰……ŠŠ…€€‚ƒ†‰‡ƒ‚}‚ƒ…‚~€‚†Œ’‘‰ƒ~|ƒƒ„‡ƒ‡‡€‡‹ŒŠ†€€~{~ƒƒ€ƒ‡‡‡Œ‘”“‘…~‚~…‰Š†z|€„Љ‚€‚ƒ‚ƒ„ƒ†Š‰……„†ŠŒŒ‰~{|}€€~€ƒ„…„‚ƒ‚€~‡Œ‘”‡„…ƒ‚}~€‚‚€€€†Š––Š~~…І‡‰„€~|}‚‰•”Œ„‚}{}~‚…„‚ƒƒ…‹‹ƒ€~~‚‡Š‰ŒŽŠ„€~~‚‹‘‘†‚‚zx{}~‚……„ƒ‚ˆ”’Œ†„…ƒ~}ƒ†‡ˆ‡‰‡€{wvz‚Œ‘Š…~{x{€„‰Š‡‚„†Œ“’Š„ƒ‚€}{}ƒƒ…ˆŠ‰…~{{~ƒ’‰Š…€|wy€ƒ‰‘‹ƒ€…Œ“’‰ƒ‚}{{}‚„‚ƒ‡…‚}|}‚ˆŽŠ†ŠŠ…€€†Ž‰‚||‚‡‰Š†‚ƒ}{|…†‡‹„~~}‹ŽŒ‡„…ƒ~zz{{~ƒˆŽ‡‚‚€†Š‰ˆ‡†ˆ†|~€†ŒŒ„~}€‡‹Š‰…„…ƒ}z{|}ˆŽŽˆ€‚‡ˆ†‡ˆŠŒ‰‚€€‡Š|yx}‚ƒ…‡‰‰…~vtwz€Š‘’‘Œ„€…‹‡‡‰‰†}|zy|ƒˆ‰‡…}~€‚ƒ„ŠŽŠ…~yz}„”“‘ˆ€~}‚‚ƒ†Š‹†‚~{}‚‡Œ‡|z}€‚‡Š‡†„}y{ˆ“Šƒ}|ƒ€‚‡ŠŽ†~xty‡ŒŠ…|{€†…ˆŒ‹‰ƒ|xw{‚‡‰‹ˆ„€~}~€€ƒ†ˆ‹‹†}}ƒˆŒ”–ˆ„|zz}€‚ƒƒ}y}„ŠŽ‘‘Œ†ƒ€‚„„†ˆˆ‡…‚ƒ‚~€……‡Š‡‚{xx{‚†‡ˆŠ‰†‚€~€„…†‡‡†~{x†‰Ž‹Š‹ˆ~‚†ˆˆ‡†ƒ~yx|€‚ƒ‚€€€}ƒƒ„ŽŽ‘Ї„ƒ…ˆ‡†„€~~}~‚…ˆ†‡‰…{z|‡†„……ƒ…†‡ŠŠ‡ˆ‡ƒƒ„{xxz„„„…‡ˆ‰‡„†……Ї‚††~{y|„ƒƒ‚ƒ„ƒ„„……„……‡‹ŒŽŠƒ€~~~}~‚ƒ€„†Š‰…ƒ€†…€€ƒƒ††ƒ†„‚„ƒ„ƒ€‚‚ƒ‚€…ŠŒ‘Œ‹ˆ†„~}{{~~|}|{€‰‹ˆ‰‡ƒ…„ƒƒƒƒ…ˆŠŒŠˆ‡ƒ€‚€~„…€„‡ƒ€ƒƒ‡‰†ƒ€‚…ˆˆ‡‡†…†ƒ€~{}ƒ†ˆŒŠ‡ˆ†…†„~~||{wy~‚‰ŽŒŠˆ‰Š†‡ˆ‚‚‚„‚~}„†ƒ‚‚‚„ƒ€€‚……‡‰„‚‚‡Œ„ƒ~~~€ƒƒ‚ƒ„…‚ƒ‚…ˆŒ‹…ƒ†„„‡†ƒ…ƒ„ƒxty~ƒ‡…†ŠŠˆ†‡‡…‚‚ƒ„‚‚ƒ{}…‡…„†‰‡†‡…}~€‚‚~}‚‰Š‰ˆ††ƒ€}{|€ƒ…ˆŠ‰…‚‡‹ŒŒ‰†ƒ€€~~€ƒ„ƒƒƒ|yz~€€„„†ˆ†ˆˆƒ„ˆ‹Ž‹ƒ€€|yy{€…ˆˆ†€}€„‡ŠŠˆ‚|}„†‡ŠŠ‰…ƒ„†…ƒ€€‚ƒ€€ƒ†„…„‚…‡†…‚‚‚€„ƒ€{y{~…‡‰Ž‰†ƒƒƒ€€„†‡†„‚€~}}‚‡†…‚ƒ~€„‰Œ‹†€~€‡‹ˆ…€~||~‚‡ˆ†……†Š‹ˆ„‚„ƒ€‚„††‚€‚‚€~‚„~„„„…‡†ƒ€~‡‹ŒŒŠ…‚€|{~€‚‚€~€‚…ŠŠ„€}z|~~}„………ƒ„‡…€‚†‡†ˆ‰ˆˆˆƒ~~~€…‡††‡ƒ~}~~}€€€€‚…‰ŽŒŠ†€‚€‚†ˆŠˆ‚€}xy|‚‡ˆ‡‡~ƒˆˆ‡†……„€ƒ„…††ƒ€|}‚ƒƒ€„…„…„|xz€„‰Œ‹‡ƒ€~}€†„ƒƒ€~~{|„‹‘–“‹ƒ}{~„‰‹ˆ„}{yx|€†ŒŠ‡€~‚ƒ‚€€€ƒ‚€€€…‰‰‰…~€ƒ…‰ŒŒ‹‰†‚}{}‚ˆ‹Œˆ|yz{|~€€||}z{€†Ž”“Œ„€~‚„„ˆ‹ŠŠ‡‚~{utx~…ޑЂ~~€‚„ƒ€~}|~ƒ‡‹Š„€€€€€‚ƒ„……„„~ƒˆ‰ƒ}ywxy{~€ƒ„„ƒ€€…‰Ž’ˆ{z}€‚……ƒ€}{{{~€‚†‰ˆ‚~~ƒƒƒ„†ˆ†~{{~†‹Š…‚‚€€ƒ„……ƒ‚‚€ƒˆŒŽ‡}||{zyy|€‚€ƒ……ˆ‰‹‹…ƒƒ}}|}€„…„‚€ƒ…†ˆ‰†‚~||{z}€„‹Š‡‚~~€‚ƒƒ€‚„€€…ˆ‰Š‡ƒ‚„ƒ„†„‚‚}~}z{zz|ƒ††ƒ‚‚ƒƒ†ˆŠ‹‹‰Š‰†}zwy~‚„€€…„…ˆ‡‡‡…~}zyy{†ŒŽ‹…‚‚ƒ„ƒ~{{||€†‹Œˆ†‡‡„‚€}zz|zxy{|ˆ‹‹ˆ„‚‚ƒ‚‚„ˆ‰‰‰ƒ~}{z|€„…„‚‚ƒƒ‚ƒ…†„‚ƒ{z{|€†‹‹ˆ„€€‚ƒ„††…„€||}|~„‰‹ŠˆˆŠ‰‡…‚€|z|{wtwy|†‰‹ŒŠ†…„‚€€…‡†„~{||}„…‡†ƒƒƒ‚€€€‚}|~€„ˆŠ‰‡ƒ€~{{}€ƒ‡ˆ…€~~‚…ˆ‰ˆ†……„„ƒƒƒ€€|wvx{~‚…‡ˆ‡‡†„ƒ„ƒƒ‚‚†ˆ…‚|z{}‚„…‡ˆ‡„‚‚€€€|{|}€†ˆ‰‹‰…‚~||~€ƒ…‚€~€„ˆ‰ˆˆ‡……ƒ‚‚€€~|{yz{}€ƒ„…‡†ƒ€ƒƒ„‡‰ˆ†ƒ~~€€„ƒƒƒ„ƒƒ„ƒ‚ƒ~~}~€ƒ……‡ˆ„€€€€€~~„‡ˆ‰‡†ƒ‚„„ƒ„~{xy{{|€„ƒ…†…„‚€‚ƒ„ƒ‚ƒ„‚‚ƒ€€‚‚€€‚‚ƒƒ‚€€‚€€‚ƒƒ…„‚€~~€ƒ‚‚ƒ€€‚‚€„…„ƒƒ…†ˆ‡„|{|{|~€€‚ƒƒƒ‚ƒ‡†ƒƒ‚€‚‚‚€€€‚‚ƒ„ƒ€~~ƒ‚‚ƒƒ‚€‚ƒ~‚€€€€‚ƒ„……„‚€€‚‚„††…††…‚~|}|}€~}}~„ƒ‚ƒ…††…‚€€‚„ƒ‚€}~~€ƒ‚‚ƒ„„ƒ~}~€‚ƒ‚ƒ‚€‚€‚€~~ƒ†‡…„‚€‚„……„„…ƒ}{z|ƒ„€~|}‚…†……†…„ƒ€€ƒ…††ƒ€~}}‚‚ƒƒ‚‚€~}~ƒ…„‚€€€‚ƒƒ„‚€~}~ƒ…‡‡‚€€ƒ„ƒ……ƒ‚~|||~€‚ƒ~}}~€ƒ……„…„ƒ‚}~€„‡ˆ†‚||}€‚„„‚‚€€€ƒ„ƒƒƒ€€€ƒ‚€€~€‚…††„€‚‚ƒ…†…ƒ||}‚}|~‚ƒ…†……„€~€‚ƒƒ„†ƒ€~~€€‚‚€~~€ƒ…„‚€€€€‚ƒ‚€}}~„…‡ˆ†„‚€€€‚„„€~|~~€€€‚‚ƒ„†…‚~€‚‚‚ƒ„‚€~~~€ƒ‚€~~€„……„~€€‚ƒ‚€~|{~€ƒ†‡‰ˆ„€€‚ƒƒ€~}}~~ƒ„‚€€€‚„„ƒ‚€€€‚„„…ƒ~}~€€‚€€‚‚‚ƒ„ƒ€‚‚€}{|}ƒƒ„†‡†„€€€€€~}~~€‚„ƒ€~€‚ƒ„„ƒƒ~}~‚„…†…ƒ€}{|€€€€€‚ƒ„„‚‚‚~€€€€~}~€ƒ„……††„€€€€€~}~€€€‚€ƒƒƒ‚‚}~€‚„ƒ„…ƒ€~{{}€‚€~~€‚ƒ„ƒ‚ƒ‚€~~€€~~~€‚„„„ƒ„……ƒ~~~~€€€~€€€ƒ€~~~€‚ƒƒ„ƒ‚€~„…„ƒ‚€}{|}€€€€€‚‚ƒ‚‚‚€~€€€€~€‚ƒ„…„„ƒ€~~€€€€~€€‚€€€‚ƒƒ~€‚ƒƒƒ|{|}€‚‚‚‚‚ƒƒ‚€~~~~~‚‚€€‚‚ƒƒ‚€~~€‚‚€~}|}~€‚€~€‚ƒƒ~€‚ƒƒ‚€€~}~}~€‚ƒ‚‚ƒ‚‚€~~}~€‚‚€‚ƒ‚‚€~}~~€‚€~~€€€€~‚ƒƒƒ‚€~~€€~~}~€€€€€‚€€~~€€€€€‚‚€~~€€€€€€€€€~~€€‚‚€€€€€€~~~€€€€€€€€€€€€~~€€€€€€€€€€€€€€€€€€€€€‚€€€€~~€€€€€€€€€€€~€‚‚€€€€€~~~€€€€~€€€€€€€€‚€~€€€~€€‚€€~€€€€~~€€€€€€€€€€~}~€€€~~€€€~€‚€€€€€€€~~~€€€€‚€€~€€€€~~€€€€€€~€€€€~€€€€€€~€€€~€€€€€€€~€€~~~€€€€€€€€€€~~€€€€€€€€€€€€€€€€€€€€€€€€€€€~~~€€€€€€€€€~~€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~~€€€€€€€€€€€€€€€€€€€€€€€€€€€€~€€€€€€€€€€€€€~~€€€€€€€€€€€€€€€€€€€€~~~€€€€€~~~twinkle-1.4.2/data/ringtone.wav0000644000175000001440000012717510503576710013406 00000000000000RIFFu®WAVEfmt "V"VdataQ®€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚ƒ„…†‡‡ˆ‰‰ŠŠ‹‹‹‹ŒŒŒŒ‹‹‹‹ŠŠ‰‰ˆ‡‡†…„ƒƒ‚€~}|{{zyxwwvvuutttssssssstttuuvwwxyyz{|}~€€‚ƒ„…††‡ˆˆ‰ŠŠ‹‹‹‹ŒŒŒŒ‹‹‹‹ŠŠ‰‰ˆˆ‡†……„ƒ‚€~~}|{zyxxwvvuutttssssssstttuuvvwxxyz{|}}~€‚ƒ„……†‡ˆˆ‰‰ŠŠ‹‹‹ŒŒŒŒŒ‹‹‹‹ŠŠ‰‰ˆ‡††…„ƒ‚€~}|{zyyxwwvuutttssssssstttuuvvwwxyz{{|}~€‚ƒ„„…†‡‡ˆ‰‰ŠŠ‹‹‹ŒŒŒŒŒŒ‹‹‹ŠŠ‰‰ˆˆ‡†…„„ƒ‚€~~||{zyxxwvvuutttsssssstttuuuvwwxyzz{|}~€‚ƒ„…††‡ˆ‰‰ŠŠ‹‹‹‹ŒŒŒŒ‹‹‹‹ŠŠ‰‰ˆˆ‡†……„ƒ‚€~~}|{zyxxwvvuutttssssssstttuuvvwxxyz{|}}~€‚ƒ„…††‡ˆˆ‰ŠŠ‹‹‹‹ŒŒŒŒŒŒ‹‹‹ŠŠ‰‰ˆ‡‡†…„ƒƒ‚€~}|{{zyxwwvvuutttsssssttttuuvvwxxyz{||}~€‚ƒ„„…†‡‡ˆ‰‰ŠŠ‹‹‹‹ŒŒŒŒ‹‹‹‹ŠŠ‰‰ˆ‡‡†…„ƒ‚‚€~}|{zzyxwwvuutttsssssssstttuuvvwxyyz{|}~€‚ƒ„…†‡‡ˆ‰‰ŠŠ‹‹‹ŒŒŒŒŒŒŒ‹‹‹ŠŠ‰‰ˆ‡‡†…„ƒ‚€~}|{zzyxwwvuutttssssssstttuuvwwxyyz{|}~€‚ƒƒ„…†‡ˆˆ‰ŠŠ‹‹‹ŒŒŒŒŒŒŒŒ‹‹‹ŠŠ‰‰ˆ‡‡†…„ƒ‚‚€~}|{zyxxwvuuttsssrrrrrrsssttuuvwwxyz{|}~€‚ƒ„…††‡ˆ‰‰ŠŠ‹‹ŒŒŒŒŒŒŒ‹‹ŠŠ‰ˆˆ‡†…„ƒ‚€~|{zzyxwvuutsssrrrrrrrrrssttuuvwxyz{|}~€‚ƒ„…†‡‡ˆ‰ŠŠ‹ŒŒŽŽŽŽŽŽŽŽŒŒ‹ŠŠ‰ˆ‡†…„ƒ‚€~}|{zyxwvuttsrqqpppqqrrstvwxy{|}€ƒ„…†‡ˆ‰‰ŠŠ‹‹‹‹ŠŠ‰‰ˆ‡†…„ƒ‚€~|{zzyxxwwwwwxxyz{|}~€‚ƒ„…†‡ˆˆ‰ŠŠ‹‹‹ŠŠ‰ˆ‡†…„ƒ€~}{zyxwvutsrrqqpppqqrstuwxyz|}~‚„…‡ˆ‰‹ŒŽ‘‘‘‘ދЉˆ†…„‚€}{zxwutsrrrrrrstuvwyz{|}~€‚ƒ„…†‡ˆˆˆˆˆ‡‡†…„ƒ‚€~}}||{zyyxwvvuuttuuvwwxyz{||}~€‚ƒ„…†ˆ‰ŠŒŽŽŒ‹‰ˆ‡†…„ƒ‚€}{yxvutsrqqqrrstvwy{||}~~€‚„…‡ˆ‰ŠŠŠŠŠ‰‰ˆˆ‡†…„ƒ‚‚€€}{ywutsrrrsttutttuvwxxyz|~‚„‡Š‹ŠŠŠ‹‹Šˆ‡†…„‚}{zzywutstvwxy{|~~}{{{|}~€ƒ…†‡‡†††‡‡††…„ƒ‚€€‚ƒƒƒ‚|xtqpppppopqrrqppqtwxwvwy|‚…‰Ž”—–”‘‘’’‘ŒŒŽ‘’‘‰‡‡ˆ‡„€}|||yuqprvz{{zz{{zvsqruxzz{|~€€€€‚„……„‚€€‚…ˆŠ‹‰‡…ƒ€}xutvxxwtrsuwvtrsvz|zustyƒ„…‡“—–‘‹ˆŠŽ‹ˆ‰‘Œ†‚ƒ‡Š‰„}yyzyvqnpu{|xwxxwsporvz{zyz|‚‚ƒ…‡ˆ‡…ƒ‚‚ƒ„†ˆŒ‰…ƒ~zwvwyyxtqpruwvtrtvxwsonpu{…ˆ‰‰‰Š”—˜–’މ††ˆŠŽŠ†‚~ƒ„‚zwttwz~€}yurrsuy{}}||}€…‹•—–”’ŽŽŽŒ‰†ƒ‚‚ƒ„„‚€|yvttttttsrpooooonmkjijkmpsvy|‚…ˆ‹ŒŒŒŠ‰‡‡‡ˆˆˆ‡…„‚‚‚ƒ„„ƒ€}zxvwy{}}|ywtstuwxxvsqprv|‚ˆŒŽŽŒŒŽ‘”–•“І…†ˆŒŽ‰„€}}~€‚ƒ~zvuvx{~~}ytpmmpsx{}~~~€„‰Ž“––•‘ދЋŒŽŽŽŒ‰†„ƒ„……„ƒ€}zxxyz{{{yxutrqpomkigggiknqsuvxyz|||{ywuuuwy{|||||~€‚…†‡†…„„†‰““‘Ž‹ˆ‡‡ˆ‰‰ˆ…‚€„‰Ž‘’‰…ƒƒ„„„‚zurqsvz}}{xtqpruz}~|zyy{~‚„…ƒzwvx{€…‰Š‹ŠŠ‹Ž‘”–—•‘Œˆ…„…‡ˆ‰‰‡…ƒ‚ƒ„ƒ‚€~{zz{}~~}{xusqonlkihhhjlpsvxyyyyzzyxvtsrrtvxz|}}}}~€‚…‡ˆ‡†††ˆŒ’””’‹ˆ†…†ˆ‰Šˆ‡…„†‰‘““‹†‚~|||}|zwsppruy||{xurqsv{‚~|{|~„„‚|yy{…Š’““‘‘“••’Іƒ‚ƒ„†‡ˆ‡…ƒ€€‚}{{{}~~}zxuronmmmmmmmoruxzzyxwvusrponnnnpruxz{{zz{}€ƒ…‡‡‡††‡‰ŒŽ‘Œˆ„‚ƒ…ˆŒŽŽŽ“•—–”‰„||}~}zvsrsvx{{zxurpqsx|€|xvvx{}~|{z|€…‹‘”•”‘ŽŽ‹ˆ…ƒ‚ƒ…‡‰‹Š‰‡„ƒƒƒ„…„‚€~|||||{ywspmkjklmmnopruwyzzyxvtrpoonnmmmorvy|}}}}}~„‡‰ŠŠ‰ˆˆ‰‹Ž‘Ž‹ˆ††ˆ‹“””“’‘‘’“””‘Œ†zxxy|}}|zwuuwy}}zurqsw{~~{xussvy}€}}ƒ‰”——–’‹Š‰Š‹Š‰†ƒ€€„‡‰‹ŒŠ†‚‚‚ƒ‚}{||{yvtux|‚ƒƒ‚~zuqonmllnqtusqnnoppnllorttrru}…‹Œ‹‘މ„ƒ‡Ž“•’“—˜”މ‰Œ‹†‚„ˆŒ‹‰Š”•‘‰|{|{xutvz}{wqnnopnkhhjlmllmquz|~€€|xutuxz|~…‡‡„€‚……ƒ€ƒ‡‰‰ˆ‰”™›˜“‘‘‡‚‚†‘‹ˆ†ˆˆ…wstx|{vqnqv{|zyz~€zrlkmqssrruy{zuqoprsrqqtx{}}~€…‰ŽŽŽŒ‰…‚€…ˆŠ‹ŒŽŽ‹‡‚€€‚ƒ‚€~‚„…„‚„ˆ‹Š†€}}~}{xw{‚‰Œ‰„€€‚ƒ|xx|‚……†ŒŠŠŽ‹…}yy|}{{}~}wpjgikmmlmptwxyz}‚†ˆˆ†„ƒ€„ˆŠ‹‹‹‹Š‰…€{yyzzxwwy|~}ywwzzustvwvuw}…‹‹‡~‚„ƒ}…‹ŒŒ•š›˜”‘’••’Š„€„††ƒ€€zskfegijjjlnqssstwz||{zzzzyxx{„‡ˆˆˆˆ‡„zwx{€€~€ƒ…„€…‰‰…{{ƒ„‚‚‡Ž‰‚€‚‚€||€‡Ž‘ŽŠˆŠŽ’’Œ‹ŒŒŠ…~yx{€‚€|yvurmgb`adghhhknqssstvxz{{{{|}}~€„‰ŽŽŒŠ†‚…‰‰ˆ††‰‹ŒŠ‡†‡‰Š‰„}~„„‚ƒˆŒŒ‡yvwyzxwx}„ˆ‰†ƒƒ†‹ŽŒ‡ƒ‚ƒ…„|z{~‚‚|yyxvqkfeglprstvxzyxxy|€€~€‚…ˆ’‘Šˆ‡…ƒ}}‚„ƒ‚ƒ†ˆ‡‚}{|€‚€|xwy}}|„‡†€xsrvz|{{~„‹‹ˆ‰‘“‹ˆˆ‹Œ‰„‚„ˆŠ‰…{zyvqjffimpqqqsvwwvuuvxyyyyz|~ƒ†‰Š‰ˆ†„ƒ€|yxy~‚„„„„…‡‡„~‚…†ƒ~|}…‡…ƒƒ†‰‹‡zwy}€}}‚Š’–”ŒŒ’‘ŽŠˆ‹Ž†€~€„…ƒ~yurpke`]_djmmllmoppnmnorsuvx{~ƒ…‡ŠŒŒ‹Šˆ…€„‰Ž‘‘ŽŒŒ‹‹Š‰†„€€„…†„~}}~ƒ„………„„„…ˆŒŽ‹†ƒƒ„………„ƒ‚‚ƒ…‡ˆ†‚}xuuvxxxvussstuwz||{ywwx|„†‡‡†……††††…„~{yy{~ƒƒ‚€}zvsqooopqrqponmnprttttvx{~ƒ…†‡‡†…„……†…ƒ€€‚…‰ŒŒ‹ˆ†…„ƒƒƒ‚{wuvx|€‚~~~€‚†ˆ‹‹‹Š‰‹‘“”‘ˆ„€‚„…††…„ƒ„‡‹ŽŒˆƒ}ywwxyzywtqppqtwyzzxvuvy}‚…‡††…„„„ƒƒƒ‚€~|{{~‚‡ŠŠ‰‡††‡‡‡†„}zwtstvyzywusstvwwwvuuuvwy{|{yurpooppponopsx~„‰ŒŒŒŠ‰‰Š‹ŽŽŠˆ‡‡‰‘“”’Œ‹‹Œ’““‘ŽŒŒ’‘މ„|zz{}€€}{|~„…„€{vrppprsttsqooquy|}|zyxy{~ƒ„„‚|{z{{{{ywvvwz}‚†‰ŠŠŠŠŠ‹‹‹‰‡„|{z{|}|zxvvwxyyyxvvuvvwyzzxvrpoprtttsstwz~„‡ˆˆ†„ƒƒ…ˆ‰‰ˆ…ƒƒ…ˆ‹’”•”’“•–•‘‰†ƒ€~|xtnigfhknprrsstvx|€{wtrsvxz{{||{{|~…‡ˆ‡…ƒ„‡ŠŽ‹‰‡†‡‡†ƒ€~~€ƒ†‡‡†…ƒ}{yxvspnlklmopppooooopqrrrqqrstuutrpnmlmoruwyz{„Š”—™™˜—––—™›œœš—”“”–™š›š—•’’•–•’މ†„ƒƒ‚~zuplkknruvuspooprstsqnlihjmquwwwvvx|€„‡‰ŠŠŠ‰‰ŠŒŽŠ‡„‚‚‚ƒ„„„ƒƒƒ„†‰‹ŒŒŠ‰‡…ƒ€~|zwtqooooonmkjjklmmnnnmmlmoqssrpnnprux{}€‚„‡Œ‘”•”’‘‘’”•––•“‘‘“–šœ™—•••–—–•‘‡‚~}}~~|xsnkklosvxwvtrqrtwy{zwspnnpsvxyyyyz|ƒ†‰‹Š‰‡‡ˆ‰ŒŽŠˆ†……‡ˆŠ‹Šˆ……†ŠŒ‰†ƒ{wtstwyyyyz{zywuuuutqommmmkjjmquvusqqrsrqsx†‹Œ‹ŠŒ’’ŽŽ‘‹ˆ‰Œ“”““”—˜—’‰ˆŠ‹Š‰ˆ‰ŒŽŽŠ…€|yvutsqnmnqstspnlkifdcdgkmoqsvyzyyy{}€~}}€‚„ˆŽ‹‰Š‹Œ‹Š‹Ž“—™˜•”•–—”Šˆ‰‰ˆ…{z|~~|{}{upmnprrrrsuwvtqpqstspnmoprstuw{~€€}{{}€„‡ŠŒ‘“’‘‘““’Œ‹Œ‹ŠŠ‹ŽŠ†„ƒƒ‚€~~‚„„‚€~zvrppqpmjhilprstvz}~{yz}„‡ˆŠ‘”•”“’’““’ŒŠŠ‰ˆ†ƒ‚‚ƒ„ƒ€}zwtplihiklnnnoqrrrrstuusrqqx~ƒ‡‹•šžžœš™˜–’ŽŠˆˆŠŠ‡‚}zyyxusqrtutrqsx€‡Œ‘”˜œžš™™š›š—“‘‘‘Œ‡‚~{yvqligedcaacgkoqrrstttstuxz{|{{|}}|{yxxvtpnmnprtvy…Œ’“”–šœœž¢¥¥£Ÿ›™˜•‘‹ƒ|wsnh`ZWWY[[[]`ejmmmot{ƒ‰Ž“™ ¦ª¬«««¬¬ª¥ž˜’‡{uqnkhc]XTROMLKMQV[`ekrx~‚…ˆ’•————˜™šš™šœžœ—’Šˆ†ƒ€~€‚ƒ‚€€ƒ„„‚€~~~}{wttuxyyxwvvurnjhhjlnoqty~ƒ…‡ŠŽ‘‘‘’“”“’‘‘’““’‹†{uoifeddba`abcefilptwxz}ˆŽ”šŸ¥«¯²±¯¬«ª¨£ž˜“‘ˆztplha[VSRQPMKLQXahmrw}‚†‡ˆˆŒ‘—œžžžž ¡ ™•’Œ‡€{wuutsrrtvxyyxvvvwwxz}ƒ………†……ƒ~|zwsokjknqsux|€„†††‡ŠŽ‘”•–™ž¡£¡™—–”†}vqnke_[Y[^`_\Z[_cfggkqzƒ‰Ž’™¡©®¯­«ª«ª¨£˜•“‘‡}yupjc]XVTRQQSVZ^bglqvy|~„‡Š”™ž¡¡ Ÿ ¡¢ œ˜”’ŽŠ„€‚…†ƒzyyyvqljnswxvtuy}}zyz~€ztqrtwxwwy}‚{xxz~€‚…‰Ž‘’‘‘’‘І‚|wspoooonlie`]\^cgkpv~†ŒŽ‘—ž¢¢¡¢¦«®­©¦¥§©¥œ„|wqh]RLMRUURPSY_a`]]dny„Š“šžž¡¥§¥’‰„…‡‰ˆ††ˆŠŠ‡‚~|}~}zvttvxz|~‚†ŠŒŒ‹‹Šˆ…€{xxz|}~~€‚ƒztqsw|~€…–œ ¡¤©®°¬£–ˆznf`ZSLE?<<@GP[fntwxz|‚ˆ“”‘ˆƒ€}||}}}{yy|ƒŒ–Ÿ¦ª«©§£ ›–‡|qe[TOOQTY^bfjou{‚ˆŒ‘‘ŽŒ‰‡„|yxy|„‰—Ÿ¨°¶¹º¹¶²­¥œ’ˆuld^\\_cfikmqv}‚‡‹‹‰†ƒ€}wohcacgnt{€…‰‘–œ £¡œ’†zofa^[XTPMMPV^hrz€„…†‡‹–œž˜‘Š„€~}}|zxvuvy€‰“œ¡£¡žš–’Œ…}si_VOJIJOUZ_cgmt}…Œ‘”–———–•“‘‹…yurqrtw|ˆ‘š£ª°´¶µ³¯ª¥Ÿ™“Œ„~ywx|…‰‹ŒŒ‘•—˜—“Žˆƒ~yvsnh`VMGDFLSY_dinu{‚ˆŒ‡~rg`\\\]]]^`djqyƒŒ•šœ¡¦«¯¯¬¥”…zwsokfcdhr}‡Ž‘‹‡‚~zwsng`XRPRX`gmqsvy}‚‰Ž“––––—™š™•ˆzsnjijmpt{ƒŽ™£«±³´³±­©£—Іƒ‚‚ƒ„†ˆŠ‹ŒŒŒ‘“•–——•‘‹„}wrle[RIC?@CJT^hnqrtw{€‚{sjb]\^djorrppsyŠ’—™™—–™ž¥¬¯­§ž”‹„}yurpmkkmrz‚‰Ž‘“’‹…~xsniecba`^^_ciorttux|‡Ž•šœ–‹‰ˆ…vmeaadjr{„Œ”˜¥«®¬§ š–••–˜™—’ŽŠŠ”––”Œ‹Œ•œ ¡“ˆ€{wtndYQIDBCIS]eijkpuy{zwutrnkhhkmlklnsyyuuv|‡’™ž£¥¥¦¤¡¡¤£’pfcdinprtsqsx‚•–‘‡~zyy|~~|rheeirwqkjhku{~‡’“’‹‡‹Ž‹‡}ohhjlquy„‡Œ”Ÿ­´²­¤Ÿ¢Ÿœ—•˜”Ї‰‰•€ƒŽ—’”’‘•“ŒŽˆ}r`SSSQQOJIMPV^grzwqjcfrz|{qnnghu}‚Šztvu‘–– ¢ššœ•™¥¥•‡wuwsrsqtz{yy{„•“І‘Š…€ut}{tvtlnqd[behw}snqmpƒ‰‹Š€z‚‰ŒŒ‚}zvuutx~|zzx{Š“”–”ŠŠ”—𧬍®²¦ ¥¢Ÿ©ªž™•„y|xtxue\]]ZUQNMNQTRKEHTdmonpw€ŠŽ†}yyytkir‘‘ŽŠ…‚ƒ‡‡€xz…‘–“’˜  ™‘”–—™Ÿ¢œ††‰Š‡ˆ‘šœ•‰ˆ„xj_ZWTTY_cdglnkc_bksvtsuz„––‘’—˜‡ƒ…ˆ‡„ysqx„Œ‰~x~‰Žˆ}wvupkkpt{‡š©ª ••œ œ”’˜žŸŸŸ •Œ†wj`^ac_XRPONPVaku|‚„ƒ‚ƒ„ƒ}wuy~„‰’‘Ž‹†}sqwƒzrs|†‰ˆˆŠŠ†‚€|vv–„‚Œ˜œ™”“‘ŽŠ‡‚xi\XYWNFFQalpmjffiouzˆ—§±´µ¶·µ±¬¦Ÿ˜•–™—Žƒ}{ytpry~zsnmjd]\_a^^eq{~€†’™•‰ƒ‡•–—™™—–š ¡™…ƒ€vfZY_gkjgb`cktxurtz€}xuttvwtpq|˜—‚}{ywx}„‰”œŸš“‘•—‚|€ˆŒŒ‘•’‹ˆŒ“––—š™ƒzxxrhaadea^_bfggea]\cnx||‡’œ¢£¢ž›šš•‹‚Š•˜’ˆ‚€~}{yskdekngZTW_`YU[hw‚‹’“‡‡Ž˜œš§µ»·¯ª¨¤›‡€yrprutpkiiihiovz{zzyyz|~~ƒ‡‡„ƒ‡Œˆ€zwtrty}zvv~ˆ‰‚|}‚‚{rnqx€Š–š‘‹Ž••Œ‚€†Š‡}tmieba^XRR[honhdfimpu}‰•£®²±®­®­©¢›šššœš’Ї…€yuuxukcadfc`bhljhjpux{ƒŠŠ‚{~‰“•‘”šœœš˜“Œ…€|sg_cp}|tnnoonkgfkrxwrorx{xspot~‹’‡~{‚€~ƒŽ˜œœ›œ›—“’”ˆ‚‹’”’’—™“ІˆŠ‡€zzzuportsolmlf`_djlhdcehkosvy‰’—˜–””“‰„‚ƒŠ– ¢›‰‡…}rifeedddda`djjc\^k|†ˆˆ‹ŽŽŽ— §¬³¼¿¹®¦¤¦£™Žˆ…‚~……‚}yvpkhhiiiiknqty~€}xsmjkpssokjiijq~Š‘“•› ¡ŸŸ¢¢›„€€}wsrpi]QMNPPU`ksttw|~zuuvvtrrvwromnvƒ†‰’‘—œ¢ªª š–”œ™Œƒvrmaamsu{xos~„š›––‚zwty‚zsmjpx~†Œ”–’‘–ª¸º²¬¦Ÿ¢¦ š›•‰ƒykirtv|wlmtv|ƒ€|~wh]WU[dc^ZVU[`gov}…‰…ƒ†‹—¤£›˜“Œ‚z{umjcVV^aellju„‰Ž„€}~ysnmqz€€‚††„•ž¢™Š†ƒ‰Œ†€vlib[bpuy}yvŒ™¡ Ÿž’yuuz}vkeaaeimt|„Љ†‰‘š§±­¦¤ ¢£š™œ–މ}t{…†‰‹‰‘•”šŸ›™—‹{pgbde]VSQRTSU]fmsrosx}†‹‡‚‚~yytiilfa_WQX__emowˆ’•›ŸŸŸ•‹Š‰ˆ‰…|vuuy‚…‰‹‹ˆ•¥£•‹ˆ‚€|~}qfaZYfrw€„‹‘– §¨©¤’‚{ww{yrlgbadgozƒ‰‹‡„‰’›¦©¤ •‘“‘“•†€us~‡‰Ž‘’˜–•ž£¡”ƒumfcec[VTQRTTZeouvrqw}‚†…~{ytrsnilkc^[UYfklrvvŒ’™£¥¢¡šŒ„„…ˆ‰vqoot{‚‹’”’‹‹’𣩤–‡€„}ne_Z`msw}ƒ‹”Ÿ£¢ ”‚xutvwrkhfdfjnx‚‰‰‹“›¡¦¢››™“‘’ŽŽ‘Œ‚~zuz†ŠŒ’““œ¡žž¤¤¢ž‘€xslhf_XVTSVWW\chlmkow|~€{wxxrqpjfg`XXWW`jjlsvz†“œ¤¤¡œ‘‡†ˆˆŠˆwuttxz€Œ”•“ˆŒ–œ¡¤ž•‰}z}zohb`jtx~†ˆˆ‹‹Š—™™•ˆ{uqopojikkjjkr~‡‘˜£§¤Ÿž™‘‹ˆ‹…zwtt|„‡Ž—š› Ÿšœ Ÿœ–ˆzvsnjd][\[Z[\`hnoomls{€yvxunliddbYQSV\kvxz€„Ž”— ¨¥Ÿ•†}}„ƒ}wtqrw‰•››—‘‘™¡¥¨©¤ž˜‹€~~~€tieabkpotzyxwrowxkehmsy{z†‰Š‹‹”“†}z~‚ƒ„ƒ}{|zx{|}„‡|{zŒ”—™ž¢£¢¢¡”І‰Œ‰‚zutsokjjjnqtrldacec_\]dlsxxvssuuqlkr|…‰ŒŽ‘“”••“ˆˆ‹Œˆ{|~}ywz‡ŠŒ’’’’”–•“˜˜”’•𛕆‚~xspmjhkpuvsqsvtpkggknrvursx~‚€‚ˆŽ‘’‘ŽŠ†ƒ}uljox|yrnmjfbadhmuŒ’— ¬³°ª©¬®­ª§¦¥Ÿ˜”‘‹…ƒƒ…„}tpomga]\\[[\^`bglomjknqqppuy~…’’Œ‹Š„yppuwvsqqstuz€€„—›••›—ŠŠ”—™˜“‰€zxsja_dikkkotvvwusrty€„ƒ‚…‰‹‘•šŸ ¢¥¥ žš’‡€~{uonprolhb[RLJLLHFMZgosv~‡‹‹Œ’–š §ª§££§¨£›”“—˜•އ~ule^WQMPW]^]]`cfilmpt|ˆ“˜›¡¨««§¡Ÿžš”’‰ysrrojinrtssu{‚…††‰Ž”—˜š ¦¦Ÿ˜•“ˆ~wtsqppnhb_\YSJGMU[`cfkt|…’”œ©³¸¶²°±¯¨ž•މ††‡…|pf`]VLEGLQVY^fnsz„ŒŽ’—Ÿ§§¦¨¬­­¬««¬©£¡•‹ƒ~zsh^XURONRW[_dhijmrz~|{Œ•¢¥¦¦¢›•…~~‚ukillifeglquy|}}€‚„‚~ƒ™žŸžž™”Œˆ„€~yvuvtpida_^`fihikqyƒŠ•¡¥§¨ª««­¯ªŸ—’ŽŠ‚{y{ztkc]XTPMLKNU^hort{‚…ƒ€~…‘™Ÿ ¡¤§¦¦¥Ÿ›œž›–Ž…}sg_XSTY_efb_beefhmsw{‚Œ“–𡍫¥œ–””’Œ‰…|||zwutvvplmsy~}{{~€ƒ‡Ž•›Ÿ¡ ›—•“ˆyy||zwtqmf_YSNPYaeeejsy|…Š•›£ª«¨¨ª§¡˜ŽŠ‰†vngdaZROPRVY[`jrx~‚ƒ‡Œ•¡¡¤ª°´´±°±®§¡›—”‘Ž‹…yle`\WTU]ccbcfikklnoqxƒŽ”••˜š•‹‚}|~€{wvvusposz~„†‡‰‡„~xuvy~~yxy{{{z{}„‹‘’–œ œ…zuwxqkf`ckmnv~…‘š¡©±¯¨¥ ˜•“‡…vng``fhffebejjlqrsvslknt€‡†††…ˆ”¡¢¦¤Ÿ¡¥§®²ª”‰~xqiggbXPIFJSY]cfglrsxƒ‡‹†~{z|ƒ†ƒ~yxxsrwy|~{…‰’ŽŒŠ‡‡‡†‰‹‰†……†••‘ˆ…†ƒ{wxwvsjcfls~……ˆ‰‰Ž“’’•”“‘ˆ€‚„zvtpnprw~„…ƒ‚„ˆŽ“’Ž‹‡~{uturpmd^ahq}‚‚…‰ŠŽ”››—‘‰…ˆŠŒ‰„€zwvw|„‰‡yxzƒzxske_VVZZZXPKPV_kqu}ƒ…ŠŒŒ”“’‘’šž–Œ‡wpnqx€„†‰‘›£¬²°«§ž“Œƒxvwtpkcdp|‡“˜œ¡Ÿš–‘Šˆ„{rh][aflstuyxsqruz}{unlov†ˆ‰’‘’Ž”—‡|ohikq|„‹’™¡ª®© ”†€}wsrpnmhdgoz‡”“Ž‹Šˆ„uole[VRS\dfhiegmorussvsnnnq{~}‚„Œ”–˜™“ˆvqpu}ƒ„…‰”¡ª±µ³±®£—‡€€}vqlgmy‚Ž™Ÿ¤¨£œ˜‘Šqi`XZ^`gnrvwqmnrx|ztplosu{‚…‹‘ŒŒ™š’‹xwxuy†ŒŒ‹”›¤¤Ÿ™…‚}vttrqmd`dm{ˆ•——˜–‘މzqbUPMR\`aeggmqqv{yvqf`aclttuy}ƒ‘”šœ—ƒuoosz€€„Š–¢«³¹º¸°Ÿ’Œˆˆ‰‚yupnu}…™œ™Š‰ˆŠ‡zog_]achryzztnpw~„„|upmprt|‚‚‚€z|…Œ•›—‰{|zx|}zurz‡“ ›š•’‰„‚{slc_gr}‡ŠŠ”˜œ—“Œ~sgZW[]adbcjpu|~}~xme^Z^bdffdjs|ˆ‘“—𖉀…†……‚‚Š–Ÿ¥©¯¯«©£š—•Œ…~trvsswy~‡‰ˆ””ŽŠ„}ywphdachjmqu|‚„‡‡‰‹†}uqstsxz{…„‰‘•”ˆ~xnjmjjrsrz~‹˜¤¦šŽˆ€yvsonomlpz†’¢ž›˜ŒŠƒ|ypbWMKVdpyyu{‚ŠŽ…„†{rpeaovtyuefqsz‡ˆ‚usz‚Œ™¢¤¢¥«²¸¼ÁÅÁµ¥’†~~{m^[ZW\gn{ˆƒ{~xЇ‚{eUWUMUchr}{z‡“œ«° Žƒ~€€xrv{{rbZbnz…„vqsoqxsp}x}ˆ‹—¯¸·»±™’‰ƒ‡€rngYW_bj|‚yttw‚‡‚€„…€wmn|Š–£¤œž¥¦«­¢™›o]SGISNFOQMYkmpxrikh^f{Š™«¹º°¤žœ—™§¯¬¦£¡–Œob]ajqw‚Ž€m_[XROZp‰‹œ§© •†}~…—–Ž„vfTFDMX`goy€~~zsotœª¼ÌÍÀ¬ž™—‹‘¥¥ ˜‘‡{ocR?45?GMV`d\MEHLNRb{–•—¡«®¨ œœœ¡«·Á¿³£’€l[SV^dhlqsrpongZOP^oz…•¨²® ––™›ž¨³¸¶°«¦œ~qeXPT`ku‹‹}gXW[[Zbt‡Ž‹‡‰’‹€wrrtyƒ˜–Œth[PNVbhjmqsrpqsphbgwŒª¹ÅËŸ¬§¦£¢¥¬±®¥œ—‚oZH949EQYakrn^PNW`djw‰–—–™Ÿ —‹‘™Ÿ¦²ÀȲ¡qd\\`ekpqoke_XQJFHUj}ˆŽ—¡¥œ’“›ŸžŸ§´µ«¡–‡sbZUQWiz€ˆˆva[_b_^lƒŽŠˆ–“„uty~„— ¥¤ •of_\\`juz{~vjbaghix‘¨³µºÂÁ°Ÿ¢¢œ˜¡°¯¡•ŒoXID;36HY_]_im_PNV]]^oˆ“‘“›œ“‹Œ‘™¥±ºÁÁÀ½°˜ƒui`]`ksrpssiXIGKJIWo…“®±¢•–ž£ Ÿ¬ºº°§ž’}haa]Zbs„ˆƒ„‡r`Y]a]\l€ˆ‡„yqoolp|‰‘”•š‘€une[Was{xvy{tf_eiej}”§««¹ÈÅ´¤›žšŸ­´±¬¤˜‡lXQK@FYsœµ··£|ml¯²º¾°—~c_jjn{†‹†om…•›«²©›€lgf^l’¤ ‹xYJYj|‹—£wj_ajek‰wtqz„“•k\JHEEdŽ¡©¶¯¡’‚‹§±«©›‰w]BD]x•¡£“„ssvƒ› ŠxaXXe{ˆœœ“Œ€‚~†”˜…jXHEXs‹–š‘‡w]W^^clzwmQJMVu‹£¯¨š›’“¢«²²¢’}cPN`£¥¥”€rsyŒ™œŽ‚gZ]_q„™•‰‰„€‡“——“‹{lUKbz‰“œ”†xbZ\]ir{‡}kULHJk…œ§Ÿ›“™¥®¬›}_JJ]v”Ÿ šŠus|‡–¢¥lXWZq…•˜Žˆ‡…}‡•”“އvaOIYmˆ•–€nYVZYfx‚‡{mVDDLn‹¤²¦ŸŸ™“•Ÿ¦ª­¡’~gYUg‚š¡£ Š~xx~‚˜ž¡”†q\XTd~‘‡Œˆ‚ƒ~‚ޓ𙒄mUK^oƒ–œ–„wf\[Zfv†wbUGCHh‰ž©¢˜’““™£¦£—Ž{[KK[pŸ£¢‘‡……‡–¥¥’„u]XWh‚”Œˆˆ…|‡–”–•‹x]LFUi„›¡ž‡qb`]S]t~‚yh[H@Gd‡¦Ž—³ÆÃ¥‚hhwƒŒ€qhqŽª²”}zƒ—¡¡”{kpˆž–{TF[oƒŽy‰ž«¤‚jbi‹Œ€o\h €e]ds|u^V[p‡z]GIa¨ ’‹Ÿ¹¾²‘rfn}ƒ‹|fau—Ÿ˜~rt~›§¢”~oxŒ|cOH\w– Œ~{‰œ¢”teeo†““x`]t–pRQf{‡…t\[lrvhXMOs¸±¢“Ž£µ°žŠoht’¥ˆu|„›£•‚nw…«¸¢ˆjlpwuiS:@]…šž†x‡”ª¨¡„s|‹®¥–zjgm„}ZBJjŽa[XafqnNKO‚¨°¦ŒŒŠ£«¦šqZ]…œskkŽ™xpw ½¾tfwwwaE@Gw”©œ‚…›ª»¤‚t{›©©Œxkm{zqT[v‡‰Š†ˆ‚xsmŽ©Äů‰n_p€—„c;2Ju’‡rtˆŸ§™uUQgŽ›y_Yl…‘‰rRUr•ª Œuq{“™vY^zœ­­›ˆƒŠ ¤’kIHcˆŒ{ijw¡™…u{š»¿®“uku†„rQ9D_‘’„us„š˜‹hU`y’—‘va[nƒ…wb[jަ®©Œqh|–—‚kdo¨«¥‘~z‘¢˜zVIPpŽ™Žwegylp}𝾫‰mn‰“‰gOBNcyމxfsŸvg]n„ž¨š|_j†“‚ojk~•ª¯¡do†•‚iXT^u”“Šoi}™¤€kij†ª¬”hcp“–‡~z‡†¦¾Ç¦yow˜~cOMOl}wVXnŽƒoediŠš£‡_SgŒ„rqx§¶º™zm|Ÿ˜Œme^_…šŸ}iiƒ£—ˆrkfi‚š¢tOKgІ}ls|Œ§²º“rk‚^TM\~Šufk«¡urgqŸŸƒqo‘®¤’xtrz’šude€šƒha[_uƒ…g]gŒ¨–|^YP^v…wlu›µª˜„ŒŒœ´²¨ˆxv”¬™…j`T\swpWTa†Ÿ{`_Zfƒ‰ljt™²Ÿ‡mpr†ž¥Ÿwlt”«œ‡nrq‡gaož´Ÿ„_VNcy€fbn™¬‡kprªª–ogm•¦’z^ZShˆzX_s£·§Šlrk–‘poz©¶£ˆgij„—Œhdp™¤”uY_b‡„sXYhœ§•wZ\[x‚†xbo¯·¨Švƒƒ£²°’yu„°®šw`ZYpuydNPj–˜Œm_gpŽˆr^_w§©™~mkx—––‚w|¶²œzoq{˜–‰h[]u¢¡‘o_^c}~|bTa~¥¢mfo ¢Ÿjk†«¢j^_o‚}|aYc…²°žzpr‚ œuloŒ²ª•pef|œœ”pej…¥Ÿˆa\]rŠ„yRIRy£¡g[Zl‚…„kiu¾¶Ÿwpt‘¸ÇÅž{at”œ™{p_jtkdD@Gu¤°¤{bK\v†Štqo‹¤›nQY‚¥«­š€|™¯°©‡le|ŠwlWJ]‘¼Â²„TD\nlrh_l‘§›‡bHY‰¬°§ŒniŒ¦£™sSOgvgbSNj È˸ŒeZzŒ{nx™®žˆdHT‚ ¡šns—¬£”lPOm~i]KD^•¹¸¤wRLm‚{}pn‚¨À¯•q[m ¾º¬‘€¤¸¥bCFanXI::[•¹·­ŠhQ]gi†˜¡§©šxbTL_‹ ¡¥šŒ€‡›™ŠˆySHM[y¨Á¼®†]@DNLjˆ˜¤¨™v^PMe—±¯­‡s|…}Їysp]=8CZ|®ÌȽ›{ckxu¥­°²¡}cQKWƒ˜”˜‚v}ƒ}‰Š{~oJ<@Oh𳮩ˆcJLSTp‘§°¸¨ˆrffs¡·°­œˆry‚”‹‚€eA34D^Ž«ª¦‘yhrzv‹ §«´ž|bMJRy‹†‡|rhu}}‹˜œš¤”q]Ybu¤¼·±”pUUUTd~“ ŽkUGIXŠ¢Ÿ “ƒt~„…Ž™™tO>>Qjš¶·¯Ÿ†qz€€‘¬¸¶¿¦€dOJNo{ywk\iosƒ•š–‡fSQ\n–¯­£’qUTQUiŠ  ¦“nVPVd§¨¥¢|‚ƒ„Ž £–“vP>CSk•®°§ ‡qvv{‹¨µ°²›u\WYf…‘Š|vcLPR[p•©¬²›tYY\m¢žˆkTTMN`…š˜q^cl}¢´®Ÿ”}egpr‚¡±­¥hPVXh‰¤¥–•‚oqrv‰­¹±­œx_^al„’‰}v`FHV\u›«®©—u^calˆ¢¢Ž‰nSQQShŒš—“Œr_lt€œ¯©¢›€d`kn¡­¬žŠgS_[cš¡šžyuuw‰¬µ¬£™y_ffk~Œ†€|fKDUZqž°³©–w`khn…˜˜ŠŠvZNMI[‚Œ…m_q|ˆ±¬¦¡†i\jhw ¬­£ŽnY]`n‰ ¥Ÿ¢’zpoq€œ¬­ª}ghjn|‰‚{s\JDNXqœ³¸± fefn†˜–Œ‰rRFDDUt‰”—wir|†˜®ª¤›ƒmahj| ®®£r\\an‡ž¥¥¤•ykml{–¨«ª }ighkyŠ‚}vcODOWo˜¯²®¡~gdiq…–”’ŠuRA?>Tr˜›–}tyˆ–¬¦¢œ†m_chƒ¤«™ˆzggu€|€ŒŸªŸ|hik†¡®¢“Šx{„„wrysz€nWD>^£²¨ŠŠ…Šƒ}qv|{gE1/He‡˜™…••ž¡¤Žt]Sk€ ¦—‹z||‚~|~‘¡s[\sޝ´ª•ƒz€tlehx|†pW?:^€§®¤–‰Š†‹ˆ‚xyƒˆ…fE*.Lm••ƒ{…”’š©«­ŒoVRmˆ¥¤˜…{xv}zys~—™~cKVp±µ©ƒqxŒ©¦™s`dp‹ŠxTEZ¦«™zot‹££”mVRg}xd?:Lr—™‹jbnŒ±´¨Š|’ª¢‡e[m¥¡ˆgbmˆ  h_gƒ˜“€cev™²¬™ulz–¨ž‰j`i~ŠnPJ^ˆ¢¡ˆop~¬¤‡cX[sw]?DX–•}ch~ µ´ž‰‚‹£­§…h`s–•sVS`‚’•}fcr“ž™|edr“Ÿ™zbd¡°¬wlu‹’lYXm‘š–uc_r’›—wb]nˆŒ…fQPe‡˜‘qck°»±‘sƒ—˜’gSTm‹”‰eXXu™£Ÿnpˆœ¥|nj¢©–tbdª³®†ujz–†_TQs’”ˆeSWy”ŸeYXqˆŒ{`PPw‘¡•oer›¶Ã±‘†z–§¡ŽfSZ}Ž–„]RRu—ž‡k]d‰“—ˆk_c™¥†b\e•«¯ €mi‚”€__n–¯°™zdeˆ•–{XN_ƒ• ‰uhd‡–•{]Un­´pn‡•qZRd™•{\OXvŠoZUlŸ²±†v†£¨§ƒfaw¡µ¯‘ybkŒ“ŒoUPo•¦¡iWaŽ…hOGf‹˜”wc\mŒœ’sbX}­¼º¢‡zŠš¤˜t`Zvª–y^Le}‰„gROn“¦—€riƒ› ‘sZ[|›­Ÿ„sjz‘—‚kX[‡¦³¤†oiyŒ˜‚jYVz™žˆr_c’›ˆjZ\¦³ |z–“{^NZ}§‡mYTm‚tcRa‰¤°—yt{–­ªzim’­¶Ÿuxˆ–‘qYNW¤¬r]`rzfNKVyœž~fZk‰›Ÿ‰n`n‘·Ã©“Ф©–y^MdŠ«µjY[p|fVK]‚¡£…g`v¢Ÿ}dVd‹¬¯™v†—ŒlUOk”º¸–ygs‡Œ„qVSm‰¨Ÿ{c^t‘¡˜„eQaƒ®À´˜ˆ€zn^ROj§¦‡]NRc„{h\e~˜˜€€˜§¯¦‡c\k’¼Á´—~~sdQUr•±¬ŠfX[q…‚o\Z_tˆˆrfhr›’uch{¢ÆÍ»¢…†‡uZS_wœ²©‡gZWo…qdbk€”xlnxŒmY]n”¹»§‘sw{kUUc|£»µ—zlj“Švkiqƒ‘…ogkw“£sdfyžÀ½©•‚wuv^DDVq–­œz`WZq‹‚pikx‘|v‘©¶œ|lq‡¨Å»¢Ž|tssbU\dlzˆ„„‚zvyh]etŒ˜Œ~|zrt~uq˜¢­¢•”Ž…n`iu}ˆ“ˆ€‚xuve[eq{‡“‹}xxxr€Ž˜ §šŠˆsprbV^iw…“‘Œ’ކ‚„xmv‹—Ÿ”Œ‹‚zwyrn~ˆ”›Ÿ—‚zuseX`grz‚}w~wppncZcn|‰”””›“ŽŠ‰€w„Œ—Ÿž•އƒƒseihqvy{|ˆ‡……‚vnw‚šŸ–wtnd\gpw~}z{…„††{‚ƒŠ‘‘•‰~rb[aiv~ƒƒƒˆ}w{xqo}…‹”ކ†‰{~yngoou~}€‡“‹‹~}‰˜¡¢œ››‡||pgcjpsxtry‚~~†…~z‚‚Š‚€ƒ…{ppfX[djv~€ˆ†~ƒ~uw‡Œ–‘‰‘’ˆ„„~uszzy}vy‡”—–›•ƒƒ‡„ŠŒŠ‘•‰„…{prsspke_kxx|……}€†‚‚†€~‰Œ†‚|q`djcgims‚‹ˆŒ‰’”ŽŠ†‚}……||~|y€yrptxŠ”‘”“„ˆŒ‚ƒ‰œŸ’Œ…}rz{spigfqwu{‚……‘‡}}~Љuma_dY[]fuˆ“‘І‘ˆˆ‚‚†‡~zxy„‡{uw}‹••œ•Œ†…Š„ƒ…‘™š“Žunrvpqjfhnux~}€Œˆ…€‚‹‡ˆyhb^a\^acv‰”–˜ˆ‹‘ŠŒ…~€~|ysmr}}vwy}†‘™™œ•‡ˆ‰‡‡ˆ”ž•€twzwlijelsv}~}{…’†ƒ‚„‹Šyl\__YUV_fwŠ’”•ŽŠ‘–‘‡‡‰„…ˆ~ztlmv†‚|{y~ˆ•™–Ž…€‚‡‘š“‹ypssnjjkknuruunu…žžmm}”ž›q\WZTRTVhœ¦¡“yvˆœ¦¢™‡{uvpnl^hx–Š{gl›¬²¬•ƒ}€{xuq”©«š†g`oƒ‰}jeirtxxn{Ž¢§—‚kn–“{aXOXPJHTj€¢­¬˜€~‰ —†€}v€ztkaj}•“‡qht†¤²µ¡‘…ƒŠ{uko‚—­¯Ÿzb\j€€{okkq{|~ro{ޤ¡Žvon~’”“{eWWZPJDVoŒ¨±«’zŽž¡œ‹‰†ƒ€yocbjƒ“‚mir‰œª©”ˆ{z|pfdo‚«°¢„qk|ŠŽ„z{|‚€}{zz|ƒ~z~‘€tliggfZTOViz„ˆ“–œ ›œ„z}ˆŽ€{nnopwuvs€Œ—š‘‘ŠŠŠˆ~titŒ‹ŽŒ‰~wks~‰‰~yy{{y|z‚ˆ‰~ujnkoke^[cizz}‚ƒ‘—–•ŽŒ”–ž“uligkhlqu†›˜‰‰Œ‹’‹ˆ~w}†€|v{ƒ‚Љ‡‚‚†˜‡yvwuvuvx€†Œ“‰}qmnuxtpfgjnxust{€‡Š‡‡€†ŒŽˆyknmptw}„—£§¤™’ˆxvrwxsomu~…†‰ˆŠ‘–˜‘ƒwrqvuwy}…ˆŠ‰…vpppwuqlhhmpssmpx…††…ˆŠŒ‘‡wlnruy{|‹’˜Ÿ œŠ‹Š‚zxvtqsnefjyƒ…„ˆ’’“Š{spw{{y{ƒŠ“““Šzsrtvwopx{…‰Šzy}zztu{„‡Ž…ymlqmqquƒ’–œ•‹|‚€{~‡‡‚…}vqt}{‚†—™ ˜Œ€~~}|u}„ŠŠˆ‡}qeinpqjmsz}…€xnsxyytyŒ‹ŒŒƒ|qu{}yx‹›œŸ —„†}w{‡…„€vjdnv~xqw}ˆŽ–˜v{}€xpu‚”Žƒsgow~xtuŒ’އ{ty€‚{rq€ŠŒ‰roqx~uns€Ž•——Ž|xw}ƒzss€†‡†€ymnu…xyŠ•˜—’„~|~}vor„‹Œˆrpoy|wutƒ‰‰†‡€xzyxqr„Šˆ‡€sst}}yt{‹‘˜–—‚€}ƒ€wnq„ˆ‚umot„|tw‰”„zwx‚}vlr‚‹’Œ‰~uuw~zwzˆ––||{…’•”€ndn}‚z{xz|}{kef~˜¡Œ‚vst{xtrƒŽƒsop{†”…vmyˆ“’Œ‹Œ‡~lbe~–¢˜†vjkoz~{vxŠ’“‡wrt€‹}d_m{~€~{{ƒˆ€~sgsŠ¡¤œ|u{}}€{vzŒ˜‚rem|‹Œkhy††…|yŠ‘…}nal…˜›’ƒqltx{zz…™¦œ‚v}‰”•Œ}ifu|uskhpxwrg^m‡›Ÿ˜Œ|„…€|{†—Ÿpbixƒ†‚xnp‰„„~}ˆ“™ŒshtŒ™—snuwtyuxˆš¡—ˆxomoyŠ’‹viZahp}„~~zonx„‘£«¦˜‰wiq{…”žž‘ˆ{h]^cp„Ž…{qbiv~Œ’“Œ‡}okt~ˆ™Ÿš‰xjakv‚“¢©¢™|nknx‰Ž†|qg]coxƒ‡‡yn_Yct†ž¬©‹|qt}…’Ÿ—Œl[Ybqƒ‹ˆxpjt…› ž–ˆvf`ft• œŽ{negq{Ššœ•‹}ma_iv‡Œ‡}vps€‰’˜˜„sc]cr‚– ˜|pjjs€œ ›“…ueclvƒ‹†€xmkp}…Œ•“‚rd_ev‰œ§œŽropxŒ™œ•ƒob`jx‡‘‹…|vx{†‹Ž•”Šo[UWgzŽš…wiffo|‰™ ž˜‡pebly…‡ƒ}wz~…Š˜˜„tffk{Žœ¦›ƒsmmt~Š–™“Ž~miku‚‹“‹„{liinv‚–‘‡wgdeo}ˆ…wljio}Žœ¢œ“‚mjlx†•‡}njkpw†–žš“„ttt|Š”™Ž‡~rmlpw†“›˜‘~hegt‚–‘Œƒwoopu„”ž˜Ž~jeekx…‹ƒ|vkfinxŠ˜Ÿœ“kfhr~Š’Œ…zmfjmu…–¡ž—|wx~Š–œ“‹‚wnpx}‰”—“|hdgpz‰“Š€slnptƒ’š–Œ€lcfkw…‡{wohksx†“š™€kdkqw…Œ†vnkpsw‡›¥¤”…|€ƒ˜—‰ƒzpmtx„’—˜lgmt{†Ž‰xnlnn~‘—“Š}k`cjt„€}wmefsz‡˜žž”ogkrxƒŒ‡umlot|‹¥¤œ“…z}ƒŒš›‘‰~piirx‚’˜›•„rmrz}‚…‚„‰‡re`m‰™›•‚nchqvzyv{}tihjt‘£§ž„mcelnsxv{„ƒ€vjl|™¬°¬š‰‡‹„}Šƒ{pght”¦©¡‰tmsxx{‚€„‘Œ€q_]l„›šŠqbbky{{tv|ƒ‰~m^cx”¨§šnjozzsko|‰Žƒwjn™¯¬ž‡|~Œ”Š}Š‹~l[_qŽ¢¢–wv~†ƒysy„’”ˆvfivŠ˜“kdgrzwpiow‚…{laj}™¨£–ƒzy~€zohnz‹Œ€qejz‘ €|ƒ‘˜‘†~‡€maj{•£ž‚}~…†wu~†Œ‚yx~‰‹…vjbhw‚†zkcgsz{rnox‹•™|ƒŽ”}ochv…{qp|Œ”“†yv’Ÿ¢”ƒy|†ˆƒtjht†‘“‡{xƒ“›—‡|rw†…{yŒŒ~j][j~ŒŽsnu€yf\`nƒŽ‘‡~€˜™yjdm|‚‚unsކwoq…›§¦—ˆƒ‹’l`bp‚‹‰€y’Ÿ ”sr{‰Œ‰zor}…‚whah{Œ•”‡|}†Œ…weX\k}ƒ‚|u{ˆŠ~nejxˆ‹‡~w™•Š|wž ™‹‚ŠŽ„s`W`p‚Љ…ƒœ¢™‰xqz…Š€sjs~…shfs…’’‹ƒ~†ŽŽk[Ubr‚{vt€Œ‘‡ymit€Šˆ€yw…“›”…zw„’œ™‘ˆ†‹‰{gYVfw„†€~Œ˜›“‚uoz‚†}qkhx‡’„{u€‰‹|z†•Œ}rkv‚‹„vniwƒŠ…xmgqz€{qnr†”ž™‹~v‹†zrp~‡‹ƒvkhz‰“‹€z}Ž›£š‹~w‰‰ylglŒ”Š|pn|‡urw†‚rffv…‹}oil}‡Ž‡{on}†‰|st~’¥™Š{w…’•„wps‡‰|mcfyˆŽsrz‹˜ž‘sr€Š‹wkhq‚Ž•Š{mo€•†{{ƒ•—‰zrq~ŠŒ|pnu€ˆŒtnrˆ‰wknyŠ•™Œ}su‹‹zoowƒˆ‡zkhq‚Žsw‚Ž—˜‹~w|‹‘‹vhkw……xsz…}ty…‘”pnv„Œ…sfht€‰‹tr|ˆ„qgpŽ™–‰{w€”‹vkp{…‰„wijxˆ”‰vkt„‘™•‡yu}Š€l_hyˆ’‰‚„…‚ys{Ž™š‘€ris‚“…xsz~~|ywy„Œ„m[Zp„”𔋀~€‚|phnƒ’‰zmht‚wv‚‰Š†|”•…l[\r„‘–‘ˆ„†„|njxŸ ‚rny…„~sjmx…zws—’m`bv‰’‰‹’…tjbqˆ—˜Š{omx€}tpz‡“~ws}Ž–‘€l^]o€…‰†…Œ‘”ˆwmix’¤¨›Œ€z‰…xry‚ˆ€rher„ŽŒ{e[^o„ŠŠˆŽ’–‹znixžymily‚‰†{tnrv}ˆŽ’ˆoeclŒšš‚tprx~†Œ•˜”ŽztvƒŠ’Œshdjt}†‡Š„{rdacn‘Ÿ –‰}vw|ƒŽ’˜’Š„volq|„‡ƒyqlhpz…‘Š~ugado~—™ƒyorx€Œ“œ—”‰€}„ˆ‹‡yle]gv‚Ž‘•Œ}qb\_jyŠ˜œ’…stz€‹™–Šupsw~€~shhen|Š–šŸ–‡}pcckwˆ‘–Ž‚}rqv~†Œ—˜’‹trv{‚‚vkkhq‹•š ›Œ}pcco~Ž—šŒ|wnlqx}‚“ˆ€rou|ƒ††yklmt‰”š–‰|p`]j{Ž—šytrx†Œ–œ—Ž„rkr}‡‰‡yhgkrŽ“•™š€sb^l~Ž––‰umhglsy€Š’ƒyniq|……viipx‚”˜œš|ocaq„–žž•…}{{~…‹••~skit„’Ž…vnkkpz„ЉyngerŒ‘ˆzqmkmu~…‹Œ‡{rnmyˆ‘•’Œ€ytsw~‡‹‰|qnkw„—•†}zzx~…Š‘Œ€rlis‹Š…zsopt}…‹“‘sony„—“Œ€wpmjqzІ„{ojgr€ŠŒ‡~wpqtz‚‡ŽŒ‰}omkx‡• Ÿ˜Ž†||{‹‘˜“…wplt~†‹‰ƒzqjkoz†Œ”„xhdgt•‘‰tkjiq{Š„zmknw„Ž“†~woqx€Š‘—†|mlq›£¡–Œ‚vvz‚‹’—†{olox‚‰Œ‡|uohks~Š”‹wkhmz‡‘—“‰~qffir}ƒ‹†~xojnxƒŽ“‘‡~wpqw€‰“Œ‚zokp}š¡¡—‹usxŒ’™’ƒtlp}Š‹€xrrxwutz…Ž’‹zmglz‹•’ˆ€{yxrkimy‚‰…wkekzŠŽ„~||€yx}‰”—|nip€‘›“ŒŠ‰Šƒzx}‹—›—†tlr~‰‡|vvvwslkr„”—Œ{k^ewŠ”ˆ}}}wnfgl}•xhal~Ž“‘Š}|~~{ss}‘ ¡“}l`h}‘›˜‘ˆ‹Š‚yqs{ž¢—meo€ŒŽˆ}zxvqko}‘¡žxe[bt†‘ƒ{xtlb^dp‚”—Œ{igu†“—•Ž…€~{vqtƒ”˜ˆrfgu…‡€€‰”—‰xt{Œ˜š}qp€–Œzru~††}qkq†˜›‰rfhx…‹ƒulkxƒ„ub^f|‹†tmp…˜ž‘}tx…‘…vos†”—„mek~‹’Š|w{Ž™›ˆrmuŠ•˜‹xoq…”˜ˆsmt†’‡zu|‘›˜~cY`v„Œƒxtv‡‰s\Xby‡Š}mjqˆ˜™ˆws{””…wtzŽ–‘w`Zd|Š‘‹ƒ‚Š£…nlw˜–†unr†€poz‹‹zoox”Œs^Ye|ˆŽˆ‚…Š˜—‰p__nƒˆƒsdbm€‰‡wnr€‘“Œx|‹žvcbq†Ž†‚†‘ž›‹ugl€“–{rr~Ž’Šypu†“„tmt„“’hZ^q„Šˆ~†”ž–€h\dx‡‡{kbev…‰rmv‡“‘†zw~Žš–„odi|‹Žˆ‚‚Œ˜¡š‚mbj“І”žš‡qgkyƒvmmyŒ™–‚j_ctƒˆƒ€‰–’x`Vbv„†{pnu†•’lem|†…zux…š§¡ˆqgm~Š…‚œ£™{f_jކˆ—ž•}khq}‚~sqv‚’™wfcm|…„}…›œq_\hx€tqu€”Šuigq~ƒ€xy‚’ ¥—|kisˆ†€‡“segt„Œ‡}}ƒ‘žŸwiiu€…ss|‰–šŠqcbo}…‚|ˆ“™•„l`ao}‚|rs~‹””…pfjw„ˆz}ˆ˜¡‹sfjy‡‹„{~‡’˜“iagx‡‹‚x~Š–˜…ndhw‚†{qw„“‘€kdix†Š‚|‚‘œ”€jai{‡‰}tv‚{kcl|„„upw‡–š“~i`i{‰‹€|ƒ‘˜˜Žwfcn~‘Œ‹•‘Š…~y{ƒ†„|nkt„Š‹ˆ~rknqvxyƒ’ Ÿ“€m`_m|‡ˆ‚‚†Š†‚{ttx‚ˆ…xkl{–—torw||{„–¤ž‘}i`dsŒ‹ƒ‚‰’…|rq~ƒ„}occt„Ž‘‰ztuvxww{ˆŸ©¦˜kdn~‡Œ‰ƒŠ‹‡wqu…Љ€ofk~•‘…vorttssv‚—ž˜ˆrbaoˆŠ†€‚‹ƒzvy‡Œ‡}ngk~Ž”„vqwz{zz€‹ž¥Œtcao€‰Š„{}‡‰‡|spu…‹ˆ~pip„•˜€rmtyzyw{†™¢›xg_dr‚’œ›’Š~vrrw|†‡ƒ|qjhp|‰‘‘‰|siflxˆ—¥¨žŽzibgsƒ’œœ•tnowŒ‰€volt‰Ž‡zqf_blž¢™‡sd^fsƒ‘šž˜‚vonv€‘Œ‚vnlt}ˆŽŠ€xnffo’£¨ Ž{kekt€Š‘‰‚wlfiu†–š”…xolu€ŠŽˆwmeel}’¢¨¢zkfmwƒŠ‡€ujdgtˆ˜ž™Š|rq{„‹ˆ€wmb_gu‰šŸ˜ƒobamx‡‘–—‘Œƒysu€’ ¢šˆvkir{„‡ƒxpibclzž¢œ‡uhckt‰‹Š„~umimyŒ›¡ž‘…{y‚Š’–‘‹‚vlb`gs†”—’na]gp““ˆvswŽ››•‡ymkv~‡‹†~vldfp|‘£¥ž‹xidms}‡‰†|rkks€“¡¡˜‡vhfqz…–•‡yjekrƒ““Š{oggqwŠ’’‘‚xv€‹›¦ “€qc_ekr~ˆŠ‰ƒuhenyŒœ›’…{qoux}‡Ž‹„vihu‚“žšŒ~rhisz‚™š™‘‚qjnw‰——‰yk`_hqxƒ‹‹‹‡|ppz†˜¥¢“qb`hqx„ŽŽ‰}oms}ž¡—Š~rmrx}…Šˆ…rfemyˆ•–‹}obakuŽ™›—Žolr}Œ˜˜‹tihnt{†”“Ž‚wx‚œ¦£’‚rdaeltŠ‚tecmzŠ——Ž…{ohjou‹Ž‰‚rdgq€——wmkowƒ”¥©¡”€njrŒ•”‡|ujdfiq~•’Œ}rt~‹•›—ˆ{rhdfju„”™“‰xihq𛓋„xommt~Œ“„tffp~Œ‘‰wkkoy}|€Ž™œ—ƒngo€•Ž~rrsx|wtw„“š™‹}zƒ’œ”€qoouxsru‹Ž‰{jfo•yyxzxqln{ˆ‰zhfp€’‹|stw}€€‰–Ÿ¡—…pkv‡•–vux|}zu{ˆ•›’‚sr{Š—™Ž|pmquuqnw‚Š„tdbpƒ“—€yxyyxtnu‚Ž„tccpޔހzz€~|}ˆ–Ÿ}kju†’“‰}{z{zxvu‚‘œœ‘~os~‹“”Œ~xwwsplkx‡Œ‚sghv‡’‹€|{{toklw†|iam…—•‡ris†–”…tp•¡šˆrit‹š–†ofr‡”‚rn{‘ž™‰tm{“Ÿ—…nem‡wd_l„’Œ|ifrŠ™”ƒpjt‰“Œzgdo„އvdcr‹™”…rmwŒ–‘‚rr€–’€nlz’œ”‚mgr‰’‹{mn{‘š“…xz‰¡§˜g`h{ƒ~qfjxŽ•‹xjl{—}nmxŠŽ„rdft†Š‚sim”—‹vfdq„‰…{u{Ž£¦šˆ{~Ž ¡•rnx‰Šmchwˆ‹‚upx‹ž ‘yjlzŠŒƒunv†•–ˆukqƒ’‘„qeiy‰‰|jbj}Œ‹~oiq…—•ƒlah{ŒŒtr}“¥¦•€y‚–¤ŸŒvlq€ŽŒze_j€Ž‹~pp~“¡ž‹pfnƒ~nkwŒ˜•ƒnitŠ–~keoƒŒyd_kŒˆwikxŒ˜’}f^iŒŒuzŒ¢¬¦vo{Ž˜‘on~‘œ–kbm‡sio‚™¤œ…ldn‹ˆ|sv…™¡•~hcp„…thiz˜‘zfbn†ogoƒ™¢—~ganŠ…yqy ¥™lk{•‹{qv‰šž’~po|‰‡ykgt¡¢‘wdbp€†~tt€”¡žŠqcg|’ƒogo„“”†qdhy†„tdcv’¥£Žr`asƒ…zpq‚›§ ‰pfo‡˜˜‡tq}”¢ž‹tjoŒ‡udgz•¤Ÿ‰m^bs€‚vjp„œ¥›ƒjaj‚|jgx‘œ•‚ngp„†scg|š¨ ‡nagz††xnsˆ¡¨œ‚jdp‡”‘~mn~•Ÿ—‚okuˆŽ†qaf}™¤œ„mbj|„‚tkt‹¤§˜|gcrŠ”zij}”šyiiw‹Ži\eš¢–zfam~…ojw§¨œ„oiq€‰‹‚}ƒ›˜Šyqtƒ‘‘‡tgl~•}rntzwpfhy“¦¥’yigq…€xu}Ž—‘ojs„‚ngo„”•‹zqrz~zpgk›«¦’yiiv…yx„’—’€ojs†~mfpƒ†wnr{{oin„žª¥xko|ˆ‰zy†–š’ojv‰’Ž|kgt‡”‘‚tkpy}xkej€š¦Ÿˆpekz††yxˆ—›“}nkxŒ•~okxŒ—’‚tlvƒ}mhn…Ÿ©Ÿ‡qfn{†„{vx‰—™Œtggw‹“Œ{ll}Ž˜|plvyljn”¡¡–„unkpu|†Œ—š“†sihq‹Ž‰yxy|zz}~ƒ‚}vmms„—¡ž’ƒvqnrv}ˆœ”„rjkuƒŒ‰||||xux|‚{qghq‚“›•Š|tqorty„›•ƒqikw„‘†‚€yvz€‡‡€tihr…–ŸšŽyvtsprz†“•~nho}‹”‘Š}}}ztrw€‰Šƒvigr„—ž™Žzvrpmmu‚Ž‘‰xifo~Ž——ˆ…†…€yuz„ƒteak}Ž•’‡}wtsrps}›ž“ƒtow…‘˜•Œ…{tmls~‡‡~qeerƒ“™•Œƒ{vqmkmx†‘‡wjiq€˜˜”‹†€zz€ŠŒ€odcn~‰Šƒ|wsnjhn|Žš™Ž}rpy†•‘‹‡„{tor{ˆŠ€qjn{Š“—’Œˆ„}rhbeo‡†~souŽ”—“‹ˆ€vmjs“™“„qhhs~„‡‡‡‡…}shdk{–”Š~{€Œ•™—’ˆtg[YduˆŽ‰}oko{†’“•”…wjdju„Ї|qpu‹Œ‰‡~vljt‚”›™{rnu~„‡‡ˆ†‚xnc`fs„މ‚Š•–“Žˆsh__iw‡…ytt}‡‘–šš—‚uhdhp|‚ƒ|usty€‡ŠŒ‹‡wohlx…‘”‘‡zsrv}„ˆŽ†zoffn|Š’“ŽŠŠ‹“•”’Œ…|oe^bnz‡Š†~trtz‚‰–™–‹|na`gq|€~ywy{~ƒ†ˆ‹ŽŽ‡}rkq€—™’ˆ~zyz~€…Œ‘†wh^`lz‡‹ˆ†ˆ‰‰‹‰‰ŠŠ†|ob\cq‰‰ƒ}|~‡‹’šŸœna`hs}}wtxƒ‰ˆ‚wsx…Žpgjz‰‘†~{€„‚}vw–‘ƒoaao‹ŽŒ‹—š˜‘†‰‹…wf\_m{„†zz‡‡„€Š•™’m^Zeqxyvv{„ˆ†€zy€“smq~Œ•”‹„‚‡Š†~{|…Ž‘Œ}mcgv†ŽŒŒ“”†}y~†‡~m_\bo{‚|y†‰‡€~„—–Œyh]amw{yxz‚††yvz†’”‹|rqz…‹……ˆ‡€vv}‰‘…uifp}ˆ‹ˆ‰Ž•˜“Šyz…Œˆ{k``js|~}}…‹‹…~€ˆ•™“…qa\hz‚{kbh~’š“€pn|˜Ž|op€–Ž}po€”œ“~qq€“ŠxjhxŒ•€w|ŽŸ¤™„smx†‰|i]_p„}phl‚˜¡˜…zzˆ“’…qcam|€vhbj€“˜€ttƒ’–‹zrv†‘„tkoƒ–›}ru„Žƒtkn~‡|z†š§¤’}mjvuifp‚Š…wieo†™’‚z€Ž•Ž}lcgt}|odetŠ–“phm~Š‹uu’˜‘€sr}’Ÿž€{ƒ‘•ŒzkhqІxoqƒ˜ ™…smsˆ…vkmyŠŽ…sgiyŽš™Š|zƒ“‡sdbl{€{kchz—|mku‡‹}suƒ”—{os”˜‰|{‡”•‰ughu„Š…wpu†™”€rpz†‰qhm|Œ€ogl€“š•‡||‡’“†pdcp}~widj}”Œxklvƒ‡vs{ž •€tu‚Ž“Œ}x{‰—˜Œyoq~ˆ‰sovˆ˜œ‘}qox~wlkt†”•‡sjm}І{vzˆ‘‘„qimxshgr‡—™{rv‡…zop{˜•…rls„Ž„yy‚’œ™‰xryˆŽˆznn|š™‡tmq}„€shiw‹—•‚oir„Ž‚wv€–}jdn}„qfixŽ›™ˆvox†Š„tik|›—‚qkv‰‘‚xz‰š ˜ƒqlxˆŽ‡wln‘™“plu€ƒ{kbgzŽ—}ljw‡ˆzqv…•š{khv…Šƒsjo”œ•„vs‹Œqhn‚“š‘}olw†‹„yt{š›Žykl|‹†umq‚’–Ž~rs‡†yhcm‚•š}oo|ŠŒ„yt}Ž™–…qehy‡ˆ}mgo‘ˆyqw…mci– ›‰wpu„‚||‡—¡‹ughz”~ss}‰‹„ztx„‹„ta[g•š’qowƒƒ}wx…–ž–‚j`fxŠ…wpuƒŽŒ„yv~‹’Šxfcp‰œœ’rqx€€{vyˆ™¡—kci|Š‹ƒuou‚Œ‰tr|ˆŒ‚qcbqŠœ‘€vw€‡ƒ|wzŠœ£™„nfm‹Š€sou„ŽŠ€vuŒ…scao†——‹zqsz~{uqx‰¤˜‚nhq‚‹‚ws{‡ˆ|st‘…rddt‹š™Œ}vz‚{spyž¢–j^ao€‹ˆzy{zz|‹“’ˆyjdl~’œ›‚wolkqy†–¡¡”j`es‚‹Žˆ€|ywtsu~‰‘redpƒ”š™ƒ|vrps{‰™¤¢’~jagt‚ŠŒ‰ƒ€~zutu~‰‘Žsfep€Ž”’Š€xrjfir‚•£¢•„rlr}†‰‰…€~|vqqv‚™”„tggs„•“‹ƒ}wniirƒ•¡Ÿ‘~mglw„…„‚~wrqw„’›–‡viit„•“…~vlghs…˜¤ ‘~mhoz…„‚€}ypkjr€˜“„shiu…–•‡yojlwŠœ¥ž|njp{‚††…ƒ€{qmmv…“š‘‚pght‚‹‹„|sieixŒž¥œŒyljs}„ˆ‡†ƒ€yolnyˆ–™€qko{‡Ž‘‹…~tieixŒœ¡˜ˆvkjqz€ƒ…†…yolp|‹˜šsns}‡’‹„xjcft…”—„ytw…‡ˆ‡†yl`]duˆ–™Žups|„‰Ž‘“ˆ{lfjw‡”—…|xz†‰‹‹Š…}ob^drƒ‘”‹~soqy†Œ’Š~pjmyˆ•˜…{vw~‚„……ƒ~vk_]dt‡—›“ˆ}xy€ˆ’”“Ž…wicfrŽ’Œ„|vv{†Œ†{l`]ds„‘•…zssy‚Š“š›•Š|njo{‰”–Ž„zsrty~ƒ†ƒ{naXXcs…‘•†~xx|…Œ•›š“…vifmzŠ”–Šƒ‡Š‘“ކwh]^gv†Žˆvqqt|…‘˜˜’ƒthfn{ˆ‰„}xwvy|„‰ˆ€re^am|‹”–‘Œ‡ƒ‚ƒ‡Ž˜š~m`^eq|ƒ…|zyz€†••qijtŒ’’Šzvttz‚””Œ~qhiuƒ‹‹‡ƒ†‰Š…|usy†qc[an|…ˆ†ƒ…ˆŒ‰„‚„Ž˜š‘‚qddmyƒ‚…ŠŠ†ƒƒŒ–™’ƒtknw‚ˆˆ„}~~ytrwƒŽ‘‰zldgr~ƒ…ƒ‚…‡‡xtv~†ˆ€qc]ds‰‹‰ˆ‰Œ‰„‚‡’}mehr|‚€…Š‹…€€‡’›šŒykfm{„†ƒ~~€‚€xsr{‰””‡uhelyƒ…ƒ€…‰‡~wv|†Œ‰zh\\gx„‡†…ˆ‹Ž†‰”›–†sgfmy€~…‹Œ†ƒ‹•œ–†qfk|Ž“ˆwlq~Ž‘†xpv„ŽkcjyŠŒrjr‚’•ŠyquŠ„uc\ev‰ƒwr|Œ›œ‘„~„š•„phn|‰‡{nkvˆ˜š}„‘™‘€mgp€‹~okv†‘Žspz‰”Ž}jdm}Šˆ{omx‰–“…uqy‡Ž„r`^j|ŠŠ~rq~š—‰}|‡•›‘~kfp€‰„vkn|š˜Œ€Š˜œ{kiu†Šzmlx‰‹|qt€”‰uferƒ‹„tkn{Œ“su€j]_o‰„wptƒ”š“…}‚Žšš‹vijx‡Œ„slr€‘—„}‚Žš™‰tilzˆ‹ƒtlq~†xsz†Ž€nejyˆŠ€pktƒ‘‰|u{†Œ|hagv‚ƒ{pnxˆ–—€|„‘™”…skq~ˆ†|omyˆ”•Œˆ•›–„rls€ˆ†|pmw…tr}Š‘ojp}†ƒwllz‰“ƒwryƒ‡€pbbo€Œ‹‚xv€Œ’€uw„“š”…vqw‚‡‚vmp—“‡}|…‘”‹zmn|Œ”…zyŠ‹qgkzІvigp{€zpkrƒ’—x{†pdhw†Œ†|uy„‚uoxŠ˜™}qqzƒ„zplu†”–Œy‹•’…vnt„’—„|~„‰…yolv†‘Žndht~xonx‡““‰~z€Šˆxhbk{‰ŠƒxtzƒŠˆ~uv‚“™Šzqt|ƒ€wmny‰“‘‡|{ƒŽ“Œ~pnyˆ’‡}z†ˆtjlyˆ‰{lho{„ƒ|uw‚Ž“‚xz‚‘‰|onvƒŠ†~vv|ƒ…vpv„“˜sqv„€yru~ˆŠƒxqvŒ‰}su“‡€‚‰Ž…zu|‰–—‹{mms{|vnio{……|plsŒ‘Œ€qlr‰‹ˆ€ƒ€{us|‹› —†vps|‚„€{|‚‡…|rnvƒ“‹|pow†Ž‰„…‡‰„|sqz‰˜™zjglu{|yvy€†…}ts|Š••~srz†Œ‹…€„„xqsŽ››ros{}{wuw}|sllvƒŽŽ…yqs|ˆŒˆ†ˆŠŒ†yzƒ˜–‹}rpu{~|z{~‚„€wqr{‡Ž…zstzƒ||‚ƒ~wsv–”Š}ww{€€}z{„…~unq{†Ž…}y|‚ˆˆ„ƒ‡Š‰zuuyƒŽ•’‡ymgiox„…„‚|uppvŽ–•Ž‚vru|ƒˆŒŒ‰†€zvw|‡“™”‰{ojlryƒƒ‚xohhp}Š’‘‰urv}…Š‹„|ww}ˆ“™”‡ynjmu}„ˆ‡…zrmov‚“ˆ}spsy„ˆŠˆ„}vsv}ˆ“—’‡{rnpu|ƒˆˆ†yokmv‚“‘‹xuw}‚‰ŽŒ‡xuu|…Ž‘Œ‚wmikrzƒ‰Šˆƒzqnpy„–”ƒyvx|‡ŒŠ…~wvw}‡‘”„yplnrx„…‚}sigjt€‹‘Šywy|ˆ‰zwy‚–—†{rnpu|„ˆŠ‡vljmw„Ž“ˆ~vtvy~„‰‹‰„{ssv€Š““‹‚wqorw}„ˆŠ‡vljny†”ˆywy|€‡ŒŒ…|trvЉ€wqnpt{ƒˆŠ†}rjjq|‰’”‰‚|yz|‚‰‘“‡|sqt|…‹‹ˆ„zwxz~‚„zod_bmzˆ’•“Œ„{vuxˆ‘Œ„{squ|…ŒŽ‹‡‚€„ˆ‹Œ‡thbdmx„Ž‹ƒ|ursw~‡Ž†}vtw~†‹Œ‰†~|}~…‡„|qfbgsŽ––‰{wwy~‡Š€umlr{…‹‹ˆ…‚€€‚…‰Š‡thbep}‰‘‘Œ…~ywy~…Ž•–‘‡{srw‡ŒŠ‡ƒ}ywxz~‚wmc`frŠ‘‘Œ…~xuv{ƒŒ’‘Štnov€‰Ž‰…ƒ„ˆŒŠ€sgbfny‡ˆ†‚}ywy~†Ž’Ž…zplou~†ŠŠˆ†‚|xx{‡‰„{qigmwŠ’‘Š…ƒƒ†‹‘‘Š~rhcflu}„†……‚}{}ˆŽ„yokpw€‡ŒŒ‰†€|{}ˆ‘„yoknu‰‹‡ƒ„†‡„}vsw~‚vibep~‡Š‡„†‰Œ‹†€~ƒ‹Š}ndfo|…‡…‚†‹Œ‡‚‚ˆ”ƒtjmwƒŠŠ†‚„„}xyЇ{meis……~€ƒ‚~wrs|„ˆsfaivƒŠ‹‰‰Œ‹„€ƒŒ““ˆxjdit…„…‰‰„~…——Œ|ojq{ƒ„~‚……yx~‰‘„ujho{…‡ƒ‚„ztsz…Œ‹odcly‚…„ƒ…ŠŽ‡…”peemzƒ…‚€‚‡Šˆ‚€†‘™—Œ}rr{…‰ƒzuv†ˆ„}{€ˆŽŠ~pjmx‚†‚zvx€††~vu{„‰…ylfju‚~xxŠ‘’Œ†„‰‘”Žqkoyƒ~xw|†Œ‹„Š”˜’„wrv…„{ssz„Šˆyy€ŠŠ{ols~‡ˆ€yw|„ˆ„zst}‡Š„ujflx€ytw“ˆ‚Š’“‹znkr}ƒƒ|vw‰Ž‹‚~ƒšœ”ƒvqw†ƒyst}†Š…|wyƒŽ†wmnwƒ‰†~ww}ƒ„~tpuŠŠqgfoz€zw|‡’…„Ž”’†wmnw…‚{wy‚ˆŠ…~~†“š˜~tt{ƒ}uqv€††€yyŠŒuot‡ˆzw{‚…ƒ{tt{†‹†zoimu|}xtu~ŠŽ‡€‡“Œ€snr{€zuu}†‹‰ƒ‚Œ˜œ–‰}vyƒ€yss{…‰†~wxŠŽ‰ury…ƒ{vv}…‡‚yqqx€ƒ~skkt~……~z{ƒŠ‹†}x{‡’–„zuz}uqt~ˆŒˆ€{~ˆ‘“‚{{„‹‚|{€„yokq‰‡}vu{€{utz…ŒŒ„zuw€†…}rmp{‚…|{…ˆ…~xy€‹‘‡}ww|~|vqryƒ‰ˆƒ€†Ž’‡}‚‹Ž‡€}~€{snpz‡ŒŠyvyyuw~ˆ‹ˆ€zy~„…€voov€†…€}}††ƒ}z}†“Ž„|xy|{xsqu~‡‰„}xz€‡ˆ†€~€‰’“Ž„}z|~|vposŠŽŠ|{ƒƒ€||€ˆŽ…{vv{~ztru}…†‚}{}ƒ€zuu{‡’Œƒ}|~}yuv|…‹Š‚yvy€„„{{ˆŽˆ‚€ƒ†…€ytv~‰‘‘‰}~€€|vsu|…‰…zrpu{}{wwx|€…‹Œ‚wopy…“Š…€|vqqx‰‹†}trw……€{{|„„ƒ‚…ŠŠ€unpx…“‰„€}yuu{„Š‹†{sqv~‚€zvwz‚‚€€…‹ŽŠsmr}Š’”އƒ€~ztopyƒŠ‹„ztu{‚„zvx{€‚‚€‚†‹‹…zomsŠ‘ˆ‡…ƒ}vrt~‡†}xy}‚{usx}‚€€†‹Šƒypow‹Ž‰…„~wpmq{…Љ‚zw{€ƒ|ww}‚††ƒ‚†‡‡„€|xwx}…•”…{rnot|ƒ‰‹‹…}vpory€ƒ„}{|~„‡‡†„€|zz€ˆ”“Œ‚womot|ƒ‰ŒŒ†}uppu|‚……}{|}ƒ„ƒ~yxx~†”“‚xpory‚ˆ‹…|uoot|ƒ‡‡„€~~ƒ„…„‚~zyy‡Ž’‡}rkknv…ЋЄ{topu}…ŠŠ†‚~~€‚ƒƒ}{{}‚‰’‰unmqy‡ŒŒ‰‚yrnnsz‚ˆ‰†‚ƒ„„ƒ}}‚‰‘އ~unnqx€†ŠŠ‡€xrnou|ƒ‰‰†‚}}}~~|zz|‰“‘‰wqqu{ƒˆŒŽ‹„zrmnv‡‹‹†‚€€‚ƒ~{z{ˆŽŒƒyqmnry€†ŠŒ‰xpmowˆ‹Š†‚€~~€‚~|z{€ˆŽŽ‰zvuvz‚ƒƒ~wpmou‰‘‰‚}zyzƒ…†ƒ|z|€‡ŒŽ‰‚{ustw~ƒ„„~wrprw€ˆŽŽ‡xtsuy}€~zwwy~†‘’‰‚~{|„ˆˆ…wqnpu}…ЋЅ~yvvz„††„€||}‡‹Š‡{urqu|ƒ†„~vpos|…‘‘Š‚{vsuz€„ƒyuvy†‹Œ‡{xx{‡ˆ…wpnpw†‹Œˆ{xx|‚‰ŒŠ†€{{}†ŠŒ‹‡xrnou|‚ƒyrnnrx…ЋЇ{xy~„ˆˆƒ|tpqv~‡–˜–‡€||€†‰‰„|upopu{†ˆ‡„~yxz€†Š‰„}vrsw|‚ˆŒŽ‹…}ursy„„€{vtux}ƒ‰ŽŒ†€€†Š‹‡€wplmpu|ƒˆ‹‰ƒ}zz{{{|€„‡†zvw~‡‹†ƒ‚‚‚€€ƒ„ztqu‰Š„~{zwtssw|~|vpos}†‹Œ‰†…†‡„‚……voou€‰Œˆ„‚‚‚{{~…ŒŽˆ~vsx‚‹ŽŠ…‚‚ƒƒ€|z{ƒƒ|slmvŠŠ…€}{yuppu}ƒ„}uoowŠŒŠ‡†‡‰ˆ„€†‰†~slnv€‰ŒŠ†‚€|y{€ˆŒ…|vv|„‹‹‡„‚ƒƒ~{}…‡ƒzploy„‹Œ‰„€~{wsprx€„‚zqmpx‚ˆ‰‡……‡‡†‚€…‰‰„zplq{…ŒŒ‰…|}……ƒ€€ƒ„„‚†‡…€}}€…‡…€{wwyzzxy}ƒ‰Š‡€{yy|}|xvuwzzyxxz…‡†ƒƒ†‹ŒŠ„{z||zyz~ƒ‰Š‡}|~‚„ƒ€ƒ……ƒ~‚…†ƒ€€ƒ††‚~{xxyzzz}‚†Š‰„~zxy{{ywvwxyyxwx{~‚ƒ‚‚†‰Œ‹‡‚~|{|{zz~‚‡Šˆ…€~~€ƒƒ‚‚ƒ……ƒ€~~€ƒ„„€ƒ„‚|zz{{zyz…‰Š‡‚|zyz{zxvwyzzxvvy}‚……ƒ‚„‡ŠŠ‡ƒ~}|}|{yz„‰Š‡ƒ~}‚„‚€„†…‚~|~…†„~€ƒ†…‚}yyz}~|zz…‰Š†|z{|}zvuvyzywuux}‚…„‚‚„ˆŠ‰…€}||}|zyz…‰‰†ƒ€€‚„„ƒ€€ƒ††„€}}€ƒ……ƒ€€‚……‚~zz{|}|zy|†‡†‚~}}~|zwtuxzyvtsw|„„‚ƒ‡‹‹‰„€~}|zww{…†„€€ƒ††…‚€‚„‡†ƒ€ƒ†ˆ‡…€‚ƒ}xuuwxxwvx|ƒˆ‰‡ƒ‚„‚zwwyzyvstyƒ„ƒ‚ˆŒ‹‡}|||zxuv{‚†…}|€„ˆˆ†ƒ‚„†ˆ†‚€„ˆ‹ˆƒ}{|€ƒ‚~xvvxzyxwy†ŠŠ†‚€‚„…ƒzxxyzwtru|‚†…ƒ€†‹ŽŒ†€}||{xvtw}…ˆ†{z}‚}~†‰ˆ„„‡‡„€|{~‚„‚}wvwz{zzz†Ž‘‰ƒ‚ƒƒ€|yy||wtuz€|yz}‚ƒ€|wwxzzyxy~…Žˆƒƒ…ˆˆ†‚‚…†‚}z{€†‰‡vsw‚Š‹„xqpuz~}{}„’…zvzƒŠ‹…{uuz~{wx~†Š‡~usy„‹‹‚vppv{}|z~†”…zx~ˆˆ~xyƒ‚}xy€‡‰…{sry„‹‰vqrx}~||€‰’”Žƒzy‰Œ„zvx}€~yvy€ˆŠ„yqrz†Œ‰€wsuz}}yz‰‘’Œ€ww}†‹‰zz…ˆ„~z{€ƒ€xnio{ˆŠ€xux}}y{ƒ•”Š~xzƒ‹Žˆyz†‡ƒ{y|‚„€vljrŠŽˆ~vtxzzxuxŒ’†{vzƒŠŒ‡{}„‰‰…€}{zzzzz{}€~}}}{zzz}†‰‹‹ˆ…~{{|‚„‡†„‚~|zzyyz{}‚ƒ‚€~|ywxz~ƒ‡‰Š‰‡„‚€}|}€„ˆŠ‰†}{yxvuvwz}~}|}~}yxxz€…ŠŒŒŠ‡†„‚~|}€…ŠŒŠ†~||{xwwy}ƒ‚€}|||zwttw}ƒˆ‰‰†„ƒ‚€~}~‚†ŠŒ‹‡‚~|zywvvy|}||}|zyy|€…‰ŠŠ‡„‚€|{}€„‰‹Š†}zyyxxy{‚„ƒ~|||{yxy|€…‰Š‰‡„‚}}~‚†Š‹‰…{xwvttvy}~}{|}~}{yz~ƒ‡‹Œ‹‰‡„~{{…Љ„|zyywxy}€|{{{{xvvx}‚†ˆ‡‡…„ƒ€}||€…ŠŒ‰„€}zxwvwy}€~||||{z{}€„‡ˆˆ‡…ƒ~{z{„‰Œ‹ˆ„|zxxyz}€‚ƒ|zyz{{{|~„‡‡‡‡†…„}~…‰‹‰…€{wtrqqtx|€~|zz|~€€‚„‡Š‹‹Šˆ†„}zy{~ƒ‡‰‰†‚~zxvwy|€‚„ƒ€}{zxwxy{}€‚ƒ„…†‡†„ƒ€ƒ†‰‹Š‡ƒ}wsqrtx}€‚|zyy{}€ƒ…††††‡‡‡†ƒ|yz|€ƒ‡‰ˆ†ƒ{xxy|€„……ƒ€|zxwxy{|~€ƒ……††„€}{{|‚„……ƒ~zvuvx{}~|zyyz}ƒ…‡‰ŠŠ‰ŠŠŠŠˆ„€|yxz}€‚„„ƒ~|zz{}€€~}|{{{|}‚‚€|zyyz}€‚„‡ˆˆ†„‚€€‚ƒ‚}|zyxxy{~€‚‚‚ƒ„„‚€~|{|}~€‚„……ƒ}~€‚„„„ƒ‚€}||}‚‚€~}{ywvvxy{}ƒ…†…ƒ€ƒƒƒ‚€|{zy{~‚…†‡†…„„„„ƒ‚€~}~~€‚ƒ„„‚€~}}€‚‚‚‚€~|zyyz|~€€~}}{zyxxyzz{|~…ˆ‰ˆ‡…ƒ‚‚~}|{zzz|ƒ†ˆˆ†„‚€€€~}~€ƒ†‡‡…ƒ‚‚ƒ‚€~|{{{{zz|‚…†…~{zyyxwwxxyyyyz~…‡ˆ‡†…„„ƒ‚€~}||||}~‚…‡‰ˆ†ƒ€‚†ˆ…}urw€ˆ‹†zz…ˆ‡„‚ƒ†‡ƒzros|„‡„~{|€…†ƒ~|}€{sllq{ƒ„€zwz€†‰‡……ˆ‹Š„zrqw€‡ˆ„~|~„ˆ‰†‚„‡‡yst{…Љ‚{y{‚‡ˆ…ƒ„‡Šˆ€uopx‚ˆ‡|{„‡„~yy}€xoilt„‚|vw|„‰‰†„†ŠŒ‰vprzƒˆ‡|}‡‰‡‚†‰‡€xsv…ˆ…z|€…ˆ†€†ˆ…~tor{ƒ‡…€}~…„€}z}€‚€xokox€€{x{€…‡†…………„€~{{|~€ƒ†‡†„‚ƒ‚€}}€€€~}€„†……„ƒ„ƒ|zz}€€‚„„‚€~|xutuxz{zyz}€„………………„‚€|zz|~~~€ƒ…††…ƒ„„„‚€~€€€~€ƒ„„„„…„ƒ€~{z{}€€€€€€€€€~zwttuwz{{|}€ƒ„†‡ˆ‰ˆ…~zyy{}}}}~€‚ƒ…†‡ˆ‡„€€€€€‚‚€€€€€‚ƒ„ƒ€}zxxy|~€€€€€€€‚ƒƒ‚€{wvvwwxz{~€€‚ƒ…‡‰‰‡ƒ€}zxwxyz{}~€„‡‰Š‰‡…‚€€€€€€€€€€€€€‚ƒƒ€}{zzz{}~€€€€€‚ƒƒ‚€|yxwwxy|~€€‚ƒ†‰‹‹Š†}ywvwy{|~€~~€‚„…„ƒ‚‚ƒƒ€~~€€€‚„„ƒ€~{yz{}€€‚ƒ„ƒ‚‚‚€€~~}|{yyz{}€€€}zxwxz{~€€€‚„„„„…‡ˆˆ‡†„ƒ€€€~|{{|~€€‚ƒƒƒ‚€|zyz|}€€€€€€€€€‚‚‚€€€€~}{z{}€‚‚‚‚€}zxxy|~€€€ƒ„„„ƒ„…††…ƒ€~}{zyy{}€€€€}{z{|~€€€‚ƒ„ƒƒ‚‚€€€€€€‚ƒƒ‚€~}|{{{|~€€}|{|}~€€ƒ„„„ƒ‚‚‚€€€€‚€€}|{{||}€€‚‚€~€€€€€€‚ƒ‚€€€€€€€€‚‚€~||{{{|~€€€€}{{|~€€€‚„………ƒƒƒ„„‚€€€€€€€}xvx}ƒ€{wy}‚……€|{|€}~€†ŠŠ…zz~ƒ††„ƒƒ~zx{€„„€{wy}€€{xy|€~|~‚‰‹…€{{€„‡†„‚{ww{€„ƒ€{x|€„„~||~€€~|~‚ˆŠˆ‚|xzƒ…„‚ƒ„„€|ww|€„‚{x{€‚‚€|z|€€~~€…Љ„~|}€„„ƒƒ„‚~wtuz€€}yy|€ƒ||€€||„‰‹‡€|{|€ƒ†ˆˆ‡„€}||~€€€~|yyz|€€€~|zyz}…‰Š‰…~|}€‚…ˆˆ†ƒ€|yy{}€€€~|zz|ƒ„‚€}{z{~…ˆ‰‡ƒ{yz~‚†ˆˆ†ƒ€}|{}€€€~{yyz}€€€€}|{}€ƒ‡‹‹‰…€}{|~…‡‡…~zxxz}€€€}{yy{}€‚ƒƒ|yz~‚‡ŠŠ‡ƒ€|{}€ƒ‡ŠŠˆ„€{yy}€‚‚€}ywwxz}€€€~{z{ƒˆŒŒŠ†€}|}‚…‡†„€{wvvz~€‚€|zz|€ƒ†‡†ƒ€}{|~‚†ˆˆ…€}zxz}€…‰‰†‚}yxz}€ƒƒ~{xwy{ƒƒ€|z}€…‰ŒŒ‰…€}|}~…††‚}xutvz}€€}{zz|‚…‡†„€}{}€„ˆŠ‰…~|{}€ƒ‡‰‰†‚~{{|€‚€}zxwx{~€€~{yy|€…ŠŒ‹†}yxz}€„††ƒ€|yxz}€€€}{{}€‚…ˆˆ†‚€~}‚†‰Šˆ‚~zwvx|€ƒ……‚€}{{}€€}{{|~€‚……ƒ€~||~…‡‡…‚{yyz}€ƒ†…ƒ€~||~€€€€~}{{{}€‚„…ƒ€~|}‚…‡‡†‚€|zyz~€„††„€~}~€‚‚€~||~€‚‚|zz|‚„„‚€|yxxy|€‚……ƒ€~||~€‚€~}~€‚„…„‚€~€ƒ†ˆˆ†‚|zy{~„……ƒ€€€€}zyxz|€ƒ††…‚€}||~€€€|zyxz~„†…‚€~€€|zzz}€…ˆŠˆ…~€‚ƒƒ‚€~|zz|ƒ†‡†ƒ€€€~|yxx|€ƒ†‡†ƒ€|{{}€~zww{~€€~}~„…ƒ€~‚ƒ‚zxy}‚„„ƒ‚ƒ…‡†ƒ€~€‚…„€|yz~‚‚€€ƒ……‚}ƒ~ywx}ƒ‚€€ƒ…ƒ€|{}€‚€}wuw|€€}}€ƒ…„€ƒ„}yw{€ƒ…ƒƒ†‡…€ƒ…ƒ{y|€€~„†„ƒƒ€{ww{€‚ƒ€€‚…„}z{~zvvy}€€~}‚…†ƒ€~…„€{wx{€ƒƒ‚…ˆ‡ƒ€}‚……}yy}€‚€€„†…}ƒ…„€yvxƒƒ€}{„ˆˆ{xzƒ‚}wuw}‚zy~„‰‰ƒ~{}‚…„xvz€„„~}‡‹‰ƒ~|ƒ†„yx|„ƒzz€†Šˆ‚~}€„†ƒ|ww|„ƒ{|€†‰†€zy}ƒ€zvv{€ƒ€|xz€†‰†€}}€„…€zvv|‚…‚~|~ƒ‰‹‡€}}†‡|xz„†|y|‚ˆŠ†€~ƒ††€yvx~ƒ„|z|††|yz‚}wuy„„€|z~ƒˆˆ„€~€„†ƒ}vtw~‚‚{z„ŠŠ…€…ˆ…€zy}‚†…€zy}‚‡†‚~}€„†„~wvz€„„€{{„†…€{z}‚€{uv{„ƒ{{€…‰‡~~€……€zuty€}z|‡Š‡‚€ƒ‡ˆ„~zzƒ…}z{€„†„€~‚††{wx}ƒ}z|††‚~{|€ƒ‚~xvx„†ƒ€~€ƒ‡‡ƒ}~‚…ƒyvx~~yx{†‡„€…‡…€zx|…„}|~ƒ†…}|ƒ‡…€|z~‚„ƒ~yy}‚‡†‚~€„†‚}wvz€ƒ‚~{{ƒ…‚~yy}‚„‚~yz~‚„}z|€‡‰ˆƒ€€ƒ††‚}xx}ƒ~|}…†ƒ~{|€„…‚~{|‚‚{xz„†„€~€ƒ…„€{xz~‚ƒ~|~‚…„€|z{€ƒƒ€|z|€‚~{z}‚‡‡„„†„€zxz~‚||ƒ…„€|{~‚……}{}€‚}z{„‡‡‚~|‚„‚{{ƒ†…~}‚€{xy}ƒ†…|{||z|€†ˆ†~}€„…‚~zz~‚…ƒ€}}‚{y{†‰‡‚}|~€|{}†‡„|}€„„}z{ƒ…ƒ€~~€‚}yx{ƒ……‚€}|{{{}€ƒ†‡…‚€~€ƒ„‚€~~€€€‚€|zz}€…‡†ƒ€~|{{|}€‚……ƒ€~}~€‚ƒ‚€€€€€€€€‚‚|zz}€ƒ„ƒ€}{{{|~€ƒ††„~€‚‚€€€€€€€€|z{…†„€~||||~€ƒ……‚€}}€‚‚€€€€€€€€€€~{z{~ƒ„‚€~|{{{}„†…ƒ€~~€ƒƒ€€€€€€€€€€}{z|‚„…ƒ€}|||}„…„‚€||}€ƒ……ƒ€~~€‚‚‚€}{yz}€„†…~zyy{~€ƒ………‚€}}~€ƒ„ƒ‚€~~~€€€€€}{z{~…‡†‚|z{}€ƒ…†„‚|{}€‚„„‚€€€€}zyz}„…„~{z{}ƒ…†…‚€}}~€ƒ„ƒ€~€€€€€€}{z{~„…„}{{|~€‚„…„‚€}}~€‚„ƒ‚€€€€€€€€}zyz}€ƒ„‚€~}|}~ƒ…†…‚€~}~€‚‚‚€~~~~~€€€€}{{|€‚…†„‚€~}|}~€‚„„ƒ€~}}€‚ƒƒ‚€€~€€€~|zz{~€‚ƒ‚€~|}~€‚…††„€~€‚‚€~}}}~€€€~|{{}€‚„„ƒ€~}}}„……ƒ€~€‚ƒ„ƒ‚€€€€€‚€|zz|~€€€€~}}€ƒ…†…‚}|}€‚‚€€}|}~€‚€~|}‚ƒƒ‚€~~„……„€~||}€‚‚‚€~}}€‚‚|||~€‚‚€~~~ƒ……ƒ€~||~€‚‚‚€~}~€‚‚€~|{}~€€~~~„……ƒ€~}}~€‚ƒ‚‚€~~€‚ƒ‚}|}€€€~}}ƒ„ƒ~|{|}€€€~}~€‚ƒ‚}}~€€‚‚€~€‚…†„‚}}}€‚‚‚€~~€‚ƒƒ‚€}{{|~€€€‚€€€€‚‚€}||}€€€€€€~€ƒƒ€~||}~€‚ƒ‚€€€€‚ƒƒ€~~€€‚‚€€‚ƒ‚€~||}~€€‚‚€€€‚€~}}}~€€€€~€‚‚‚€~}}}~€€‚‚ƒ‚€€€€€‚ƒƒ‚€€~~€‚‚€€€€‚‚€~}|}~€‚‚‚€€€€€~}|}}€€€€€€‚‚‚€~}|}~€‚ƒ‚‚€€€€‚‚‚‚€€~~~€‚‚€€€€‚‚‚€~}|}~€‚‚‚€€€€~}|}~€€€€€‚‚€}}}~€ƒƒ‚€€€€‚‚€~~~€‚€€€€€€€€€€~||~€‚‚€€€€€€€€€€€}||~€€€€€€€€€€€}|}€‚‚€€€€€‚‚€~}~€€€€€€€€€€‚€}|}‚€€€€€€€€~||}€€€€€€€€€€€‚€~|}~€€€€€€€€€€‚‚€~~€€€€€€€€€€‚€~}}~€€€€€€€€€€€€~}}€€€€€€€€€€€}||~€€€€€€€€‚‚‚€~~~€€€€€€€€€€€‚‚}}€‚€~€€~~€€€~}}€‚€€‚€€€~|}~€€~€‚ƒ‚€€€‚‚}~€‚€~~€‚€€‚‚€~}~€‚€~€‚‚€}~€€~}€‚‚~€‚‚€€‚}|}€€~‚‚€€€‚€~~‚‚€~€‚€€€‚ƒ€~}€€€‚‚€~€€€~~€€~~€€€€‚€}}€€€€‚ƒ€€€~~€‚€~~€€€€‚‚€}~€€€€€‚‚€~€€~€€~€€€‚€~}~€€€€‚‚€€€€~€€~€€€‚€~~€€€€€€~~€‚€€‚€~~€€€€‚€~}€€€€€€~~€‚€€€~€€€€€€‚‚€~€€€€€€~~€€€€€€~€€€€€€€~~€€€€€€€~€€€€€€€€€€€€‚€~€€€€€€~€€€€€€€€€€€€€€€~~€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€twinkle-1.4.2/depcomp0000755000175000001440000003710011151323411011456 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2005-07-09.11 # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mecanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: twinkle-1.4.2/twinkle.desktop.in0000644000175000001440000000034210651165510013564 00000000000000[Desktop Entry] Encoding=UTF-8 Name=Twinkle GenericName=A SIP softphone Comment=A SIP softphone Type=Application Exec=twinkle Icon=@datadir@/twinkle48.png StartupNotify=true Terminal=false Categories=Qt;KDE;Network;Telephony; twinkle-1.4.2/aclocal.m40000644000175000001440000011621011151323366011752 00000000000000# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. dnl Copyright (C) 2000-2003 Open Source Telecom Corporation. dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a configuration dnl script generated by Autoconf, you may include it under the same dnl distribution terms that you use for the rest of that program. dnl OST_CCXX2_VERSION([MINIMUM-VERSION[,ACTION-IF-FOUND[,ACTION-IF-NOT-FOUND]]]) dnl Test for usable version of CommonC++ AC_DEFUN([OST_CCXX2_DYNLOADER],[ ost_cv_dynloader=`$CCGNU2_CONFIG --dso` if test "$ost_cv_dynloader" = "yes" ; then MODULE_FLAGS=`$CCGNU2_CONFIG --module` AC_SUBST(MODULE_FLAGS) fi ]) AC_DEFUN([OST_CCXX2_LD_THREADING],[ LD_THREADING=`$CCGNU2_CONFIG --cclibs` AC_SUBST(LD_THREADING) ]) AC_DEFUN([OST_CCXX2_VERSION], [ if test -d ${exec_prefix}/bin ; then PATH=${exec_prefix}/bin:$PATH elif test -d ${prefix}/bin ; then PATH=${prefix}/bin:$PATH ; fi AC_PATH_PROG(CCGNU2_CONFIG, ccgnu2-config, no) ccgnu2_version=ifelse([$1], ,0.99.0,$1) AC_MSG_CHECKING(for commoncpp2 version >= $ccgnu2_version) if test "$CCGNU2_CONFIG" = "no" ; then AC_MSG_RESULT(not found) echo "*** The ccgnu2-config script installed by commoncpp2 0.99" echo "*** or later could not be found." echo "*** You need to install GNU Common C++ 2, whose later releases are" echo "*** available from http://www.gnu.org/software/commoncpp/ and any" echo "*** GNU mirror." ifelse([$3], , :, [$3]) exit -1 else config_version=`$CCGNU2_CONFIG --version` ccgnu2_config_major_version=`echo $config_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` ccgnu2_config_minor_version=`echo $config_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` ccgnu2_config_micro_version=`echo $config_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` ccgnu2_check_major_version=`echo "$ccgnu2_version" | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` ccgnu2_check_minor_version=`echo "$ccgnu2_version" | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` ccgnu2_check_micro_version=`echo "$ccgnu2_version" | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` version_ok=no if test $ccgnu2_config_major_version -gt $ccgnu2_check_major_version ; then version_ok=yes elif test $ccgnu2_config_major_version -eq $ccgnu2_check_major_version \ && test $ccgnu2_config_minor_version -gt $ccgnu2_check_minor_version ; then version_ok=yes elif test $ccgnu2_config_major_version -eq $ccgnu2_check_major_version \ && test $ccgnu2_config_minor_version -eq $ccgnu2_check_minor_version \ && test $ccgnu2_config_micro_version -ge $ccgnu2_check_micro_version; then version_ok=yes fi if test "$version_ok" = "no"; then AC_MSG_RESULT(no) ost_cv_ccxx_config=false echo "*** An old version of CommonC++ of $config_version was found." echo "*** You need a version of commoncpp2 newer than $ccgnu2_version. The latest version of" echo "*** CommonC++ is always available from ftp://ftp.gnu.org/gnu/commonc++/." ifelse([$3], , :, [$3]) else AC_MSG_RESULT(yes) ost_cv_ccxx_config=true SINGLE_FLAGS="$CXXFLAGS" SINGLE_LIBS="$LIBS" AC_SUBST(SINGLE_LIBS) AC_SUBST(SINGLE_FLAGS) CXXFLAGS="$CXXFLAGS "`$CCGNU2_CONFIG --flags` GNULIBS="$LIBS "`$CCGNU2_CONFIG --gnulibs` EXTLIBS=`$CCGNU2_CONFIG --extlibs` LIBS="$LIBS `$CCGNU2_CONFIG --stdlibs`" AC_SUBST(GNULIBS) AC_SUBST(EXTLIBS) fi fi ]) AC_DEFUN([OST_CCXX2_CHECK], [ if test -d ${exec_prefix}/bin ; then PATH=${exec_prefix}/bin:$PATH elif test -d ${prefix}/bin ; then PATH=${prefix}/bin:$PATH ; fi AC_PATH_PROG(CCGNU2_CONFIG, ccgnu2-config, no) ccgnu2_version=ifelse([$1], ,0.99.0,$1) AC_MSG_CHECKING(for commoncpp2 version >= $ccgnu2_version) if test "$CCGNU2_CONFIG" = "no" ; then AC_MSG_RESULT(not found) echo "*** The ccgnu2-config script installed by commoncpp2 0.99" echo "*** or later could not be found." echo "*** You need to install GNU Common C++ 2, whose later releases are" echo "*** available from http://www.gnu.org/software/commoncpp/ and any" echo "*** GNU mirror." ifelse([$3], , :, [$3]) exit -1 else config_version=`$CCGNU2_CONFIG --version` ccgnu2_config_major_version=`echo $config_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` ccgnu2_config_minor_version=`echo $config_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` ccgnu2_config_micro_version=`echo $config_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` ccgnu2_check_major_version=`echo "$ccgnu2_version" | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` ccgnu2_check_minor_version=`echo "$ccgnu2_version" | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` ccgnu2_check_micro_version=`echo "$ccgnu2_version" | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` version_ok=no if test $ccgnu2_config_major_version -gt $ccgnu2_check_major_version ; then version_ok=yes elif test $ccgnu2_config_major_version -eq $ccgnu2_check_major_version \ && test $ccgnu2_config_minor_version -gt $ccgnu2_check_minor_version ; then version_ok=yes elif test $ccgnu2_config_major_version -eq $ccgnu2_check_major_version \ && test $ccgnu2_config_minor_version -eq $ccgnu2_check_minor_version \ && test $ccgnu2_config_micro_version -ge $ccgnu2_check_micro_version; then version_ok=yes fi if test "$version_ok" = "no"; then AC_MSG_RESULT(no) ost_cv_ccxx_config=false echo "*** An old version of CommonC++ of $config_version was found." echo "*** You need a version of commoncpp2 newer than $ccgnu2_version. The latest version of" echo "*** CommonC++ is always available from ftp://ftp.gnu.org/gnu/commonc++/." ifelse([$3], , :, [$3]) else AC_MSG_RESULT(yes) ost_cv_ccxx_config=true CCFLAGS2=`$CCGNU2_CONFIG --flags` LDCCGNU2=`$CCGNU2_CONFIG --gnulibs` LDCCEXT2=`$CCGNU2_CONFIG --stdlibs` AC_SUBST(LDCCGNU2) AC_SUBST(LDCCEXT2) AC_SUBST(CCFLAGS2) fi fi ]) AC_DEFUN([OST_CCXX2_FOX],[ AC_LANG_SAVE AC_LANG_CPLUSPLUS ost_cv_lib_fox=false AC_CHECK_HEADERS(fox/fx.h,[ AC_DEFINE(HAVE_FOX_FX_H) ost_cv_lib_fox=true]) AC_LANG_RESTORE ]) dnl OST_CCXX2_XML([ACTION-IF-TRUE[,ACTION-IF-FALSE]]) AC_DEFUN([OST_CCXX2_HOARD],[ AC_ARG_ENABLE(hoard, [--disable-hoard Disable hoard support]) AC_ARG_ENABLE(mpatrol, [--enable-mpatrol Enable mpatrol debugging]) if test "$enable_mpatrol" = "yes" ; then LIBS="$LIBS -lmpatrolmt -lbfd -liberty" elif test "$enable_hoard" != "no" ; then AC_CHECK_LIB(hoard, free, [LIBS="$LIBS -lhoard"]) fi ]) AC_DEFUN([OST_CCXX2_XML], [ AC_MSG_CHECKING(for commoncpp2 xml parsing) AC_LANG_PUSH(C++) AC_REQUIRE_CPP AC_TRY_RUN([ #include #ifndef COMMON_XML_PARSING #error "" #endif int main() { return 0; } ], ost_cv_ccxx_xml=yes, ost_cv_ccxx_xml=no) AC_LANG_POP(C++) if test "x$ost_cv_ccxx_xml" = "xyes" ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_OST_CCXX2_XML_PARSING, 1, [Define this if the CommonC++ library was compiled with XML parsing support]) ifelse([$1], , :, [$1]) else AC_MSG_RESULT(no) ifelse([$2], , :, [$2]) fi ]) dnl ACCONFIG TEMPLATE dnl #undef CCXX_CONFIG_H_ dnl #undef HAVE_FOX_FX_H dnl END ACCONFIG # Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 12 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/vl_lib_readline.m4]) m4_include([acinclude.m4]) twinkle-1.4.2/README0000644000175000001440000002214310507757120010776 00000000000000Twinkle is a SIP based VoIP client. Release 0.5 notes ----------------- In this release the SIP UDP port and RTP port settings have been moved from the user profile to the system settings. If you made any changes to the default port values in your user profiles, then these changes will be lost. Library requirements -------------------- To compile Twinkle you need the following libraries: libccext2 (version >= 1.4.2) [GNU Common C++] libccgnu2 (version >= 1.4.2) [GNU Common C++] http://www.gnu.org/software/commoncpp/ libccrtp1 (version >= 1.5.0) [GNU RTP Stack] libzrtpcpp (version >= 0.9.0) [Extension library of GNU ccRTP] http://www.gnu.org/software/ccrtp/ libqt-mt (version >= 3.3.0) [Qt library with threading support] http://www.trolltech.com/ For the Qt environment the $QTDIR variable must be set correctly Shared user data ---------------- Installation will create the following directory for shared user data on your system: $(pkgdatadir)/twinkle Typical value for pkgdatadir is: /usr/local/share or /opt/kde3/share Application icon ---------------- If you want to create an application link on your desktop you can find an application icon in the shared user data directory: twinkle16.png 16x16 icon twinkle32.png 32x32 icon twinkle48.png 48x48 icon User data --------- On first run Twinkle will create the directory ".twinkle" in your home directory. In this directory all user data will be put: user profiles (.cfg) log files (.log) system settings (twinkle.sys) call history (twinkle.ch) lock file (twinkle.lck) Starting Twinkle ---------------- Give the command: twinkle 'twinkle -h' will show you some command line options you may use. NOTE: the CLI option is not fool proof. A command given at a wrong time may crash the program. It is recommended to use the GUI. If you do not specify a configuration file (-f ) on the command line, then Twinkle will look for configuration files in your .twinkle directory. If you do not have any configuration file, the configuration file editor will startup so you can create one. If you have configuration files, then Twinkle lets you select an existing configuration file. See below for some hints on settings to be made with the profile configuration editor. If you specify a configuration file name, then Twinkle will such for this configuration file in your .twinkle directory. If you have put your configuration file in another location you have to specify the full path name for the file, i.e. starting with a slash. NOTE: the configuration file editor only exists in the GUI. If you run the CLI mode, you must have a configuration file. So first create a configuration file in GUI mode or hand edit a configuration file, before running the CLI mode. If you run the CLI mode and you do not specify a file name on the command line, then Twinkle will use twinkle.cfg NAT --- If there is a NAT between you and your SIP server then you have 3 options to make things work: 1) Your SIP provider uses a Session Border Controller 2) Your SIP provider offers a STUN server 3) Make static address mappings in your NAT for SIP and RTP STUN can be enabled in the NAT section of the user profile. For the static address mappings enable the following in the NAT section of the user profile: Use statically configured public IP address inside SIP messages And fill in the public IP address of your NAT. Twinkle will then use this IP address inside SIP headers and SDP bodies instead of the private IP address of your machine. In addition you have to add the following port forwardings for UDP on your NAT public:5060 --> private:5060 (for SIP signaling) public:8000 --> private:8000 (for RTP on line 1) public:8001 --> private:8001 (for RTCP on line 1) public:8002 --> private:8002 (for RTP on line 2) public:8003 --> private:8003 (for RTCP on line 2) public:8004 --> private:8004 (for RTP for call transfer) public:8005 --> private:8005 (for RTCP for call transfer) If you have changed the SIP/RTP ports in your profile you have to change the port forwarding rules likewise. Log files --------- During execution Twinkle will create the following log files in your .twinkle directory: twinkle.log This is the latest log file twinkle.log.old This is the previous log file When twinkle.log is full (default is 5 MB) then it is moved to twinkle.log.old and a new twinkle.log is created. On startup an existing twinkle.log is moved to twinkle.log.old and a new twinkle.log is created. User profile configuration -------------------------- A user profile contains information about your user account, SIP proxy, and several SIP protocol options. If you use Twinkle with different user accounts you may create multiple user profiles. When you create a new profile you first give it a name and then you can make the appropriate settings. The name of the profile is what later on appears in the selection box when you start Twinkle again. Or you can give the name.cfg at the command line (-f option) to immediately start that profile. The user profile is stored as '.cfg' in the .twinkle directory where is the name you gave to the profile. At a minumimum you have to specify the following: User name: this is your SIP user name (eg. phone number) Domain: the domain of your provider (eg. fwd.pulver.com) this could also be the IP address of your SIP proxy if you want to do IP-to-IP dialing (without proxy) then fill in the IP address or FQDN of your computer. If your SIP proxy does not request authentication and the value you filled in for 'Domain' can be resolved to an IP address by Twinkle, eg. it is an IP address or an FQDN that is in an A-record of the DNS, then you are ready now. NOTE: Twinkle does not support DNS SRV records yet. Authentication -------------- If your proxy needs authentication, then specify the following fields in the SIP authentication box: Realm: the realm for authentication you might leave the realm empty. If you do so, then Twinkle will use the name and password regardless of the realm put in the challenge by the proxy. For most network setups this is fine. You only need to explicitly specify a realm when you have call scenario's where you have to access multiple realms. Then for the realms not known to Twinkle you will be requested for a login when needed. Name: your authentication name Password: your authentication password If authentication fails during registration or any other SIP request because you filled in wrong values, then Twinkle will at that time interactively request your login and cache it. Outbound proxy -------------- An outbound proxy is only needed if the domain value cannot be resolved to an IP address by Twinkle or because your provider demands you to use an outbound proxy that is at a different IP address. Check the 'use outbound proxy' check box in the SIP server section. For outbound proxy fill in an IP address or an FQDN that can be resolved to an IP address via DNS. By default only out-of-dialog requests (eg. REGISTER, OPTIONS, initial INVITE) are sent to the outbound proxy. In-dialog requests (eg. re-INVITE, BYE) are sent to the target indicated by the far end during call setup. By checking 'send in-dialog requests to proxy' Twinkle will ignore this target and send these requests also to the proxy. Normally you would not need this. It could be useful in a scenario where the far-end indicates a target that cannot be resolved to an IP address. By checking "Do not send a request to proxy if its destination can be resolved locally" will make Twinkle always first try to figure out the destination IP address itself, i.e. based on the request-URI and Route-headers. Only when that fails the outbound-proxy will be tried, but only for the options checked above. I.e. if you did not check the 'in-dialog' option, then an in-dialog request will never go to the proxy. If its destination cannot be resolved, then the request will simply fail. Registrar --------- By default a REGISTER will be send to the IP address resolved from the domain value or to the outbound proxy if specified. If your service provider has a dedicated registrar which is different from these IP addresses, then you can specify the IP or FQDN of the registrar in the registrar-field. The 'expiry' value is the expiry of your registration. Just before the registration expires Twinkle will automatically refresh the registration. The expiry time may be overruled by the registrar. The 'registrar at startup option' will make Twinkle automatically send a REGISTER on startup of the profile. Addressing ---------- When you invite someone to a call you have to enter an an address. A SIP address has the following form: sip:@ Where 'user' is a user name or a phone number and 'host-part' is a domain name, FQDN or IP address The only mandatory part for you to enter is the . Twinkle will fill in the other parts if you do not provide them. For the host-part, Twinkle will fill in the value you configured as your 'domain'. Currently "sip:" is the only addressing scheme supported by Twinkle. January 2006 Michel de Boer michel@twinklephone.com twinkle-1.4.2/THANKS0000644000175000001440000000066310650327034011030 00000000000000Thanks to the following people for testing and finding all those lovely bugs: Richard Bos Schelte Bron Ruud Linders John van der Ploeg Marco van Zijl Thanks to Richard Bos for RPM building and advertising. Thanks to Joerg Reisenweber for his excellent testing and debugging. Thanks to Treeve Jelbert for helping me catching build errors in release 0.4 Thanks to James Le Cuirot for helping me debug several ALSA and RTP problems. twinkle-1.4.2/configure0000755000175000001440000242022411151323376012027 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.60. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # Find out whether ``test -x'' works. Don't use a zero-byte file, as # systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then as_executable_p="test -x" else as_executable_p=: fi rm -f conf$$.file # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="src/phone.h" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #endif #if HAVE_STDINT_H # include #endif #if HAVE_UNISTD_H # include #endif" ac_default_prefix=${KDEDIR:-the kde prefix} ac_default_prefix=${prefix:-/usr/local} ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CPP CXXCPP RANLIB LEX LEXLIB LEX_OUTPUT_ROOT YACC YFLAGS GREP EGREP CCGNU2_CONFIG SINGLE_LIBS SINGLE_FLAGS GNULIBS EXTLIBS PKG_CONFIG CCRTP_CFLAGS CCRTP_LIBS XML2_CFLAGS XML2_LIBS QT_CFLAGS QT_LIBS LIBUTIL LIBCOMPAT LIBCRYPT LIBRESOLV LIB_POLL FRAMEWORK_COREAUDIO LIBSOCKET X_EXTRA_LIBS LIBUCB LIBDL include_x11_TRUE include_x11_FALSE XMKMF X_PRE_LIBS LIB_X11 LIB_XRENDER LIBSM X_INCLUDES X_LDFLAGS x_includes x_libraries QTE_NORTTI LIB_XEXT LIBPTHREAD USE_THREADS KDE_MT_LDFLAGS KDE_MT_LIBS USER_INCLUDES USER_LDFLAGS LIBZ LIBPNG LIBJPEG qt_libraries qt_includes QT_INCLUDES QT_LDFLAGS PERL MOC UIC UIC_TR LIB_QT LIB_QPE kde_qtver have_lrelease have_kde KDECONFIG kde_libs_prefix kde_libs_htmldir CONF_FILES KDE_EXTRA_RPATH KDE_RPATH X_RPATH kde_libraries kde_includes KDE_LDFLAGS KDE_INCLUDES all_includes all_libraries AUTODIRS include_ARTS_TRUE include_ARTS_FALSE MAKEKDEWIDGETS KCONFIG_COMPILER KCFG_DEPENDENCIES DCOPIDLNG DCOPIDL DCOPIDL2CPP DCOP_DEPENDENCIES MCOPIDL ARTSCCONFIG MEINPROC KDE_XSL_STYLESHEET XMLLINT kde_htmldir kde_appsdir kde_icondir kde_sounddir kde_datadir kde_locale kde_confdir kde_kcfgdir kde_mimedir kde_wallpaperdir kde_bindir xdg_appsdir xdg_menudir xdg_directorydir kde_templatesdir kde_servicesdir kde_servicetypesdir kde_moduledir kdeinitdir kde_styledir kde_widgetdir LIB_KDECORE LIB_KDEUI LIB_KIO LIB_KJS LIB_SMB LIB_KAB LIB_KABC LIB_KHTML LIB_KSPELL LIB_KPARTS LIB_KDEPRINT LIB_KUTILS LIB_KDEPIM LIB_KIMPROXY LIB_KNEWSTUFF LIB_KDNSSD LIB_KSYCOCA LIB_KFILE LIB_KFM GSM_LIBS ZRTP_CFLAGS ZRTP_LIBS LRELEASEOPTION LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS CPPFLAGS CXX CXXFLAGS CCC CPP CXXCPP YACC YFLAGS XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-qt-check do not check Qt installation --enable-ilbc-cpp your ilbc library is built for C++ instead of C --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-libsuffix /lib directory suffix (64,32,none=default) --enable-embedded link to Qt-embedded, don't use X --enable-qtopia link to Qt-embedded, link to the Qtopia Environment --enable-mac link to Qt/Mac (don't use X) --disable-mt link to non-threaded Qt (deprecated) --disable-threading disables threading even if libpthread found --disable-fast-perl disable fast Makefile generation (needs perl) --disable-rpath do not use the rpath feature of ld --disable-path-check don't try to find out, where to install Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-kde do not compile KDE features --without-ilbc do not compile iLBC --without-speex do not compile speex --without-zrtp do not compile zrtp support --with-extra-includes=DIR adds non standard include paths --with-extra-libs=DIR adds non standard library paths --with-qt-dir=DIR where the root of Qt is installed --with-qt-includes=DIR where the Qt includes are. --with-qt-libraries=DIR where the Qt library is installed. --without-arts build without aRts default=no Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP C++ preprocessor YACC The `Yet Another C Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.60 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.60. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking target system type" >&5 echo $ECHO_N "checking target system type... $ECHO_C" >&6; } if test "${ac_cv_target+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_target" >&5 echo "${ECHO_T}$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- ac_config_headers="$ac_config_headers src/twinkle_config.h" # Check whether --enable-qt-check was given. if test "${enable_qt_check+set}" = set; then enableval=$enable_qt_check; ac_cv_qt_check=$enableval else ac_cv_qt_check=yes fi # Check whether --with-kde was given. if test "${with_kde+set}" = set; then withval=$with_kde; ac_cv_kde=$withval else ac_cv_kde=yes fi # Check whether --with-ilbc was given. if test "${with_ilbc+set}" = set; then withval=$with_ilbc; ac_cv_ilbc=$withval else ac_cv_ilbc=yes fi # Check whether --with-speex was given. if test "${with_speex+set}" = set; then withval=$with_speex; ac_cv_speex=$withval else ac_cv_speex=yes fi # Check whether --with-zrtp was given. if test "${with_zrtp+set}" = set; then withval=$with_zrtp; ac_cv_zrtp=$withval else ac_cv_zrtp=yes fi # Check whether --enable-ilbc-cpp was given. if test "${enable_ilbc_cpp+set}" = set; then enableval=$enable_ilbc_cpp; ac_cv_ilbc_cpp=$enableval else ac_cv_ilbc_cpp=no fi am__api_version="1.9" test -n "$INSTALL" && kde_save_INSTALL_given=$INSTALL test -n "$INSTALL_PROGRAM" && kde_save_INSTALL_PROGRAM_given=$INSTALL_PROGRAM test -n "$INSTALL_SCRIPT" && kde_save_INSTALL_SCRIPT_given=$INSTALL_SCRIPT # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' if test -z "$kde_save_INSTALL_given" ; then # OK, user hasn't given any INSTALL, autoconf found one for us # now we test, if it supports the -p flag { echo "$as_me:$LINENO: checking for -p flag to install" >&5 echo $ECHO_N "checking for -p flag to install... $ECHO_C" >&6; } rm -f confinst.$$.* > /dev/null 2>&1 echo "Testtest" > confinst.$$.orig ac_res=no if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then if test -f confinst.$$.new ; then # OK, -p seems to do no harm to install INSTALL="${INSTALL} -p" ac_res=yes fi fi rm -f confinst.$$.* { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test -z "$kde_save_INSTALL_PROGRAM_given" ; then INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)' fi if test -z "$kde_save_INSTALL_SCRIPT_given" ; then INSTALL_SCRIPT='${INSTALL}' fi { echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=twinkle VERSION="1.4.2" cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' cat >>confdefs.h <<\_ACEOF #define VERSION_DATE "February 25 2009" _ACEOF ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_LEX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LEX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { echo "$as_me:$LINENO: result: $LEX" >&5 echo "${ECHO_T}$LEX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test -z "$LEXLIB" then { echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6; } if test "${ac_cv_lib_fl_yywrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yywrap (); int main () { return yywrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_fl_yywrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_fl_yywrap=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6; } if test $ac_cv_lib_fl_yywrap = yes; then LEXLIB="-lfl" else { echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6; } if test "${ac_cv_lib_l_yywrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ll $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yywrap (); int main () { return yywrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_l_yywrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_l_yywrap=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6; } if test $ac_cv_lib_l_yywrap = yes; then LEXLIB="-ll" fi fi fi if test "x$LEX" != "x:"; then { echo "$as_me:$LINENO: checking lex output file root" >&5 echo $ECHO_N "checking lex output file root... $ECHO_C" >&6; } if test "${ac_cv_prog_lex_root+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # The minimal lex program is just a single line: %%. But some broken lexes # (Solaris, I think it was) want two %% lines, so accommodate them. cat >conftest.l <<_ACEOF %% %% _ACEOF { (ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 echo "${ECHO_T}$ac_cv_prog_lex_root" >&6; } rm -f conftest.l LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root { echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6; } if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS=$LIBS LIBS="$LIBS $LEXLIB" cat >conftest.$ac_ext <<_ACEOF `cat $LEX_OUTPUT_ROOT.c` _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_lex_yytext_pointer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS rm -f "${LEX_OUTPUT_ROOT}.c" fi { echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then cat >>confdefs.h <<\_ACEOF #define YYTEXT_POINTER 1 _ACEOF fi fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_YACC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_YACC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { echo "$as_me:$LINENO: result: $YACC" >&5 echo "${ECHO_T}$YACC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { echo "$as_me:$LINENO: checking whether strerror_r is declared" >&5 echo $ECHO_N "checking whether strerror_r is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_strerror_r+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef strerror_r char *p = (char *) strerror_r; return !p; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_have_decl_strerror_r=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_strerror_r=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_strerror_r" >&5 echo "${ECHO_T}$ac_cv_have_decl_strerror_r" >&6; } if test $ac_cv_have_decl_strerror_r = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR_R 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR_R 0 _ACEOF fi for ac_func in strerror_r do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether strerror_r returns char *" >&5 echo $ECHO_N "checking whether strerror_r returns char *... $ECHO_C" >&6; } if test "${ac_cv_func_strerror_r_char_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_func_strerror_r_char_p=no if test $ac_cv_have_decl_strerror_r = yes; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); char *p = strerror_r (0, buf, sizeof buf); return !p || x; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_strerror_r_char_p=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else # strerror_r is not declared. Choose between # systems that have relatively inaccessible declarations for the # function. BeOS and DEC UNIX 4.0 fall in this category, but the # former has a strerror_r that returns char*, while the latter # has a strerror_r that returns `int'. # This test should segfault on the DEC system. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default extern char *strerror_r (); int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); return ! isalpha (x); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_strerror_r_char_p=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_func_strerror_r_char_p" >&5 echo "${ECHO_T}$ac_cv_func_strerror_r_char_p" >&6; } if test $ac_cv_func_strerror_r_char_p = yes; then cat >>confdefs.h <<\_ACEOF #define STRERROR_R_CHAR_P 1 _ACEOF fi for ac_header in linux/types.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in linux/errqueue.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if HAVE_LINUX_TYPES_H #include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Check version of the Common C++ library. # This also sets the cc++2 include directory in CXXFLAGS if test -d ${exec_prefix}/bin ; then PATH=${exec_prefix}/bin:$PATH elif test -d ${prefix}/bin ; then PATH=${prefix}/bin:$PATH ; fi # Extract the first word of "ccgnu2-config", so it can be a program name with args. set dummy ccgnu2-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_CCGNU2_CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $CCGNU2_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_CCGNU2_CONFIG="$CCGNU2_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CCGNU2_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CCGNU2_CONFIG" && ac_cv_path_CCGNU2_CONFIG="no" ;; esac fi CCGNU2_CONFIG=$ac_cv_path_CCGNU2_CONFIG if test -n "$CCGNU2_CONFIG"; then { echo "$as_me:$LINENO: result: $CCGNU2_CONFIG" >&5 echo "${ECHO_T}$CCGNU2_CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi ccgnu2_version=1.6.0 { echo "$as_me:$LINENO: checking for commoncpp2 version >= $ccgnu2_version" >&5 echo $ECHO_N "checking for commoncpp2 version >= $ccgnu2_version... $ECHO_C" >&6; } if test "$CCGNU2_CONFIG" = "no" ; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } echo "*** The ccgnu2-config script installed by commoncpp2 0.99" echo "*** or later could not be found." echo "*** You need to install GNU Common C++ 2, whose later releases are" echo "*** available from http://www.gnu.org/software/commoncpp/ and any" echo "*** GNU mirror." exit exit -1 else config_version=`$CCGNU2_CONFIG --version` ccgnu2_config_major_version=`echo $config_version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` ccgnu2_config_minor_version=`echo $config_version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` ccgnu2_config_micro_version=`echo $config_version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` ccgnu2_check_major_version=`echo "$ccgnu2_version" | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` ccgnu2_check_minor_version=`echo "$ccgnu2_version" | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` ccgnu2_check_micro_version=`echo "$ccgnu2_version" | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` version_ok=no if test $ccgnu2_config_major_version -gt $ccgnu2_check_major_version ; then version_ok=yes elif test $ccgnu2_config_major_version -eq $ccgnu2_check_major_version \ && test $ccgnu2_config_minor_version -gt $ccgnu2_check_minor_version ; then version_ok=yes elif test $ccgnu2_config_major_version -eq $ccgnu2_check_major_version \ && test $ccgnu2_config_minor_version -eq $ccgnu2_check_minor_version \ && test $ccgnu2_config_micro_version -ge $ccgnu2_check_micro_version; then version_ok=yes fi if test "$version_ok" = "no"; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } ost_cv_ccxx_config=false echo "*** An old version of CommonC++ of $config_version was found." echo "*** You need a version of commoncpp2 newer than $ccgnu2_version. The latest version of" echo "*** CommonC++ is always available from ftp://ftp.gnu.org/gnu/commonc++/." exit else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } ost_cv_ccxx_config=true SINGLE_FLAGS="$CXXFLAGS" SINGLE_LIBS="$LIBS" CXXFLAGS="$CXXFLAGS "`$CCGNU2_CONFIG --flags` GNULIBS="$LIBS "`$CCGNU2_CONFIG --gnulibs` EXTLIBS=`$CCGNU2_CONFIG --extlibs` LIBS="$LIBS `$CCGNU2_CONFIG --stdlibs`" fi fi # Temporarily add some default directories to PKG_CONFIG_PATH such that # the user will not be burdened with setting PKG_CONFIG_PATH OLD_PKG_CONFIG_PATH=$PKG_CONFIG_PATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig if test "x${prefix}" != "xNONE" then PKG_CONFIG_PATH=$PKG_CONFIG_PATH:${prefix}/lib/pkgconfig fi if test -n "$QTDIR" then PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$QTDIR/lib/pkgconfig fi export PKG_CONFIG_PATH succeeded=no if test -z "$PKG_CONFIG"; then # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 echo "${ECHO_T}$PKG_CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test "$PKG_CONFIG" = "no" ; then echo "*** The pkg-config script could not be found. Make sure it is" echo "*** in your path, or set the PKG_CONFIG environment variable" echo "*** to the full path to pkg-config." echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." else PKG_CONFIG_MIN_VERSION=0.9.0 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then { echo "$as_me:$LINENO: checking for libccrtp1 >= 1.6.0" >&5 echo $ECHO_N "checking for libccrtp1 >= 1.6.0... $ECHO_C" >&6; } if $PKG_CONFIG --exists "libccrtp1 >= 1.6.0" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } succeeded=yes { echo "$as_me:$LINENO: checking CCRTP_CFLAGS" >&5 echo $ECHO_N "checking CCRTP_CFLAGS... $ECHO_C" >&6; } CCRTP_CFLAGS=`$PKG_CONFIG --cflags "libccrtp1 >= 1.6.0"` { echo "$as_me:$LINENO: result: $CCRTP_CFLAGS" >&5 echo "${ECHO_T}$CCRTP_CFLAGS" >&6; } { echo "$as_me:$LINENO: checking CCRTP_LIBS" >&5 echo $ECHO_N "checking CCRTP_LIBS... $ECHO_C" >&6; } CCRTP_LIBS=`$PKG_CONFIG --libs "libccrtp1 >= 1.6.0"` { echo "$as_me:$LINENO: result: $CCRTP_LIBS" >&5 echo "${ECHO_T}$CCRTP_LIBS" >&6; } else CCRTP_CFLAGS="" CCRTP_LIBS="" ## If we have a custom action on failure, don't print errors, but ## do set a variable so people can do so. CCRTP_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libccrtp1 >= 1.6.0"` echo $CCRTP_PKG_ERRORS fi else echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." echo "*** See http://www.freedesktop.org/software/pkgconfig" fi fi if test $succeeded = yes; then : else { { echo "$as_me:$LINENO: error: Library requirements (libccrtp1 >= 1.6.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 echo "$as_me: error: Library requirements (libccrtp1 >= 1.6.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} { (exit 1); exit 1; }; } fi succeeded=no if test -z "$PKG_CONFIG"; then # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 echo "${ECHO_T}$PKG_CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test "$PKG_CONFIG" = "no" ; then echo "*** The pkg-config script could not be found. Make sure it is" echo "*** in your path, or set the PKG_CONFIG environment variable" echo "*** to the full path to pkg-config." echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." else PKG_CONFIG_MIN_VERSION=0.9.0 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then { echo "$as_me:$LINENO: checking for libxml-2.0" >&5 echo $ECHO_N "checking for libxml-2.0... $ECHO_C" >&6; } if $PKG_CONFIG --exists "libxml-2.0" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } succeeded=yes { echo "$as_me:$LINENO: checking XML2_CFLAGS" >&5 echo $ECHO_N "checking XML2_CFLAGS... $ECHO_C" >&6; } XML2_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0"` { echo "$as_me:$LINENO: result: $XML2_CFLAGS" >&5 echo "${ECHO_T}$XML2_CFLAGS" >&6; } { echo "$as_me:$LINENO: checking XML2_LIBS" >&5 echo $ECHO_N "checking XML2_LIBS... $ECHO_C" >&6; } XML2_LIBS=`$PKG_CONFIG --libs "libxml-2.0"` { echo "$as_me:$LINENO: result: $XML2_LIBS" >&5 echo "${ECHO_T}$XML2_LIBS" >&6; } else XML2_CFLAGS="" XML2_LIBS="" ## If we have a custom action on failure, don't print errors, but ## do set a variable so people can do so. XML2_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libxml-2.0"` echo $XML2_PKG_ERRORS fi else echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." echo "*** See http://www.freedesktop.org/software/pkgconfig" fi fi if test $succeeded = yes; then : else { { echo "$as_me:$LINENO: error: Library requirements (libxml-2.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 echo "$as_me: error: Library requirements (libxml-2.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} { (exit 1); exit 1; }; } fi # AC_CHECK_HEADER(libxml/tree.h, [], # [AC_MSG_ERROR([libxml2 header files missing (libxml2-devel package)])]) if test "x$ac_cv_qt_check" = "xyes" then succeeded=no if test -z "$PKG_CONFIG"; then # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 echo "${ECHO_T}$PKG_CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test "$PKG_CONFIG" = "no" ; then echo "*** The pkg-config script could not be found. Make sure it is" echo "*** in your path, or set the PKG_CONFIG environment variable" echo "*** to the full path to pkg-config." echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." else PKG_CONFIG_MIN_VERSION=0.9.0 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then { echo "$as_me:$LINENO: checking for qt-mt >= 3.3.0 qt-mt < 4.0" >&5 echo $ECHO_N "checking for qt-mt >= 3.3.0 qt-mt < 4.0... $ECHO_C" >&6; } if $PKG_CONFIG --exists "qt-mt >= 3.3.0 qt-mt < 4.0" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } succeeded=yes { echo "$as_me:$LINENO: checking QT_CFLAGS" >&5 echo $ECHO_N "checking QT_CFLAGS... $ECHO_C" >&6; } QT_CFLAGS=`$PKG_CONFIG --cflags "qt-mt >= 3.3.0 qt-mt < 4.0"` { echo "$as_me:$LINENO: result: $QT_CFLAGS" >&5 echo "${ECHO_T}$QT_CFLAGS" >&6; } { echo "$as_me:$LINENO: checking QT_LIBS" >&5 echo $ECHO_N "checking QT_LIBS... $ECHO_C" >&6; } QT_LIBS=`$PKG_CONFIG --libs "qt-mt >= 3.3.0 qt-mt < 4.0"` { echo "$as_me:$LINENO: result: $QT_LIBS" >&5 echo "${ECHO_T}$QT_LIBS" >&6; } else QT_CFLAGS="" QT_LIBS="" ## If we have a custom action on failure, don't print errors, but ## do set a variable so people can do so. QT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "qt-mt >= 3.3.0 qt-mt < 4.0"` echo $QT_PKG_ERRORS fi else echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." echo "*** See http://www.freedesktop.org/software/pkgconfig" fi fi if test $succeeded = yes; then : else { { echo "$as_me:$LINENO: error: Library requirements (qt-mt >= 3.3.0 qt-mt < 4.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 echo "$as_me: error: Library requirements (qt-mt >= 3.3.0 qt-mt < 4.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} { (exit 1); exit 1; }; } fi fi # Restore the original value of PKG_CONFIG_PATH PKG_CONFIG_PATH=$OLD_PKG_CONFIG_PATH export PKG_CONFIG_PATH # Check if QTDIR variable is set { echo "$as_me:$LINENO: checking value of \$QTDIR" >&5 echo $ECHO_N "checking value of \$QTDIR... $ECHO_C" >&6; } if test -n "$QTDIR" then { echo "$as_me:$LINENO: result: $QTDIR" >&5 echo "${ECHO_T}$QTDIR" >&6; } else { echo "$as_me:$LINENO: result: not set" >&5 echo "${ECHO_T}not set" >&6; } { { echo "$as_me:$LINENO: error: Set \$QTDIR to the Qt directory, eg. /usr/lib/qt3" >&5 echo "$as_me: error: Set \$QTDIR to the Qt directory, eg. /usr/lib/qt3" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for qmake" >&5 echo $ECHO_N "checking for qmake... $ECHO_C" >&6; } if test -x $QTDIR/bin/qmake then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: Cannot find qmake in \$QTDIR/bin. \$QTDIR is incorrect." >&5 echo "$as_me: error: Cannot find qmake in \$QTDIR/bin. \$QTDIR is incorrect." >&2;} { (exit 1); exit 1; }; } fi # Without this macro, compiling on non-kde systems does not work { echo "$as_me:$LINENO: checking for strlcat" >&5 echo $ECHO_N "checking for strlcat... $ECHO_C" >&6; } if test "${kde_cv_func_strlcat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' save_CXXFLAGS="$CXXFLAGS" kde_safe_LIBS="$LIBS" LIBS="$LIBS $X_EXTRA_LIBS" if test "$GXX" = "yes"; then CXXFLAGS="$CXXFLAGS -pedantic-errors" fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char buf[20]; buf[0]='\0'; strlcat(buf, "KDE function test", sizeof(buf)); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_func_strlcat=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_func_strlcat=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS="$save_CXXFLAGS" LIBS="$kde_safe_LIBS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { echo "$as_me:$LINENO: result: $kde_cv_func_strlcat" >&5 echo "${ECHO_T}$kde_cv_func_strlcat" >&6; } { echo "$as_me:$LINENO: checking if strlcat needs custom prototype" >&5 echo $ECHO_N "checking if strlcat needs custom prototype... $ECHO_C" >&6; } if test "${kde_cv_proto_strlcat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$kde_cv_func_strlcat" = xyes; then kde_cv_proto_strlcat=no else case "strlcat" in setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat) kde_cv_proto_strlcat="yes - in libkdefakes" ;; *) kde_cv_proto_strlcat=unknown ;; esac fi if test "x$kde_cv_proto_strlcat" = xunknown; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' kde_safe_libs=$LIBS LIBS="$LIBS $X_EXTRA_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include extern "C" unsigned long strlcat(char*, const char*, unsigned long); int main () { char buf[20]; buf[0]='\0'; strlcat(buf, "KDE function test", sizeof(buf)); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_func_strlcat=yes kde_cv_proto_strlcat=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_proto_strlcat="strlcat unavailable" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$kde_safe_libs ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi fi { echo "$as_me:$LINENO: result: $kde_cv_proto_strlcat" >&5 echo "${ECHO_T}$kde_cv_proto_strlcat" >&6; } if test "x$kde_cv_func_strlcat" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRLCAT 1 _ACEOF fi if test "x$kde_cv_proto_strlcat" = xno; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRLCAT_PROTO 1 _ACEOF fi { echo "$as_me:$LINENO: checking for strlcpy" >&5 echo $ECHO_N "checking for strlcpy... $ECHO_C" >&6; } if test "${kde_cv_func_strlcpy+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' save_CXXFLAGS="$CXXFLAGS" kde_safe_LIBS="$LIBS" LIBS="$LIBS $X_EXTRA_LIBS" if test "$GXX" = "yes"; then CXXFLAGS="$CXXFLAGS -pedantic-errors" fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char buf[20]; strlcpy(buf, "KDE function test", sizeof(buf)); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_func_strlcpy=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_func_strlcpy=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS="$save_CXXFLAGS" LIBS="$kde_safe_LIBS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { echo "$as_me:$LINENO: result: $kde_cv_func_strlcpy" >&5 echo "${ECHO_T}$kde_cv_func_strlcpy" >&6; } { echo "$as_me:$LINENO: checking if strlcpy needs custom prototype" >&5 echo $ECHO_N "checking if strlcpy needs custom prototype... $ECHO_C" >&6; } if test "${kde_cv_proto_strlcpy+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$kde_cv_func_strlcpy" = xyes; then kde_cv_proto_strlcpy=no else case "strlcpy" in setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat) kde_cv_proto_strlcpy="yes - in libkdefakes" ;; *) kde_cv_proto_strlcpy=unknown ;; esac fi if test "x$kde_cv_proto_strlcpy" = xunknown; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' kde_safe_libs=$LIBS LIBS="$LIBS $X_EXTRA_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include extern "C" unsigned long strlcpy(char*, const char*, unsigned long); int main () { char buf[20]; strlcpy(buf, "KDE function test", sizeof(buf)); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_func_strlcpy=yes kde_cv_proto_strlcpy=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_proto_strlcpy="strlcpy unavailable" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$kde_safe_libs ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi fi { echo "$as_me:$LINENO: result: $kde_cv_proto_strlcpy" >&5 echo "${ECHO_T}$kde_cv_proto_strlcpy" >&6; } if test "x$kde_cv_func_strlcpy" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRLCPY 1 _ACEOF fi if test "x$kde_cv_proto_strlcpy" = xno; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRLCPY_PROTO 1 _ACEOF fi { echo "$as_me:$LINENO: checking for main in -lutil" >&5 echo $ECHO_N "checking for main in -lutil... $ECHO_C" >&6; } if test "${ac_cv_lib_util_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_util_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_util_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_util_main" >&5 echo "${ECHO_T}$ac_cv_lib_util_main" >&6; } if test $ac_cv_lib_util_main = yes; then LIBUTIL="-lutil" fi { echo "$as_me:$LINENO: checking for main in -lcompat" >&5 echo $ECHO_N "checking for main in -lcompat... $ECHO_C" >&6; } if test "${ac_cv_lib_compat_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcompat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_compat_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_compat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_compat_main" >&5 echo "${ECHO_T}$ac_cv_lib_compat_main" >&6; } if test $ac_cv_lib_compat_main = yes; then LIBCOMPAT="-lcompat" fi kde_have_crypt= { echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_crypt_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6; } if test $ac_cv_lib_crypt_crypt = yes; then LIBCRYPT="-lcrypt"; kde_have_crypt=yes else { echo "$as_me:$LINENO: checking for crypt in -lc" >&5 echo $ECHO_N "checking for crypt in -lc... $ECHO_C" >&6; } if test "${ac_cv_lib_c_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_c_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_c_crypt" >&6; } if test $ac_cv_lib_c_crypt = yes; then kde_have_crypt=yes else { echo "$as_me:$LINENO: WARNING: you have no crypt in either libcrypt or libc. You should install libcrypt from another source or configure with PAM support" >&5 echo "$as_me: WARNING: you have no crypt in either libcrypt or libc. You should install libcrypt from another source or configure with PAM support" >&2;} kde_have_crypt=no fi fi if test $kde_have_crypt = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_CRYPT 1 _ACEOF fi { echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6; } if test "${kde_cv_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu kde_cv_socklen_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { socklen_t len; getpeername(0,0,&len); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_socklen_t=yes kde_cv_socklen_t_equiv=socklen_t else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { echo "$as_me:$LINENO: result: $kde_cv_socklen_t" >&5 echo "${ECHO_T}$kde_cv_socklen_t" >&6; } if test $kde_cv_socklen_t = no; then { echo "$as_me:$LINENO: checking for socklen_t equivalent for socket functions" >&5 echo $ECHO_N "checking for socklen_t equivalent for socket functions... $ECHO_C" >&6; } if test "${kde_cv_socklen_t_equiv+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_socklen_t_equiv=int ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu for t in int size_t unsigned long "unsigned long"; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { $t len; getpeername(0,0,&len); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_socklen_t_equiv="$t" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { echo "$as_me:$LINENO: result: $kde_cv_socklen_t_equiv" >&5 echo "${ECHO_T}$kde_cv_socklen_t_equiv" >&6; } fi cat >>confdefs.h <<_ACEOF #define kde_socklen_t $kde_cv_socklen_t_equiv _ACEOF cat >>confdefs.h <<_ACEOF #define ksize_t $kde_cv_socklen_t_equiv _ACEOF { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5 echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6; } if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dnet_dnet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dnet_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test $ac_cv_lib_dnet_dnet_ntoa = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5 echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6; } if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dnet_stub_dnet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi { echo "$as_me:$LINENO: checking for inet_ntoa" >&5 echo $ECHO_N "checking for inet_ntoa... $ECHO_C" >&6; } if test "${ac_cv_func_inet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define inet_ntoa to an innocuous variant, in case declares inet_ntoa. For example, HP-UX 11i declares gettimeofday. */ #define inet_ntoa innocuous_inet_ntoa /* System header to define __stub macros and hopefully few prototypes, which can conflict with char inet_ntoa (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef inet_ntoa /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntoa (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_inet_ntoa || defined __stub___inet_ntoa choke me #endif int main () { return inet_ntoa (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_inet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_inet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_inet_ntoa" >&5 echo "${ECHO_T}$ac_cv_func_inet_ntoa" >&6; } if test $ac_cv_func_inet_ntoa = no; then { echo "$as_me:$LINENO: checking for inet_ntoa in -lnsl" >&5 echo $ECHO_N "checking for inet_ntoa in -lnsl... $ECHO_C" >&6; } if test "${ac_cv_lib_nsl_inet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntoa (); int main () { return inet_ntoa (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_inet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_inet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_inet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_inet_ntoa" >&6; } if test $ac_cv_lib_nsl_inet_ntoa = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi fi { echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6; } if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_connect || defined __stub___connect choke me #endif int main () { return connect (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6; } if test $ac_cv_func_connect = no; then { echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); int main () { return connect (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6; } if test $ac_cv_lib_socket_connect = yes; then X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi { echo "$as_me:$LINENO: checking for remove" >&5 echo $ECHO_N "checking for remove... $ECHO_C" >&6; } if test "${ac_cv_func_remove+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define remove to an innocuous variant, in case declares remove. For example, HP-UX 11i declares gettimeofday. */ #define remove innocuous_remove /* System header to define __stub macros and hopefully few prototypes, which can conflict with char remove (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef remove /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char remove (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_remove || defined __stub___remove choke me #endif int main () { return remove (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_remove=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5 echo "${ECHO_T}$ac_cv_func_remove" >&6; } if test $ac_cv_func_remove = no; then { echo "$as_me:$LINENO: checking for remove in -lposix" >&5 echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6; } if test "${ac_cv_lib_posix_remove+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char remove (); int main () { return remove (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_posix_remove=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_posix_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5 echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6; } if test $ac_cv_lib_posix_remove = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. { echo "$as_me:$LINENO: checking for shmat" >&5 echo $ECHO_N "checking for shmat... $ECHO_C" >&6; } if test "${ac_cv_func_shmat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shmat to an innocuous variant, in case declares shmat. For example, HP-UX 11i declares gettimeofday. */ #define shmat innocuous_shmat /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shmat (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shmat /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shmat (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_shmat || defined __stub___shmat choke me #endif int main () { return shmat (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_shmat=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5 echo "${ECHO_T}$ac_cv_func_shmat" >&6; } if test $ac_cv_func_shmat = yes; then : else { echo "$as_me:$LINENO: checking for shmat in -lipc" >&5 echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6; } if test "${ac_cv_lib_ipc_shmat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shmat (); int main () { return shmat (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ipc_shmat=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ipc_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5 echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6; } if test $ac_cv_lib_ipc_shmat = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi # more headers that need to be explicitly included on darwin for ac_header in sys/types.h stdint.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # sys/bitypes.h is needed for uint32_t and friends on Tru64 for ac_header in sys/bitypes.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # darwin requires a poll emulation library { echo "$as_me:$LINENO: checking for poll in -lpoll" >&5 echo $ECHO_N "checking for poll in -lpoll... $ECHO_C" >&6; } if test "${ac_cv_lib_poll_poll+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpoll $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char poll (); int main () { return poll (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_poll_poll=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_poll_poll=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_poll_poll" >&5 echo "${ECHO_T}$ac_cv_lib_poll_poll" >&6; } if test $ac_cv_lib_poll_poll = yes; then LIB_POLL="-lpoll" fi # for some image handling on Mac OS X for ac_header in Carbon/Carbon.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # CoreAudio framework if test "${ac_cv_header_CoreAudio_CoreAudio_h+set}" = set; then { echo "$as_me:$LINENO: checking for CoreAudio/CoreAudio.h" >&5 echo $ECHO_N "checking for CoreAudio/CoreAudio.h... $ECHO_C" >&6; } if test "${ac_cv_header_CoreAudio_CoreAudio_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_CoreAudio_CoreAudio_h" >&5 echo "${ECHO_T}$ac_cv_header_CoreAudio_CoreAudio_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking CoreAudio/CoreAudio.h usability" >&5 echo $ECHO_N "checking CoreAudio/CoreAudio.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking CoreAudio/CoreAudio.h presence" >&5 echo $ECHO_N "checking CoreAudio/CoreAudio.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: CoreAudio/CoreAudio.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for CoreAudio/CoreAudio.h" >&5 echo $ECHO_N "checking for CoreAudio/CoreAudio.h... $ECHO_C" >&6; } if test "${ac_cv_header_CoreAudio_CoreAudio_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_CoreAudio_CoreAudio_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_CoreAudio_CoreAudio_h" >&5 echo "${ECHO_T}$ac_cv_header_CoreAudio_CoreAudio_h" >&6; } fi if test $ac_cv_header_CoreAudio_CoreAudio_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_COREAUDIO 1 _ACEOF FRAMEWORK_COREAUDIO="-Xlinker -framework -Xlinker CoreAudio" fi { echo "$as_me:$LINENO: checking if res_init needs -lresolv" >&5 echo $ECHO_N "checking if res_init needs -lresolv... $ECHO_C" >&6; } kde_libs_safe="$LIBS" LIBS="$LIBS $X_EXTRA_LIBS -lresolv" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { res_init(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBRESOLV="-lresolv" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_RES_INIT 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$kde_libs_safe { echo "$as_me:$LINENO: checking for res_init" >&5 echo $ECHO_N "checking for res_init... $ECHO_C" >&6; } if test "${kde_cv_func_res_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' save_CXXFLAGS="$CXXFLAGS" kde_safe_LIBS="$LIBS" LIBS="$LIBS $X_EXTRA_LIBS" if test "$GXX" = "yes"; then CXXFLAGS="$CXXFLAGS -pedantic-errors" fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { res_init() ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_func_res_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_func_res_init=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS="$save_CXXFLAGS" LIBS="$kde_safe_LIBS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { echo "$as_me:$LINENO: result: $kde_cv_func_res_init" >&5 echo "${ECHO_T}$kde_cv_func_res_init" >&6; } { echo "$as_me:$LINENO: checking if res_init needs custom prototype" >&5 echo $ECHO_N "checking if res_init needs custom prototype... $ECHO_C" >&6; } if test "${kde_cv_proto_res_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$kde_cv_func_res_init" = xyes; then kde_cv_proto_res_init=no else case "res_init" in setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat) kde_cv_proto_res_init="yes - in libkdefakes" ;; *) kde_cv_proto_res_init=unknown ;; esac fi if test "x$kde_cv_proto_res_init" = xunknown; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' kde_safe_libs=$LIBS LIBS="$LIBS $X_EXTRA_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include extern "C" int res_init(void); int main () { res_init() ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_func_res_init=yes kde_cv_proto_res_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_proto_res_init="res_init unavailable" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$kde_safe_libs ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi fi { echo "$as_me:$LINENO: result: $kde_cv_proto_res_init" >&5 echo "${ECHO_T}$kde_cv_proto_res_init" >&6; } if test "x$kde_cv_func_res_init" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_RES_INIT 1 _ACEOF fi if test "x$kde_cv_proto_res_init" = xno; then cat >>confdefs.h <<\_ACEOF #define HAVE_RES_INIT_PROTO 1 _ACEOF fi LIBSOCKET="$X_EXTRA_LIBS" { echo "$as_me:$LINENO: checking for killpg in -lucb" >&5 echo $ECHO_N "checking for killpg in -lucb... $ECHO_C" >&6; } if test "${ac_cv_lib_ucb_killpg+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lucb $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char killpg (); int main () { return killpg (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ucb_killpg=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ucb_killpg=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ucb_killpg" >&5 echo "${ECHO_T}$ac_cv_lib_ucb_killpg" >&6; } if test $ac_cv_lib_ucb_killpg = yes; then LIBUCB="-lucb" fi case $host in *-*-lynxos* ) { echo "$as_me:$LINENO: checking LynxOS header file wrappers" >&5 echo $ECHO_N "checking LynxOS header file wrappers... $ECHO_C" >&6; } CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__" { echo "$as_me:$LINENO: result: disabled" >&5 echo "${ECHO_T}disabled" >&6; } { echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5 echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6; } if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bsd_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6; } if test $ac_cv_lib_bsd_gethostbyname = yes; then LIBSOCKET="-lbsd" fi ;; esac { echo "$as_me:$LINENO: checking for int" >&5 echo $ECHO_N "checking for int... $ECHO_C" >&6; } if test "${ac_cv_type_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 echo "${ECHO_T}$ac_cv_type_int" >&6; } { echo "$as_me:$LINENO: checking size of int" >&5 echo $ECHO_N "checking size of int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_int" = yes; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_int=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val else ac_cv_sizeof_int=0 fi fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF { echo "$as_me:$LINENO: checking for short" >&5 echo $ECHO_N "checking for short... $ECHO_C" >&6; } if test "${ac_cv_type_short+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_short=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_short=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 echo "${ECHO_T}$ac_cv_type_short" >&6; } { echo "$as_me:$LINENO: checking size of short" >&5 echo $ECHO_N "checking size of short... $ECHO_C" >&6; } if test "${ac_cv_sizeof_short+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_short" = yes; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_short=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (short) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_short=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (short) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val else ac_cv_sizeof_short=0 fi fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF { echo "$as_me:$LINENO: checking for long" >&5 echo $ECHO_N "checking for long... $ECHO_C" >&6; } if test "${ac_cv_type_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 echo "${ECHO_T}$ac_cv_type_long" >&6; } { echo "$as_me:$LINENO: checking size of long" >&5 echo $ECHO_N "checking size of long... $ECHO_C" >&6; } if test "${ac_cv_sizeof_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_long" = yes; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val else ac_cv_sizeof_long=0 fi fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF { echo "$as_me:$LINENO: checking for char *" >&5 echo $ECHO_N "checking for char *... $ECHO_C" >&6; } if test "${ac_cv_type_char_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_char_p=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_char_p=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_char_p" >&5 echo "${ECHO_T}$ac_cv_type_char_p" >&6; } { echo "$as_me:$LINENO: checking size of char *" >&5 echo $ECHO_N "checking size of char *... $ECHO_C" >&6; } if test "${ac_cv_sizeof_char_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_char_p" = yes; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_char_p=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (char *) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (char *) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef char * ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_char_p=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (char *) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (char *) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val else ac_cv_sizeof_char_p=0 fi fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_char_p" >&5 echo "${ECHO_T}$ac_cv_sizeof_char_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR_P $ac_cv_sizeof_char_p _ACEOF { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then LIBDL="-ldl" ac_cv_have_dlfcn=yes fi { echo "$as_me:$LINENO: checking for shl_unload in -ldld" >&5 echo $ECHO_N "checking for shl_unload in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_unload+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_unload (); int main () { return shl_unload (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_unload=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_unload=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_unload" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_unload" >&6; } if test $ac_cv_lib_dld_shl_unload = yes; then LIBDL="-ldld" ac_cv_have_shload=yes fi { echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6; } { echo "$as_me:$LINENO: checking size of size_t" >&5 echo $ECHO_N "checking size of size_t... $ECHO_C" >&6; } if test "${ac_cv_sizeof_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_size_t" = yes; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_size_t=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (size_t) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_size_t=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (size_t) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val else ac_cv_sizeof_size_t=0 fi fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_size_t" >&5 echo "${ECHO_T}$ac_cv_sizeof_size_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SIZE_T $ac_cv_sizeof_size_t _ACEOF { echo "$as_me:$LINENO: checking for unsigned long" >&5 echo $ECHO_N "checking for unsigned long... $ECHO_C" >&6; } if test "${ac_cv_type_unsigned_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_unsigned_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_unsigned_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long" >&5 echo "${ECHO_T}$ac_cv_type_unsigned_long" >&6; } { echo "$as_me:$LINENO: checking size of unsigned long" >&5 echo $ECHO_N "checking size of unsigned long... $ECHO_C" >&6; } if test "${ac_cv_sizeof_unsigned_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_unsigned_long" = yes; then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_unsigned_long=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (unsigned long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_unsigned_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (unsigned long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val else ac_cv_sizeof_unsigned_long=0 fi fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_unsigned_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long _ACEOF { echo "$as_me:$LINENO: checking sizeof size_t == sizeof unsigned long" >&5 echo $ECHO_N "checking sizeof size_t == sizeof unsigned long... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_LONG choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: Apparently on your system our assumption sizeof size_t == sizeof unsigned long does not apply. Please mail kde-devel@kde.org with a description of your system! " >&5 echo "$as_me: error: Apparently on your system our assumption sizeof size_t == sizeof unsigned long does not apply. Please mail kde-devel@kde.org with a description of your system! " >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # darwin needs this to initialize the environment for ac_header in crt_externs.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for _NSGetEnviron" >&5 echo $ECHO_N "checking for _NSGetEnviron... $ECHO_C" >&6; } if test "${ac_cv_func__NSGetEnviron+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define _NSGetEnviron to an innocuous variant, in case declares _NSGetEnviron. For example, HP-UX 11i declares gettimeofday. */ #define _NSGetEnviron innocuous__NSGetEnviron /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _NSGetEnviron (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef _NSGetEnviron /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char _NSGetEnviron (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub__NSGetEnviron || defined __stub____NSGetEnviron choke me #endif int main () { return _NSGetEnviron (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func__NSGetEnviron=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__NSGetEnviron=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func__NSGetEnviron" >&5 echo "${ECHO_T}$ac_cv_func__NSGetEnviron" >&6; } if test $ac_cv_func__NSGetEnviron = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_NSGETENVIRON 1 _ACEOF fi for ac_func in vsnprintf snprintf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done kdelibsuff="$kde_libs_suffix" if test -z "$kdelibsuff"; then kdelibsuff=no fi # Check whether --enable-libsuffix was given. if test "${enable_libsuffix+set}" = set; then enableval=$enable_libsuffix; kdelibsuff=$enableval fi # TODO: add an auto case that compiles a little C app to check # where the glibc is if test "$kdelibsuff" = "no"; then kdelibsuff= fi if test -z "$kdelibsuff"; then { echo "$as_me:$LINENO: result: not using lib directory suffix" >&5 echo "${ECHO_T}not using lib directory suffix" >&6; } cat >>confdefs.h <<\_ACEOF #define KDELIBSUFF "" _ACEOF else if test "$libdir" = '${exec_prefix}/lib'; then libdir="$libdir${kdelibsuff}" libdir="$libdir" fi cat >>confdefs.h <<_ACEOF #define KDELIBSUFF "${kdelibsuff}" _ACEOF { echo "$as_me:$LINENO: result: using lib directory suffix $kdelibsuff" >&5 echo "${ECHO_T}using lib directory suffix $kdelibsuff" >&6; } fi # Check whether --enable-embedded was given. if test "${enable_embedded+set}" = set; then enableval=$enable_embedded; kde_use_qt_emb=$enableval else kde_use_qt_emb=no fi # Check whether --enable-qtopia was given. if test "${enable_qtopia+set}" = set; then enableval=$enable_qtopia; kde_use_qt_emb_palm=$enableval else kde_use_qt_emb_palm=no fi # Check whether --enable-mac was given. if test "${enable_mac+set}" = set; then enableval=$enable_mac; kde_use_qt_mac=$enableval else kde_use_qt_mac=no fi # used to disable x11-specific stuff on special platforms if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then include_x11_TRUE= include_x11_FALSE='#' else include_x11_TRUE='#' include_x11_FALSE= fi if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then { echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&6; } if test "${kde_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # One or both of the vars are not set, and there is no cached value. if test "{$x_includes+set}" = set || test "$x_includes" = NONE; then kde_x_includes=NO else kde_x_includes=$x_includes fi if test "{$x_libraries+set}" = set || test "$x_libraries" = NONE; then kde_x_libraries=NO else kde_x_libraries=$x_libraries fi # below we use the standard autoconf calls ac_x_libraries=$kde_x_libraries ac_x_includes=$kde_x_includes if test "$ac_x_includes" = NO; then # Guess where to find include files, by looking for this one X11 .h file. test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$x_direct_test_include> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Look for the header file in a standard set of common directories. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in \ /usr/X11/include \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ /usr/include/X11 \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ /usr/local/X11/include \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ /usr/local/include/X11 \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ \ /usr/include \ /usr/local/include \ /usr/unsupported/include \ /usr/athena/include \ /usr/local/x11r5/include \ /usr/lpp/Xamples/include \ \ /usr/openwin/include \ /usr/openwin/share/include \ ; \ do if test -r "$ac_dir/$x_direct_test_include"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = NO if test "$ac_x_libraries" = NO; then # Check for the libraries. test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { ${x_direct_test_function}(1) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib${kdelibsuff}/` \ /usr/X11/lib${kdelibsuff} \ /usr/X11R6/lib${kdelibsuff} \ /usr/X11R5/lib${kdelibsuff} \ /usr/X11R4/lib${kdelibsuff} \ \ /usr/lib${kdelibsuff}/X11 \ /usr/lib${kdelibsuff}/X11R6 \ /usr/lib${kdelibsuff}/X11R5 \ /usr/lib${kdelibsuff}/X11R4 \ \ /usr/local/X11/lib${kdelibsuff} \ /usr/local/X11R6/lib${kdelibsuff} \ /usr/local/X11R5/lib${kdelibsuff} \ /usr/local/X11R4/lib${kdelibsuff} \ \ /usr/local/lib${kdelibsuff}/X11 \ /usr/local/lib${kdelibsuff}/X11R6 \ /usr/local/lib${kdelibsuff}/X11R5 \ /usr/local/lib${kdelibsuff}/X11R4 \ \ /usr/X386/lib${kdelibsuff} \ /usr/x386/lib${kdelibsuff} \ /usr/XFree86/lib${kdelibsuff}/X11 \ \ /usr/lib${kdelibsuff} \ /usr/local/lib${kdelibsuff} \ /usr/unsupported/lib${kdelibsuff} \ /usr/athena/lib${kdelibsuff} \ /usr/local/x11r5/lib${kdelibsuff} \ /usr/lpp/Xamples/lib${kdelibsuff} \ /lib/usr/lib${kdelibsuff}/X11 \ \ /usr/openwin/lib${kdelibsuff} \ /usr/openwin/share/lib${kdelibsuff} \ ; \ do for ac_extension in a so sl; do if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = NO case "$host" in mips-sgi-irix6*) ;; *-*-solaris*) ;; *) rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi if test -z "$ac_x_includes"; then ac_x_includes="." fi if test -z "$ac_x_libraries"; then ac_x_libraries="/usr/lib${kdelibsuff}" fi esac #from now on we use our own again # when the user already gave --x-includes, we ignore # what the standard autoconf macros told us. if test "$kde_x_includes" = NO; then kde_x_includes=$ac_x_includes fi # for --x-libraries too if test "$kde_x_libraries" = NO; then kde_x_libraries=$ac_x_libraries fi if test "$kde_x_includes" = NO; then { { echo "$as_me:$LINENO: error: Can't find X includes. Please check your installation and add the correct paths!" >&5 echo "$as_me: error: Can't find X includes. Please check your installation and add the correct paths!" >&2;} { (exit 1); exit 1; }; } fi if test "$kde_x_libraries" = NO; then { { echo "$as_me:$LINENO: error: Can't find X libraries. Please check your installation and add the correct paths!" >&5 echo "$as_me: error: Can't find X libraries. Please check your installation and add the correct paths!" >&2;} { (exit 1); exit 1; }; } fi # Record where we found X for the cache. kde_cv_have_x="have_x=yes \ kde_x_includes=$kde_x_includes kde_x_libraries=$kde_x_libraries" fi eval "$kde_cv_have_x" if test "$have_x" != yes; then { echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$have_x" >&6; } no_x=yes else { echo "$as_me:$LINENO: result: libraries $kde_x_libraries, headers $kde_x_includes" >&5 echo "${ECHO_T}libraries $kde_x_libraries, headers $kde_x_includes" >&6; } fi if test -z "$kde_x_includes" || test "x$kde_x_includes" = xNONE; then X_INCLUDES="" x_includes="."; else x_includes=$kde_x_includes X_INCLUDES="-I$x_includes" fi if test -z "$kde_x_libraries" || test "x$kde_x_libraries" = xNONE; then X_LDFLAGS="" x_libraries="/usr/lib"; else x_libraries=$kde_x_libraries X_LDFLAGS="-L$x_libraries" fi all_includes="$X_INCLUDES" all_libraries="$X_LDFLAGS $LDFLAGS_AS_NEEDED $LDFLAGS_NEW_DTAGS" # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $X_LDFLAGS" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. { echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5 echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6; } if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ICE_IceConnectionNumber=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ICE_IceConnectionNumber=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then LIBSM="-lSM -lICE" fi LDFLAGS="$ac_save_LDFLAGS" LIB_X11='-lX11 $(LIBSOCKET)' { echo "$as_me:$LINENO: checking for libXext" >&5 echo $ECHO_N "checking for libXext... $ECHO_C" >&6; } if test "${kde_cv_have_libXext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_ldflags_safe="$LDFLAGS" kde_libs_safe="$LIBS" LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS" LIBS="-lXext -lX11 $LIBSOCKET" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef STDC_HEADERS # include #endif int main () { printf("hello Xext\n"); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_have_libXext=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_have_libXext=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$kde_ldflags_safe LIBS=$kde_libs_safe fi { echo "$as_me:$LINENO: result: $kde_cv_have_libXext" >&5 echo "${ECHO_T}$kde_cv_have_libXext" >&6; } if test "$kde_cv_have_libXext" = "no"; then { { echo "$as_me:$LINENO: error: We need a working libXext to proceed. Since configure can't find it itself, we stop here assuming that make wouldn't find them either." >&5 echo "$as_me: error: We need a working libXext to proceed. Since configure can't find it itself, we stop here assuming that make wouldn't find them either." >&2;} { (exit 1); exit 1; }; } fi LIB_XEXT="-lXext" QTE_NORTTI="" elif test "$kde_use_qt_emb" = "yes"; then CPPFLAGS=-DQWS CXXFLAGS="$CXXFLAGS -fno-rtti" QTE_NORTTI="-fno-rtti -DQWS" X_PRE_LIBS="" LIB_X11="" LIB_XEXT="" LIB_XRENDER="" LIBSM="" X_INCLUDES="" X_LDFLAGS="" x_includes="" x_libraries="" elif test "$kde_use_qt_mac" = "yes"; then CXXFLAGS="$CXXFLAGS -DQT_MAC -no-cpp-precomp" CFLAGS="$CFLAGS -DQT_MAC -no-cpp-precomp" X_PRE_LIBS="" LIB_X11="" LIB_XEXT="" LIB_XRENDER="" LIBSM="" X_INCLUDES="" X_LDFLAGS="" x_includes="" x_libraries="" fi if test -z ""; then # Current default Qt version: 3.3 kde_qtver=3 kde_qtsubver=3 else kde_qtsubver=`echo "" | sed -e 's#[0-9][0-9]*\.\([0-9][0-9]*\).*#\1#'` # following is the check if subversion isnt found in passed argument if test "$kde_qtsubver" = ""; then kde_qtsubver=1 fi kde_qtver=`echo "" | sed -e 's#^\([0-9][0-9]*\)\..*#\1#'` if test "$kde_qtver" = "1"; then kde_qtsubver=42 fi fi if test -z ""; then if test "$kde_qtver" = "2"; then if test $kde_qtsubver -gt 0; then kde_qt_minversion=">= Qt 2.2.2" else kde_qt_minversion=">= Qt 2.0.2" fi fi if test "$kde_qtver" = "3"; then if test $kde_qtsubver -gt 0; then if test $kde_qtsubver -gt 1; then if test $kde_qtsubver -gt 2; then kde_qt_minversion=">= Qt 3.3" else kde_qt_minversion=">= Qt 3.2" fi else kde_qt_minversion=">= Qt 3.1 (20021021)" fi else kde_qt_minversion=">= Qt 3.0" fi fi if test "$kde_qtver" = "1"; then kde_qt_minversion=">= 1.42 and < 2.0" fi else kde_qt_minversion="" fi if test -z ""; then if test $kde_qtver = 3; then if test $kde_qtsubver -gt 0; then kde_qt_verstring="QT_VERSION >= 0x03@VER@00 && QT_VERSION < 0x040000" qtsubver=`echo "00$kde_qtsubver" | sed -e 's,.*\(..\)$,\1,'` kde_qt_verstring=`echo $kde_qt_verstring | sed -e "s,@VER@,$qtsubver,"` else kde_qt_verstring="QT_VERSION >= 300 && QT_VERSION < 0x040000" fi fi if test $kde_qtver = 2; then if test $kde_qtsubver -gt 0; then kde_qt_verstring="QT_VERSION >= 222" else kde_qt_verstring="QT_VERSION >= 200" fi fi if test $kde_qtver = 1; then kde_qt_verstring="QT_VERSION >= 142 && QT_VERSION < 200" fi else kde_qt_verstring="" fi if test $kde_qtver = 3; then kde_qt_dirs="$QTDIR /usr/lib/qt3 /usr/lib/qt /usr/share/qt3" fi if test $kde_qtver = 2; then kde_qt_dirs="$QTDIR /usr/lib/qt2 /usr/lib/qt" fi if test $kde_qtver = 1; then kde_qt_dirs="$QTDIR /usr/lib/qt" fi LIBPTHREAD="" if test -n "$PTHREAD_LIBS"; then if test "x$PTHREAD_LIBS" = "x-pthread" ; then LIBPTHREAD="PTHREAD" else PTHREAD_LIBS_save="$PTHREAD_LIBS" PTHREAD_LIBS=`echo "$PTHREAD_LIBS_save" | sed -e 's,^-l,,g'` { echo "$as_me:$LINENO: checking for pthread_create in $PTHREAD_LIBS" >&5 echo $ECHO_N "checking for pthread_create in $PTHREAD_LIBS... $ECHO_C" >&6; } kde_save_LDFLAGS="$LDFLAGS" kde_save_LIBS="$LIBS" LDFLAGS="$LDFLAGS $all_libraries" case $host_os in aix*) LDFLAGS="-brtl $LDFLAGS" test "$GCC" = yes && LDFLAGS="-Wl,$LDFLAGS" ;; esac as_ac_Lib=`echo "ac_cv_lib_$PTHREAD_LIBS''_pthread_create" | $as_tr_sh` { echo "$as_me:$LINENO: checking for pthread_create in -l$PTHREAD_LIBS" >&5 echo $ECHO_N "checking for pthread_create in -l$PTHREAD_LIBS... $ECHO_C" >&6; } if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$PTHREAD_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Lib=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi ac_res=`eval echo '${'$as_ac_Lib'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Lib'}'` = yes; then LIBPTHREAD="$PTHREAD_LIBS_save" fi LDFLAGS="$kde_save_LDFLAGS" LIBS="$kde_save_LIBS" PTHREAD_LIBS="$PTHREAD_LIBS_save" fi fi if test -z "$LIBPTHREAD"; then { echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6; } if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_create=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6; } if test $ac_cv_lib_pthread_pthread_create = yes; then LIBPTHREAD="-lpthread" fi fi if test -z "$LIBPTHREAD" ; then { echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6; } kde_safe_libs=$LIBS LIBS="$LIBS -lpthread" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { (void)pthread_create(0,0,0,0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } LIBPTHREAD="-lpthread" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$kde_safe_libs fi if test "x$LIBPTHREAD" = "xPTHREAD" ; then LIBPTHREAD="" fi USE_THREADS="" if test -z "$LIBPTHREAD"; then { echo "$as_me:$LINENO: checking whether $CXX supports -pthread" >&5 echo $ECHO_N "checking whether $CXX supports -pthread... $ECHO_C" >&6; } kde_cache=`echo pthread | sed 'y% .=/+-,%____p__%'` if { as_var=kde_cv_prog_cxx_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -pthread" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "kde_cv_prog_cxx_$kde_cache=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CXXFLAGS="$save_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } : USE_THREADS="-D_THREAD_SAFE -pthread" else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } : fi fi case $host_os in solaris*) { echo "$as_me:$LINENO: checking whether $CXX supports -mt" >&5 echo $ECHO_N "checking whether $CXX supports -mt... $ECHO_C" >&6; } kde_cache=`echo mt | sed 'y% .=/+-,%____p__%'` if { as_var=kde_cv_prog_cxx_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -mt" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "kde_cv_prog_cxx_$kde_cache=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CXXFLAGS="$save_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } : USE_THREADS="-mt" else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } : fi CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4" ;; freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE $PTHREAD_CFLAGS" ;; aix*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" LIBPTHREAD="$LIBPTHREAD -lc_r" ;; linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" if test "$CXX" = "KCC"; then CXXFLAGS="$CXXFLAGS --thread_safe" NOOPT_CXXFLAGS="$NOOPT_CXXFLAGS --thread_safe" fi ;; *) ;; esac { echo "$as_me:$LINENO: checking for extra includes" >&5 echo $ECHO_N "checking for extra includes... $ECHO_C" >&6; } # Check whether --with-extra-includes was given. if test "${with_extra_includes+set}" = set; then withval=$with_extra_includes; kde_use_extra_includes="$withval" else kde_use_extra_includes=NONE fi kde_extra_includes= if test -n "$kde_use_extra_includes" && \ test "$kde_use_extra_includes" != "NONE"; then ac_save_ifs=$IFS IFS=':' for dir in $kde_use_extra_includes; do kde_extra_includes="$kde_extra_includes $dir" USER_INCLUDES="$USER_INCLUDES -I$dir" done IFS=$ac_save_ifs kde_use_extra_includes="added" else kde_use_extra_includes="no" fi { echo "$as_me:$LINENO: result: $kde_use_extra_includes" >&5 echo "${ECHO_T}$kde_use_extra_includes" >&6; } kde_extra_libs= { echo "$as_me:$LINENO: checking for extra libs" >&5 echo $ECHO_N "checking for extra libs... $ECHO_C" >&6; } # Check whether --with-extra-libs was given. if test "${with_extra_libs+set}" = set; then withval=$with_extra_libs; kde_use_extra_libs=$withval else kde_use_extra_libs=NONE fi if test -n "$kde_use_extra_libs" && \ test "$kde_use_extra_libs" != "NONE"; then ac_save_ifs=$IFS IFS=':' for dir in $kde_use_extra_libs; do kde_extra_libs="$kde_extra_libs $dir" KDE_EXTRA_RPATH="$KDE_EXTRA_RPATH -R $dir" USER_LDFLAGS="$USER_LDFLAGS -L$dir" done IFS=$ac_save_ifs kde_use_extra_libs="added" else kde_use_extra_libs="no" fi { echo "$as_me:$LINENO: result: $kde_use_extra_libs" >&5 echo "${ECHO_T}$kde_use_extra_libs" >&6; } { echo "$as_me:$LINENO: checking for libz" >&5 echo $ECHO_N "checking for libz... $ECHO_C" >&6; } if test "${ac_cv_lib_z+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS -lz $LIBSOCKET" kde_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char buf[42]; gzFile f = (gzFile) 0; /* this would segfault.. but we only link, don't run */ (void) gzgets(f, buf, sizeof(buf)); return (zlibVersion() == ZLIB_VERSION); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_z='-lz'" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_z=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$kde_save_LIBS" CFLAGS="$kde_save_CFLAGS" fi if test ! "$ac_cv_lib_z" = no; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBZ="$ac_cv_lib_z" { echo "$as_me:$LINENO: result: $ac_cv_lib_z" >&5 echo "${ECHO_T}$ac_cv_lib_z" >&6; } else { { echo "$as_me:$LINENO: error: not found. Possibly configure picks up an outdated version installed by XFree86. Remove it from your system. Check your installation and look into config.log" >&5 echo "$as_me: error: not found. Possibly configure picks up an outdated version installed by XFree86. Remove it from your system. Check your installation and look into config.log" >&2;} { (exit 1); exit 1; }; } LIBZ="" fi { echo "$as_me:$LINENO: checking for libpng" >&5 echo $ECHO_N "checking for libpng... $ECHO_C" >&6; } if test "${ac_cv_lib_png+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_save_LIBS="$LIBS" if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm -lX11 $LIBSOCKET" else LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm" fi kde_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { png_structp png_ptr = png_create_read_struct( /* image ptr */ PNG_LIBPNG_VER_STRING, 0, 0, 0 ); return( png_ptr != 0 ); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_png='-lpng $LIBZ -lm'" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_png=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$kde_save_LIBS" CFLAGS="$kde_save_CFLAGS" fi if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPNG 1 _ACEOF LIBPNG="$ac_cv_lib_png" { echo "$as_me:$LINENO: result: $ac_cv_lib_png" >&5 echo "${ECHO_T}$ac_cv_lib_png" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LIBPNG="" fi { echo "$as_me:$LINENO: checking for libjpeg6b" >&5 echo $ECHO_N "checking for libjpeg6b... $ECHO_C" >&6; } if test "${ac_cv_lib_jpeg_6b+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS -ljpeg6b -lm" ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ struct jpeg_decompress_struct; typedef struct jpeg_decompress_struct * j_decompress_ptr; typedef int size_t; #ifdef __cplusplus extern "C" { #endif void jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t structsize); #ifdef __cplusplus } #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ int main () { jpeg_CreateDecompress(0L, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_jpeg_6b=-ljpeg6b" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_jpeg_6b=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" CFLAGS="$ac_save_CFLAGS" fi if eval "test ! \"`echo $ac_cv_lib_jpeg_6b`\" = no"; then LIBJPEG="$ac_cv_lib_jpeg_6b" { echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_6b" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_6b" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { echo "$as_me:$LINENO: checking for libjpeg" >&5 echo $ECHO_N "checking for libjpeg... $ECHO_C" >&6; } if test "${ac_cv_lib_jpeg_normal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS -ljpeg -lm" ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ struct jpeg_decompress_struct; typedef struct jpeg_decompress_struct * j_decompress_ptr; typedef int size_t; #ifdef __cplusplus extern "C" { #endif void jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t structsize); #ifdef __cplusplus } #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ int main () { jpeg_CreateDecompress(0L, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_jpeg_normal=-ljpeg" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_jpeg_normal=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" CFLAGS="$ac_save_CFLAGS" fi if eval "test ! \"`echo $ac_cv_lib_jpeg_normal`\" = no"; then LIBJPEG="$ac_cv_lib_jpeg_normal" { echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_normal" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_normal" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LIBJPEG= fi fi jpeg_incdirs="$includedir /usr/include /usr/local/include $kde_extra_includes" jpeg_incdir=NO for i in $jpeg_incdirs; do for j in jpeglib.h; do echo "configure: 15608: $i/$j" >&5 if test -r "$i/$j"; then echo "taking that" >&5 jpeg_incdir=$i break 2 fi done done test "x$jpeg_incdir" = xNO && jpeg_incdir= if test -n "$jpeg_incdir" && test -n "$LIBJPEG" ; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF else if test -n "$jpeg_incdir" || test -n "$LIBJPEG" ; then { echo "$as_me:$LINENO: WARNING: There is an installation error in jpeg support. You seem to have only one of either the headers _or_ the libraries installed. You may need to either provide correct --with-extra-... options, or the development package of libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/ Disabling JPEG support. " >&5 echo "$as_me: WARNING: There is an installation error in jpeg support. You seem to have only one of either the headers _or_ the libraries installed. You may need to either provide correct --with-extra-... options, or the development package of libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/ Disabling JPEG support. " >&2;} else { echo "$as_me:$LINENO: WARNING: libjpeg not found. disable JPEG support." >&5 echo "$as_me: WARNING: libjpeg not found. disable JPEG support." >&2;} fi jpeg_incdir= LIBJPEG= fi { echo "$as_me:$LINENO: checking for perl" >&5 echo $ECHO_N "checking for perl... $ECHO_C" >&6; } if test -n "$PERL"; then kde_cv_path="$PERL"; else kde_cache=`echo perl | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$bindir $exec_prefix/bin $prefix/bin $dirs" else dirs="$dirs $bindir $exec_prefix/bin $prefix/bin" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/perl"; then if test -n "" then evalstr="$dir/perl 2>&1 " if eval $evalstr; then kde_cv_path="$dir/perl" break fi else kde_cv_path="$dir/perl" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: No Perl found in your $PATH. We need perl to generate some code." >&5 echo "$as_me: error: No Perl found in your $PATH. We need perl to generate some code." >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } PERL=$kde_cv_path fi # Check whether --enable-mt was given. if test "${enable_mt+set}" = set; then enableval=$enable_mt; kde_use_qt_mt=$enableval else if test $kde_qtver = 3; then kde_use_qt_mt=yes else kde_use_qt_mt=no fi fi USING_QT_MT="" KDE_MT_LDFLAGS= KDE_MT_LIBS= if test "x$kde_use_qt_mt" = "xyes"; then if test -z "$LIBPTHREAD"; then if test -z "$USE_THREADS"; then kde_check_threading_default=no else kde_check_threading_default=yes fi else kde_check_threading_default=yes fi # Check whether --enable-threading was given. if test "${enable_threading+set}" = set; then enableval=$enable_threading; kde_use_threading=$enableval else kde_use_threading=$kde_check_threading_default fi if test "x$kde_use_threading" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF fi if test "x$kde_use_threading" = "xyes"; then CPPFLAGS="$USE_THREADS -DQT_THREAD_SUPPORT $CPPFLAGS" KDE_MT_LDFLAGS="$USE_THREADS" KDE_MT_LIBS="$LIBPTHREAD" else kde_use_qt_mt=no fi fi kde_qt_was_given=yes if test -z "$LIBQT_GLOB"; then if test "x$kde_use_qt_emb" = "xyes"; then LIBQT_GLOB="libqte.*" else LIBQT_GLOB="libqt.*" fi fi if test -z "$LIBQT"; then if test "x$kde_use_qt_emb" = "xyes"; then qtlib="qte" else qtlib="qt" fi kde_int_qt="-l$qtlib" else kde_int_qt="$LIBQT" kde_lib_qt_set=yes fi if test -z "$LIBQPE"; then if test "x$kde_use_qt_emb" = "xyes"; then if test "x$kde_use_qt_emb_palm" = "xyes"; then LIB_QPE="-lqpe" else LIB_QPE="" fi else LIB_QPE="" fi fi if test "x$kde_use_qt_mt" = "xyes"; then if test -z "$LIBQT"; then LIBQT="-l$qtlib-mt" kde_int_qt="-l$qtlib-mt" else LIBQT="$qtlib-mt" kde_int_qt="$qtlib-mt" fi LIBQT_GLOB="lib$qtlib-mt.*" USING_QT_MT="using -mt" else LIBQT="-l$qtlib" fi if test $kde_qtver != 1; then LIBQT="$LIBQT $LIBPNG $LIBJPEG" fi if test $kde_qtver = 3; then LIBQT="$LIBQT $LIBDL" fi { echo "$as_me:$LINENO: checking for Qt" >&5 echo $ECHO_N "checking for Qt... $ECHO_C" >&6; } if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBQT="$LIBQT $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET" fi ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO qt_libraries="" qt_includes="" # Check whether --with-qt-dir was given. if test "${with_qt_dir+set}" = set; then withval=$with_qt_dir; ac_qt_includes="$withval"/include ac_qt_libraries="$withval"/lib${kdelibsuff} ac_qt_bindir="$withval"/bin fi # Check whether --with-qt-includes was given. if test "${with_qt_includes+set}" = set; then withval=$with_qt_includes; ac_qt_includes="$withval" fi kde_qt_libs_given=no # Check whether --with-qt-libraries was given. if test "${with_qt_libraries+set}" = set; then withval=$with_qt_libraries; ac_qt_libraries="$withval" kde_qt_libs_given=yes fi if test "${ac_cv_have_qt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else #try to guess Qt locations qt_incdirs="" for dir in $kde_qt_dirs; do qt_incdirs="$qt_incdirs $dir/include $dir" done qt_incdirs="$QTINC $qt_incdirs /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/X11R6/include/qt2 /usr/include/qt3 $x_includes" if test ! "$ac_qt_includes" = "NO"; then qt_incdirs="$ac_qt_includes $qt_incdirs" fi if test "$kde_qtver" != "1"; then kde_qt_header=qstyle.h else kde_qt_header=qglobal.h fi qt_incdir=NO for i in $qt_incdirs; do for j in $kde_qt_header; do echo "configure: 15916: $i/$j" >&5 if test -r "$i/$j"; then echo "taking that" >&5 qt_incdir=$i break 2 fi done done ac_qt_includes="$qt_incdir" qt_libdirs="" for dir in $kde_qt_dirs; do qt_libdirs="$qt_libdirs $dir/lib${kdelibsuff} $dir" done qt_libdirs="$QTLIB $qt_libdirs /usr/X11R6/lib /usr/lib /usr/local/qt/lib $x_libraries" if test ! "$ac_qt_libraries" = "NO"; then qt_libdir=$ac_qt_libraries else qt_libdirs="$ac_qt_libraries $qt_libdirs" # if the Qt was given, the chance is too big that libqt.* doesn't exist qt_libdir=NONE for dir in $qt_libdirs; do try="ls -1 $dir/${LIBQT_GLOB}" if test -n "`$try 2> /dev/null`"; then qt_libdir=$dir; break; else echo "tried $dir" >&5 ; fi done fi for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do if test -e "$a"; then LIBQT="$LIBQT ${kde_int_qt}_incremental" break fi done ac_qt_libraries="$qt_libdir" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_cxxflags_safe="$CXXFLAGS" ac_ldflags_safe="$LDFLAGS" ac_libs_safe="$LIBS" CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" LDFLAGS="$LDFLAGS -L$qt_libdir $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" LIBS="$LIBS $LIBQT $KDE_MT_LIBS" cat > conftest.$ac_ext < #include EOF if test "$kde_qtver" = "2"; then cat >> conftest.$ac_ext < #include #include EOF if test $kde_qtsubver -gt 0; then cat >> conftest.$ac_ext <> conftest.$ac_ext < #include #include EOF fi echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext cat >> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest; then rm -f conftest* else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_qt_libraries="NO" fi rm -f conftest* CXXFLAGS="$ac_cxxflags_safe" LDFLAGS="$ac_ldflags_safe" LIBS="$ac_libs_safe" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then ac_cv_have_qt="have_qt=no" ac_qt_notfound="" missing_qt_mt="" if test "$ac_qt_includes" = NO; then if test "$ac_qt_libraries" = NO; then ac_qt_notfound="(headers and libraries)"; else ac_qt_notfound="(headers)"; fi else if test "x$kde_use_qt_mt" = "xyes"; then missing_qt_mt=" Make sure that you have compiled Qt with thread support!" ac_qt_notfound="(library $qtlib-mt)"; else ac_qt_notfound="(library $qtlib)"; fi fi { { echo "$as_me:$LINENO: error: Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation! For more details about this problem, look at the end of config.log.$missing_qt_mt" >&5 echo "$as_me: error: Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation! For more details about this problem, look at the end of config.log.$missing_qt_mt" >&2;} { (exit 1); exit 1; }; } else have_qt="yes" fi fi eval "$ac_cv_have_qt" if test "$have_qt" != yes; then { echo "$as_me:$LINENO: result: $have_qt" >&5 echo "${ECHO_T}$have_qt" >&6; }; else ac_cv_have_qt="have_qt=yes \ ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries" { echo "$as_me:$LINENO: result: libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT" >&5 echo "${ECHO_T}libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT" >&6; } qt_libraries="$ac_qt_libraries" qt_includes="$ac_qt_includes" fi if test ! "$kde_qt_libs_given" = "yes" && test ! "$kde_qtver" = 3; then { echo "$as_me:$LINENO: checking if Qt compiles without flags" >&5 echo $ECHO_N "checking if Qt compiles without flags... $ECHO_C" >&6; } if test "${kde_cv_qt_direct+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_LD_LIBRARY_PATH_safe=$LD_LIBRARY_PATH ac_LIBRARY_PATH="$LIBRARY_PATH" ac_cxxflags_safe="$CXXFLAGS" ac_ldflags_safe="$LDFLAGS" ac_libs_safe="$LIBS" CXXFLAGS="$CXXFLAGS -I$qt_includes" LDFLAGS="$LDFLAGS $X_LDFLAGS" if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBS="$LIBQT -lXext -lX11 $LIBSOCKET" else LIBS="$LIBQT $LIBSOCKET" fi LD_LIBRARY_PATH= export LD_LIBRARY_PATH LIBRARY_PATH= export LIBRARY_PATH cat > conftest.$ac_ext < #include EOF if test "$kde_qtver" = "2"; then cat >> conftest.$ac_ext < #include #include EOF if test $kde_qtsubver -gt 0; then cat >> conftest.$ac_ext <> conftest.$ac_ext < #include #include EOF fi echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext cat >> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest; then kde_cv_qt_direct="yes" else kde_cv_qt_direct="no" echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* CXXFLAGS="$ac_cxxflags_safe" LDFLAGS="$ac_ldflags_safe" LIBS="$ac_libs_safe" LD_LIBRARY_PATH="$ac_LD_LIBRARY_PATH_safe" export LD_LIBRARY_PATH LIBRARY_PATH="$ac_LIBRARY_PATH" export LIBRARY_PATH ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi if test "$kde_cv_qt_direct" = "yes"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } qt_libraries= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then QT_INCLUDES="" else QT_INCLUDES="-I$qt_includes" all_includes="$QT_INCLUDES $all_includes" fi if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then QT_LDFLAGS="" else QT_LDFLAGS="-L$qt_libraries" all_libraries="$QT_LDFLAGS $all_libraries" fi test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS" qt_bindirs="" for dir in $kde_qt_dirs; do qt_bindirs="$qt_bindirs $dir/bin $dir/src/moc" done qt_bindirs="$qt_bindirs /usr/bin /usr/X11R6/bin /usr/local/qt/bin" if test ! "$ac_qt_bindir" = "NO"; then qt_bindirs="$ac_qt_bindir $qt_bindirs" fi { echo "$as_me:$LINENO: checking for moc" >&5 echo $ECHO_N "checking for moc... $ECHO_C" >&6; } if test -n "$MOC"; then kde_cv_path="$MOC"; else kde_cache=`echo moc | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$qt_bindirs $dirs" else dirs="$dirs $qt_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/moc"; then if test -n "" then evalstr="$dir/moc 2>&1 " if eval $evalstr; then kde_cv_path="$dir/moc" break fi else kde_cv_path="$dir/moc" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: No Qt meta object compiler (moc) found! Please check whether you installed Qt correctly. You need to have a running moc binary. configure tried to run $ac_cv_path_moc and the test didn't succeed. If configure shouldn't have tried this one, set the environment variable MOC to the right one before running configure. " >&5 echo "$as_me: error: No Qt meta object compiler (moc) found! Please check whether you installed Qt correctly. You need to have a running moc binary. configure tried to run $ac_cv_path_moc and the test didn't succeed. If configure shouldn't have tried this one, set the environment variable MOC to the right one before running configure. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } MOC=$kde_cv_path fi if test -z "$UIC_NOT_NEEDED"; then { echo "$as_me:$LINENO: checking for uic" >&5 echo $ECHO_N "checking for uic... $ECHO_C" >&6; } if test -n "$UIC_PATH"; then kde_cv_path="$UIC_PATH"; else kde_cache=`echo uic | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$qt_bindirs $dirs" else dirs="$dirs $qt_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/uic"; then if test -n "" then evalstr="$dir/uic 2>&1 " if eval $evalstr; then kde_cv_path="$dir/uic" break fi else kde_cv_path="$dir/uic" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } UIC_PATH="" else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } UIC_PATH=$kde_cv_path fi if test -z "$UIC_PATH" ; then { echo "$as_me:$LINENO: WARNING: No Qt ui compiler (uic) found! Please check whether you installed Qt correctly. You need to have a running uic binary. configure tried to run $ac_cv_path_uic and the test didn't succeed. If configure shouldn't have tried this one, set the environment variable UIC to the right one before running configure. " >&5 echo "$as_me: WARNING: No Qt ui compiler (uic) found! Please check whether you installed Qt correctly. You need to have a running uic binary. configure tried to run $ac_cv_path_uic and the test didn't succeed. If configure shouldn't have tried this one, set the environment variable UIC to the right one before running configure. " >&2;} exit 1 else UIC=$UIC_PATH if test $kde_qtver = 3; then { echo "$as_me:$LINENO: checking whether uic supports -L " >&5 echo $ECHO_N "checking whether uic supports -L ... $ECHO_C" >&6; } kde_cache=`echo L | sed 'y% .=/+-%____p_%'` if { as_var=kde_cv_prog_uic_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.ui < EOT ac_uic_testrun="$UIC_PATH -L /nonexistent conftest.ui >/dev/null" if { (eval echo "$as_me:$LINENO: \"$ac_uic_testrun\"") >&5 (eval $ac_uic_testrun) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then eval "kde_cv_prog_uic_$kde_cache=yes" else eval "kde_cv_prog_uic_$kde_cache=no" fi rm -f conftest* fi if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } : ac_uic_supports_libpath=yes else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } : ac_uic_supports_libpath=no fi { echo "$as_me:$LINENO: checking whether uic supports -nounload " >&5 echo $ECHO_N "checking whether uic supports -nounload ... $ECHO_C" >&6; } kde_cache=`echo nounload | sed 'y% .=/+-%____p_%'` if { as_var=kde_cv_prog_uic_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.ui < EOT ac_uic_testrun="$UIC_PATH -nounload conftest.ui >/dev/null" if { (eval echo "$as_me:$LINENO: \"$ac_uic_testrun\"") >&5 (eval $ac_uic_testrun) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then eval "kde_cv_prog_uic_$kde_cache=yes" else eval "kde_cv_prog_uic_$kde_cache=no" fi rm -f conftest* fi if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } : ac_uic_supports_nounload=yes else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } : ac_uic_supports_nounload=no fi if test x$ac_uic_supports_libpath = xyes; then UIC="$UIC -L \$(kde_widgetdir)" fi if test x$ac_uic_supports_nounload = xyes; then UIC="$UIC -nounload" fi fi fi else UIC="echo uic not available: " fi UIC_TR="i18n" if test $kde_qtver = 3; then UIC_TR="tr2i18n" fi if test -n "$LIBJPEG"; then { echo "$as_me:$LINENO: checking if Qt needs $LIBJPEG" >&5 echo $ECHO_N "checking if Qt needs $LIBJPEG... $ECHO_C" >&6; } if test "${kde_cv_qt_jpeg+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS $LIBQT" LIBS=`echo $LIBS | sed "s/$LIBJPEG//"` ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { int argc; char** argv; QApplication app(argc, argv); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "kde_cv_qt_jpeg=no" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "kde_cv_qt_jpeg=yes" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" CXXFLAGS="$ac_save_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi fi if eval "test ! \"`echo $kde_cv_qt_jpeg`\" = no"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } LIBJPEG_QT='$(LIBJPEG)' else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LIBJPEG_QT= fi if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)' else LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG)' fi test -z "$KDE_MT_LIBS" || LIB_QT="$LIB_QT $KDE_MT_LIBS" for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do if test -e "$a"; then LIB_QT="$LIB_QT ${kde_int_qt}_incremental" break fi done # Check if lrelease is available # Extract the first word of "lrelease", so it can be a program name with args. set dummy lrelease; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_have_lrelease+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$have_lrelease"; then ac_cv_prog_have_lrelease="$have_lrelease" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_have_lrelease="yes" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_have_lrelease" && ac_cv_prog_have_lrelease="no" fi fi have_lrelease=$ac_cv_prog_have_lrelease if test -n "$have_lrelease"; then { echo "$as_me:$LINENO: result: $have_lrelease" >&5 echo "${ECHO_T}$have_lrelease" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$have_lrelease" = "xno" then { { echo "$as_me:$LINENO: error: lrelease is missing (qt3-devel-tools package)" >&5 echo "$as_me: error: lrelease is missing (qt3-devel-tools package)" >&2;} { (exit 1); exit 1; }; } fi QT_INCL_PRO=qtccxxincl.pro { echo "$as_me:$LINENO: creating $QT_INCL_PRO (include project file for Qt)" >&5 echo "$as_me: creating $QT_INCL_PRO (include project file for Qt)" >&6;} # first set include path to generated files echo "INCLUDEPATH += `pwd`/src" > $QT_INCL_PRO # next get includes specified on command line ( set -- $CPPFLAGS while test -n "$1"; do echo $1 shift done ) | grep '^-I' | sed -e 's|^-I||' | xargs echo INCLUDEPATH += >> $QT_INCL_PRO #echo "INCLUDEPATH += `$CCGNU2_CONFIG --includes`" | sed -e s/-I//g > $QT_INCL_PRO # libccrtp1(ccrtp) depend from libccgnu2(commoncpp2) and # should include above flags ! echo "INCLUDEPATH += `$PKG_CONFIG --cflags-only-I libccrtp1`" | sed -e s/-I//g >> $QT_INCL_PRO echo "INCLUDEPATH += `$PKG_CONFIG --cflags-only-I libxml-2.0`" | sed -e s/-I//g >> $QT_INCL_PRO # get libraries specified on command line echo $LDFLAGS | xargs echo LIBS += >> $QT_INCL_PRO echo "LIBS += `$CCGNU2_CONFIG --stdlibs`" >> $QT_INCL_PRO echo "LIBS += $CCRTP_LIBS" >> $QT_INCL_PRO echo "LIBS += $XML2_LIBS" >> $QT_INCL_PRO # Check if KDE is available if test "x$ac_cv_kde" = "xyes" then # Extract the first word of "kde-config", so it can be a program name with args. set dummy kde-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_have_kde+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$have_kde"; then ac_cv_prog_have_kde="$have_kde" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_have_kde="yes" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_have_kde" && ac_cv_prog_have_kde="no" fi fi have_kde=$ac_cv_prog_have_kde if test -n "$have_kde"; then { echo "$as_me:$LINENO: result: $have_kde" >&5 echo "${ECHO_T}$have_kde" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi else have_kde="no" fi if test "x$have_kde" = "xyes" then unset CDPATH kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin" test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs" if test -n "$KDEDIRS"; then kde_save_IFS=$IFS IFS=: for dir in $KDEDIRS; do kde_default_bindirs="$dir/bin $kde_default_bindirs " done IFS=$kde_save_IFS fi if test "x$prefix" = "xNONE"; then { echo "$as_me:$LINENO: checking for kde-config" >&5 echo $ECHO_N "checking for kde-config... $ECHO_C" >&6; } if test -n "$KDECONFIG"; then kde_cv_path="$KDECONFIG"; else kde_cache=`echo kde-config | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z "prepend"; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/kde-config"; then if test -n "" then evalstr="$dir/kde-config 2>&1 " if eval $evalstr; then kde_cv_path="$dir/kde-config" break fi else kde_cv_path="$dir/kde-config" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program kde-config was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program kde-config was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } KDECONFIG=$kde_cv_path fi else kde_save_PATH="$PATH" PATH="$exec_prefix/bin:$prefix/bin:$PATH" { echo "$as_me:$LINENO: checking for kde-config" >&5 echo $ECHO_N "checking for kde-config... $ECHO_C" >&6; } if test -n "$KDECONFIG"; then kde_cv_path="$KDECONFIG"; else kde_cache=`echo kde-config | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z "prepend"; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/kde-config"; then if test -n "" then evalstr="$dir/kde-config 2>&1 " if eval $evalstr; then kde_cv_path="$dir/kde-config" break fi else kde_cv_path="$dir/kde-config" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program kde-config was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program kde-config was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } KDECONFIG=$kde_cv_path fi PATH="$kde_save_PATH" fi kde_libs_prefix=`$KDECONFIG --prefix` if test -z "$kde_libs_prefix" || test ! -x "$kde_libs_prefix"; then { { echo "$as_me:$LINENO: error: $KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs. This means it has been moved since you installed it. This won't work. Please recompile kdelibs for the new prefix. " >&5 echo "$as_me: error: $KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs. This means it has been moved since you installed it. This won't work. Please recompile kdelibs for the new prefix. " >&2;} { (exit 1); exit 1; }; } fi kde_libs_htmldir=`$KDECONFIG --install html --expandvars` kde_libs_suffix=`$KDECONFIG --libsuffix` { echo "$as_me:$LINENO: checking where to install" >&5 echo $ECHO_N "checking where to install... $ECHO_C" >&6; } if test "x$prefix" = "xNONE"; then prefix=$kde_libs_prefix { echo "$as_me:$LINENO: result: $prefix (as returned by kde-config)" >&5 echo "${ECHO_T}$prefix (as returned by kde-config)" >&6; } else given_prefix=$prefix { echo "$as_me:$LINENO: result: $prefix (as requested)" >&5 echo "${ECHO_T}$prefix (as requested)" >&6; } fi # And delete superfluous '/' to make compares easier prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` given_prefix=`echo "$given_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` # Check whether --enable-fast-perl was given. if test "${enable_fast_perl+set}" = set; then enableval=$enable_fast_perl; with_fast_perl=$enableval else with_fast_perl=yes fi val= if test -f $srcdir/configure.files ; then val=`sed -e 's%^%\$(top_srcdir)/%' $srcdir/configure.files` fi CONF_FILES= if test -n "$val" ; then for i in $val ; do CONF_FILES="$CONF_FILES $i" done fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="`echo $CXXFLAGS | sed s/-fno-exceptions//`" { echo "$as_me:$LINENO: checking if C++ programs can be compiled" >&5 echo $ECHO_N "checking if C++ programs can be compiled... $ECHO_C" >&6; } if test "${kde_cv_stl_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include using namespace std; int main () { string astring="Hallo Welt."; astring.erase(0, 6); // now astring is "Welt" return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kde_cv_stl_works=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kde_cv_stl_works=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $kde_cv_stl_works" >&5 echo "${ECHO_T}$kde_cv_stl_works" >&6; } if test "$kde_cv_stl_works" = "yes"; then # back compatible cat >>confdefs.h <<_ACEOF #define HAVE_SGI_STL 1 _ACEOF else { { echo "$as_me:$LINENO: error: Your Installation isn't able to compile simple C++ programs. Check config.log for details - if you're using a Linux distribution you might miss a package named similar to libstdc++-dev." >&5 echo "$as_me: error: Your Installation isn't able to compile simple C++ programs. Check config.log for details - if you're using a Linux distribution you might miss a package named similar to libstdc++-dev." >&2;} { (exit 1); exit 1; }; } fi CXXFLAGS="$ac_save_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { echo "$as_me:$LINENO: checking for rpath" >&5 echo $ECHO_N "checking for rpath... $ECHO_C" >&6; } # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then enableval=$enable_rpath; USE_RPATH=$enableval else USE_RPATH=yes fi if test -z "$KDE_RPATH" && test "$USE_RPATH" = "yes"; then KDE_RPATH="-R \$(libdir)" if test "$kde_libraries" != "$libdir"; then KDE_RPATH="$KDE_RPATH -R \$(kde_libraries)" fi if test -n "$qt_libraries"; then KDE_RPATH="$KDE_RPATH -R \$(qt_libraries)" fi if test -n "$X_LDFLAGS"; then X_RPATH="-R \$(x_libraries)" KDE_RPATH="$KDE_RPATH $X_RPATH" fi if test -n "$KDE_EXTRA_RPATH"; then KDE_RPATH="$KDE_RPATH \$(KDE_EXTRA_RPATH)" fi fi { echo "$as_me:$LINENO: result: $USE_RPATH" >&5 echo "${ECHO_T}$USE_RPATH" >&6; } { echo "$as_me:$LINENO: checking for KDE" >&5 echo $ECHO_N "checking for KDE... $ECHO_C" >&6; } if test "${prefix}" != NONE; then kde_includes=${includedir} savex=$exec_prefix test "x$exec_prefix" = xNONE && exec_prefix=$prefix tmp=$includedir while ac_kde_includes=`eval echo "$tmp"`; test "x$ac_kde_includes" != "x$tmp"; do tmp=$ac_kde_includes; done exec_prefix=$savex kde_libraries=${libdir} savex=$exec_prefix test "x$exec_prefix" = xNONE && exec_prefix=$prefix tmp=$libdir while ac_kde_libraries=`eval echo "$tmp"`; test "x$ac_kde_libraries" != "x$tmp"; do tmp=$ac_kde_libraries; done exec_prefix=$savex else ac_kde_includes= ac_kde_libraries= kde_libraries="" kde_includes="" fi if test "${ac_cv_have_kde+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else #try to guess kde locations if test "$kde_qtver" = 1; then kde_check_header="ksock.h" kde_check_lib="libkdecore.la" else kde_check_header="ksharedptr.h" kde_check_lib="libkio.la" fi if test -z ""; then kde_incdirs="$kde_libs_prefix/include /usr/lib/kde/include /usr/local/kde/include /usr/local/include /usr/kde/include /usr/include/kde /usr/include /opt/kde3/include /opt/kde/include $x_includes $qt_includes" test -n "$KDEDIR" && kde_incdirs="$KDEDIR/include $KDEDIR/include/kde $KDEDIR $kde_incdirs" kde_incdirs="$ac_kde_includes $kde_incdirs" kde_incdir=NO for i in $kde_incdirs; do for j in $kde_check_header; do echo "configure: 17222: $i/$j" >&5 if test -r "$i/$j"; then echo "taking that" >&5 kde_incdir=$i break 2 fi done done ac_kde_includes="$kde_incdir" if test -n "$ac_kde_includes" && test ! -r "$ac_kde_includes/$kde_check_header"; then { { echo "$as_me:$LINENO: error: in the prefix, you've chosen, are no KDE headers installed. This will fail. So, check this please and use another prefix!" >&5 echo "$as_me: error: in the prefix, you've chosen, are no KDE headers installed. This will fail. So, check this please and use another prefix!" >&2;} { (exit 1); exit 1; }; } fi kde_libdirs="$kde_libs_prefix/lib${kdelibsuff} /usr/lib/kde/lib${kdelibsuff} /usr/local/kde/lib${kdelibsuff} /usr/kde/lib${kdelibsuff} /usr/lib${kdelibsuff}/kde /usr/lib${kdelibsuff}/kde3 /usr/lib${kdelibsuff} /usr/X11R6/lib${kdelibsuff} /usr/local/lib${kdelibsuff} /opt/kde3/lib${kdelibsuff} /opt/kde/lib${kdelibsuff} /usr/X11R6/kde/lib${kdelibsuff}" test -n "$KDEDIR" && kde_libdirs="$KDEDIR/lib${kdelibsuff} $KDEDIR $kde_libdirs" kde_libdirs="$ac_kde_libraries $libdir $kde_libdirs" kde_libdir=NO for i in $kde_libdirs; do for j in $kde_check_lib; do echo "configure: 17252: $i/$j" >&5 if test -r "$i/$j"; then echo "taking that" >&5 kde_libdir=$i break 2 fi done done ac_kde_libraries="$kde_libdir" kde_widgetdir=NO kde_widgetdir=NO for i in $kde_libdirs; do for j in "kde3/plugins/designer/kdewidgets.la"; do echo "configure: 17270: $i/$j" >&5 if test -r "$i/$j"; then echo "taking that" >&5 kde_widgetdir=$i break 2 fi done done if test -n "$ac_kde_libraries" && test ! -r "$ac_kde_libraries/$kde_check_lib"; then { { echo "$as_me:$LINENO: error: in the prefix, you've chosen, are no KDE libraries installed. This will fail. So, check this please and use another prefix!" >&5 echo "$as_me: error: in the prefix, you've chosen, are no KDE libraries installed. This will fail. So, check this please and use another prefix!" >&2;} { (exit 1); exit 1; }; } fi if test -n "$kde_widgetdir" && test ! -r "$kde_widgetdir/kde3/plugins/designer/kdewidgets.la"; then { { echo "$as_me:$LINENO: error: I can't find the designer plugins. These are required and should have been installed by kdelibs" >&5 echo "$as_me: error: I can't find the designer plugins. These are required and should have been installed by kdelibs" >&2;} { (exit 1); exit 1; }; } fi if test -n "$kde_widgetdir"; then kde_widgetdir="$kde_widgetdir/kde3/plugins/designer" fi if test "$ac_kde_includes" = NO || test "$ac_kde_libraries" = NO || test "$kde_widgetdir" = NO; then ac_cv_have_kde="have_kde=no" else ac_cv_have_kde="have_kde=yes \ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" fi else ac_cv_have_kde="have_kde=no" fi fi eval "$ac_cv_have_kde" if test "$have_kde" != "yes"; then if test "${prefix}" = NONE; then ac_kde_prefix="$ac_default_prefix" else ac_kde_prefix="$prefix" fi if test "$exec_prefix" = NONE; then ac_kde_exec_prefix="$ac_kde_prefix" { echo "$as_me:$LINENO: result: will be installed in $ac_kde_prefix" >&5 echo "${ECHO_T}will be installed in $ac_kde_prefix" >&6; } else ac_kde_exec_prefix="$exec_prefix" { echo "$as_me:$LINENO: result: will be installed in $ac_kde_prefix and $ac_kde_exec_prefix" >&5 echo "${ECHO_T}will be installed in $ac_kde_prefix and $ac_kde_exec_prefix" >&6; } fi kde_libraries="${libdir}" kde_includes="${includedir}" else ac_cv_have_kde="have_kde=yes \ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" { echo "$as_me:$LINENO: result: libraries $ac_kde_libraries, headers $ac_kde_includes" >&5 echo "${ECHO_T}libraries $ac_kde_libraries, headers $ac_kde_includes" >&6; } kde_libraries="$ac_kde_libraries" kde_includes="$ac_kde_includes" fi if test "$kde_includes" = "$x_includes" || test "$kde_includes" = "$qt_includes" || test "$kde_includes" = "/usr/include"; then KDE_INCLUDES="" else KDE_INCLUDES="-I$kde_includes" all_includes="$KDE_INCLUDES $all_includes" fi KDE_DEFAULT_CXXFLAGS="-DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION" KDE_LDFLAGS="-L$kde_libraries" if test ! "$kde_libraries" = "$x_libraries" && test ! "$kde_libraries" = "$qt_libraries" ; then all_libraries="$KDE_LDFLAGS $all_libraries" fi all_libraries="$all_libraries $USER_LDFLAGS" all_includes="$all_includes $USER_INCLUDES" if test -z ""; then if test x$ac_uic_supports_libpath = xyes; then { echo "$as_me:$LINENO: checking if UIC has KDE plugins available" >&5 echo $ECHO_N "checking if UIC has KDE plugins available... $ECHO_C" >&6; } if test "${kde_cv_uic_plugins+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat > actest.ui << EOF NewConnectionDialog testInput EOF kde_cv_uic_plugins=no kde_line="$UIC_PATH -L $kde_widgetdir" if test x$ac_uic_supports_nounload = xyes; then kde_line="$kde_line -nounload" fi kde_line="$kde_line -impl actest.h actest.ui > actest.cpp" if { (eval echo "$as_me:$LINENO: \"$kde_line\"") >&5 (eval $kde_line) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # if you're trying to debug this check and think it's incorrect, # better check your installation. The check _is_ correct - your # installation is not. if test -f actest.cpp && grep klineedit actest.cpp > /dev/null; then kde_cv_uic_plugins=yes fi fi rm -f actest.ui actest.cpp fi { echo "$as_me:$LINENO: result: $kde_cv_uic_plugins" >&5 echo "${ECHO_T}$kde_cv_uic_plugins" >&6; } if test "$kde_cv_uic_plugins" != yes; then { { echo "$as_me:$LINENO: error: you need to install kdelibs first." >&5 echo "$as_me: error: you need to install kdelibs first." >&2;} { (exit 1); exit 1; }; } fi fi fi ac_kde_libraries="$kde_libdir" # Check whether --enable-path-check was given. if test "${enable_path_check+set}" = set; then enableval=$enable_path_check; if test "$enableval" = "no"; then ac_use_path_checking="default" else ac_use_path_checking="" fi else if test "$kde_qtver" = 1; then ac_use_path_checking="" else ac_use_path_checking="default" fi fi { echo "$as_me:$LINENO: checking for KDE paths" >&5 echo $ECHO_N "checking for KDE paths... $ECHO_C" >&6; } kde_result="" kde_cached_paths=yes if test "${kde_cv_all_paths+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_use_path_checking" = "default"; then if test -z "$kde_htmldir"; then kde_htmldir='\${datadir}/doc/HTML' fi if test -z "$kde_appsdir"; then kde_appsdir='\${datadir}/applnk' fi if test -z "$kde_icondir"; then kde_icondir='\${datadir}/icons' fi if test -z "$kde_sounddir"; then kde_sounddir='\${datadir}/sounds' fi if test -z "$kde_datadir"; then kde_datadir='\${datadir}/apps' fi if test -z "$kde_locale"; then kde_locale='\${datadir}/locale' fi if test -z "$kde_cgidir"; then kde_cgidir='\${exec_prefix}/cgi-bin' fi if test -z "$kde_confdir"; then kde_confdir='\${datadir}/config' fi if test -z "$kde_kcfgdir"; then kde_kcfgdir='\${datadir}/config.kcfg' fi if test -z "$kde_mimedir"; then kde_mimedir='\${datadir}/mimelnk' fi if test -z "$kde_toolbardir"; then kde_toolbardir='\${datadir}/toolbar' fi if test -z "$kde_wallpaperdir"; then kde_wallpaperdir='\${datadir}/wallpapers' fi if test -z "$kde_templatesdir"; then kde_templatesdir='\${datadir}/templates' fi if test -z "$kde_bindir"; then kde_bindir='\${exec_prefix}/bin' fi if test -z "$kde_servicesdir"; then kde_servicesdir='\${datadir}/services' fi if test -z "$kde_servicetypesdir"; then kde_servicetypesdir='\${datadir}/servicetypes' fi if test -z "$kde_moduledir"; then if test "$kde_qtver" = "2"; then kde_moduledir='\${libdir}/kde2' else kde_moduledir='\${libdir}/kde3' fi fi if test -z "$kde_styledir"; then kde_styledir='\${libdir}/kde3/plugins/styles' fi if test -z "$kde_widgetdir"; then kde_widgetdir='\${libdir}/kde3/plugins/designer' fi if test -z "$xdg_appsdir"; then xdg_appsdir='\${datadir}/applications/kde' fi if test -z "$xdg_menudir"; then xdg_menudir='\${sysconfdir}/xdg/menus' fi if test -z "$xdg_directorydir"; then xdg_directorydir='\${datadir}/desktop-directories' fi kde_cv_all_paths="kde_have_all_paths=\"yes\" \ kde_htmldir=\"$kde_htmldir\" \ kde_appsdir=\"$kde_appsdir\" \ kde_icondir=\"$kde_icondir\" \ kde_sounddir=\"$kde_sounddir\" \ kde_datadir=\"$kde_datadir\" \ kde_locale=\"$kde_locale\" \ kde_cgidir=\"$kde_cgidir\" \ kde_confdir=\"$kde_confdir\" \ kde_kcfgdir=\"$kde_kcfgdir\" \ kde_mimedir=\"$kde_mimedir\" \ kde_toolbardir=\"$kde_toolbardir\" \ kde_wallpaperdir=\"$kde_wallpaperdir\" \ kde_templatesdir=\"$kde_templatesdir\" \ kde_bindir=\"$kde_bindir\" \ kde_servicesdir=\"$kde_servicesdir\" \ kde_servicetypesdir=\"$kde_servicetypesdir\" \ kde_moduledir=\"$kde_moduledir\" \ kde_styledir=\"$kde_styledir\" \ kde_widgetdir=\"$kde_widgetdir\" \ xdg_appsdir=\"$xdg_appsdir\" \ xdg_menudir=\"$xdg_menudir\" \ xdg_directorydir=\"$xdg_directorydir\" \ kde_result=defaults" else if test $kde_qtver = 1; then { echo "$as_me:$LINENO: result: compiling" >&5 echo "${ECHO_T}compiling" >&6; } { echo "$as_me:$LINENO: checking for KDE headers installed" >&5 echo $ECHO_N "checking for KDE headers installed... $ECHO_C" >&6; } ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cat > conftest.$ac_ext < #endif #include #include "confdefs.h" #include int main() { printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data()); printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data()); printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data()); printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data()); printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data()); printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data()); printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data()); printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data()); printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data()); printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data()); printf("kde_wallpaperdir=\\"%s\\"\n", KApplication::kde_wallpaperdir().data()); printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data()); printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data()); printf("kde_servicesdir=\\"/tmp/dummy\\"\n"); printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n"); printf("kde_moduledir=\\"/tmp/dummy\\"\n"); printf("kde_styledir=\\"/tmp/dummy\\"\n"); printf("kde_widgetdir=\\"/tmp/dummy\\"\n"); printf("xdg_appsdir=\\"/tmp/dummy\\"\n"); printf("xdg_menudir=\\"/tmp/dummy\\"\n"); printf("xdg_directorydir=\\"/tmp/dummy\\"\n"); printf("kde_kcfgdir=\\"/tmp/dummy\\"\n"); return 0; } EOF ac_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$all_includes $CPPFLAGS" if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { { echo "$as_me:$LINENO: error: your system is not able to compile a small KDE application! Check, if you installed the KDE header files correctly. For more details about this problem, look at the end of config.log." >&5 echo "$as_me: error: your system is not able to compile a small KDE application! Check, if you installed the KDE header files correctly. For more details about this problem, look at the end of config.log." >&2;} { (exit 1); exit 1; }; } fi CPPFLAGS=$ac_save_CPPFLAGS ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu KDE_TEST_RPATH= if test -n "$USE_RPATH"; then if test -n "$kde_libraries"; then KDE_TEST_RPATH="-R $kde_libraries" fi if test -n "$qt_libraries"; then KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries" fi if test -n "$x_libraries"; then KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries" fi KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH" fi { echo "$as_me:$LINENO: checking for KDE libraries installed" >&5 echo $ECHO_N "checking for KDE libraries installed... $ECHO_C" >&6; } ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5' if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { { echo "$as_me:$LINENO: error: your system fails at linking a small KDE application! Check, if your compiler is installed correctly and if you have used the same compiler to compile Qt and kdelibs as you did use now. For more details about this problem, look at the end of config.log." >&5 echo "$as_me: error: your system fails at linking a small KDE application! Check, if your compiler is installed correctly and if you have used the same compiler to compile Qt and kdelibs as you did use now. For more details about this problem, look at the end of config.log." >&2;} { (exit 1); exit 1; }; } fi if eval `KDEDIR= ./conftest 2>&5`; then kde_result=done else kde_result=problems fi KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log kde_have_all_paths=yes kde_cv_all_paths="kde_have_all_paths=\"yes\" \ kde_htmldir=\"$kde_htmldir\" \ kde_appsdir=\"$kde_appsdir\" \ kde_icondir=\"$kde_icondir\" \ kde_sounddir=\"$kde_sounddir\" \ kde_datadir=\"$kde_datadir\" \ kde_locale=\"$kde_locale\" \ kde_cgidir=\"$kde_cgidir\" \ kde_confdir=\"$kde_confdir\" \ kde_kcfgdir=\"$kde_kcfgdir\" \ kde_mimedir=\"$kde_mimedir\" \ kde_toolbardir=\"$kde_toolbardir\" \ kde_wallpaperdir=\"$kde_wallpaperdir\" \ kde_templatesdir=\"$kde_templatesdir\" \ kde_bindir=\"$kde_bindir\" \ kde_servicesdir=\"$kde_servicesdir\" \ kde_servicetypesdir=\"$kde_servicetypesdir\" \ kde_moduledir=\"$kde_moduledir\" \ kde_styledir=\"$kde_styledir\" \ kde_widgetdir=\"$kde_widgetdir\" \ xdg_appsdir=\"$xdg_appsdir\" \ xdg_menudir=\"$xdg_menudir\" \ xdg_directorydir=\"$xdg_directorydir\" \ kde_result=$kde_result" else { { echo "$as_me:$LINENO: error: path checking not yet supported for KDE 2" >&5 echo "$as_me: error: path checking not yet supported for KDE 2" >&2;} { (exit 1); exit 1; }; } fi fi kde_cached_paths=no fi eval "$kde_cv_all_paths" if test -z "$kde_htmldir" || test -z "$kde_appsdir" || test -z "$kde_icondir" || test -z "$kde_sounddir" || test -z "$kde_datadir" || test -z "$kde_locale" || test -z "$kde_cgidir" || test -z "$kde_confdir" || test -z "$kde_kcfgdir" || test -z "$kde_mimedir" || test -z "$kde_toolbardir" || test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" || test -z "$kde_bindir" || test -z "$kde_servicesdir" || test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" || test -z "$kde_styledir" || test -z "kde_widgetdir" || test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_directorydir" || test "x$kde_have_all_paths" != "xyes"; then kde_have_all_paths=no fi if test "$kde_have_all_paths" = "no" && test "$kde_cached_paths" = "yes"; then # wrong values were cached, may be, we can set better ones kde_result= kde_htmldir= kde_appsdir= kde_icondir= kde_sounddir= kde_datadir= kde_locale= kde_cgidir= kde_confdir= kde_kcfgdir= kde_mimedir= kde_toolbardir= kde_wallpaperdir= kde_templatesdir= kde_bindir= kde_servicesdir= kde_servicetypesdir= kde_moduledir= kde_have_all_paths= kde_styledir= kde_widgetdir= xdg_appsdir = xdg_menudir= xdg_directorydir= if test "$ac_use_path_checking" = "default"; then if test -z "$kde_htmldir"; then kde_htmldir='\${datadir}/doc/HTML' fi if test -z "$kde_appsdir"; then kde_appsdir='\${datadir}/applnk' fi if test -z "$kde_icondir"; then kde_icondir='\${datadir}/icons' fi if test -z "$kde_sounddir"; then kde_sounddir='\${datadir}/sounds' fi if test -z "$kde_datadir"; then kde_datadir='\${datadir}/apps' fi if test -z "$kde_locale"; then kde_locale='\${datadir}/locale' fi if test -z "$kde_cgidir"; then kde_cgidir='\${exec_prefix}/cgi-bin' fi if test -z "$kde_confdir"; then kde_confdir='\${datadir}/config' fi if test -z "$kde_kcfgdir"; then kde_kcfgdir='\${datadir}/config.kcfg' fi if test -z "$kde_mimedir"; then kde_mimedir='\${datadir}/mimelnk' fi if test -z "$kde_toolbardir"; then kde_toolbardir='\${datadir}/toolbar' fi if test -z "$kde_wallpaperdir"; then kde_wallpaperdir='\${datadir}/wallpapers' fi if test -z "$kde_templatesdir"; then kde_templatesdir='\${datadir}/templates' fi if test -z "$kde_bindir"; then kde_bindir='\${exec_prefix}/bin' fi if test -z "$kde_servicesdir"; then kde_servicesdir='\${datadir}/services' fi if test -z "$kde_servicetypesdir"; then kde_servicetypesdir='\${datadir}/servicetypes' fi if test -z "$kde_moduledir"; then if test "$kde_qtver" = "2"; then kde_moduledir='\${libdir}/kde2' else kde_moduledir='\${libdir}/kde3' fi fi if test -z "$kde_styledir"; then kde_styledir='\${libdir}/kde3/plugins/styles' fi if test -z "$kde_widgetdir"; then kde_widgetdir='\${libdir}/kde3/plugins/designer' fi if test -z "$xdg_appsdir"; then xdg_appsdir='\${datadir}/applications/kde' fi if test -z "$xdg_menudir"; then xdg_menudir='\${sysconfdir}/xdg/menus' fi if test -z "$xdg_directorydir"; then xdg_directorydir='\${datadir}/desktop-directories' fi kde_cv_all_paths="kde_have_all_paths=\"yes\" \ kde_htmldir=\"$kde_htmldir\" \ kde_appsdir=\"$kde_appsdir\" \ kde_icondir=\"$kde_icondir\" \ kde_sounddir=\"$kde_sounddir\" \ kde_datadir=\"$kde_datadir\" \ kde_locale=\"$kde_locale\" \ kde_cgidir=\"$kde_cgidir\" \ kde_confdir=\"$kde_confdir\" \ kde_kcfgdir=\"$kde_kcfgdir\" \ kde_mimedir=\"$kde_mimedir\" \ kde_toolbardir=\"$kde_toolbardir\" \ kde_wallpaperdir=\"$kde_wallpaperdir\" \ kde_templatesdir=\"$kde_templatesdir\" \ kde_bindir=\"$kde_bindir\" \ kde_servicesdir=\"$kde_servicesdir\" \ kde_servicetypesdir=\"$kde_servicetypesdir\" \ kde_moduledir=\"$kde_moduledir\" \ kde_styledir=\"$kde_styledir\" \ kde_widgetdir=\"$kde_widgetdir\" \ xdg_appsdir=\"$xdg_appsdir\" \ xdg_menudir=\"$xdg_menudir\" \ xdg_directorydir=\"$xdg_directorydir\" \ kde_result=defaults" else if test $kde_qtver = 1; then { echo "$as_me:$LINENO: result: compiling" >&5 echo "${ECHO_T}compiling" >&6; } { echo "$as_me:$LINENO: checking for KDE headers installed" >&5 echo $ECHO_N "checking for KDE headers installed... $ECHO_C" >&6; } ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cat > conftest.$ac_ext < #endif #include #include "confdefs.h" #include int main() { printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data()); printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data()); printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data()); printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data()); printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data()); printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data()); printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data()); printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data()); printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data()); printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data()); printf("kde_wallpaperdir=\\"%s\\"\n", KApplication::kde_wallpaperdir().data()); printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data()); printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data()); printf("kde_servicesdir=\\"/tmp/dummy\\"\n"); printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n"); printf("kde_moduledir=\\"/tmp/dummy\\"\n"); printf("kde_styledir=\\"/tmp/dummy\\"\n"); printf("kde_widgetdir=\\"/tmp/dummy\\"\n"); printf("xdg_appsdir=\\"/tmp/dummy\\"\n"); printf("xdg_menudir=\\"/tmp/dummy\\"\n"); printf("xdg_directorydir=\\"/tmp/dummy\\"\n"); printf("kde_kcfgdir=\\"/tmp/dummy\\"\n"); return 0; } EOF ac_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$all_includes $CPPFLAGS" if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { { echo "$as_me:$LINENO: error: your system is not able to compile a small KDE application! Check, if you installed the KDE header files correctly. For more details about this problem, look at the end of config.log." >&5 echo "$as_me: error: your system is not able to compile a small KDE application! Check, if you installed the KDE header files correctly. For more details about this problem, look at the end of config.log." >&2;} { (exit 1); exit 1; }; } fi CPPFLAGS=$ac_save_CPPFLAGS ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu KDE_TEST_RPATH= if test -n "$USE_RPATH"; then if test -n "$kde_libraries"; then KDE_TEST_RPATH="-R $kde_libraries" fi if test -n "$qt_libraries"; then KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries" fi if test -n "$x_libraries"; then KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries" fi KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH" fi { echo "$as_me:$LINENO: checking for KDE libraries installed" >&5 echo $ECHO_N "checking for KDE libraries installed... $ECHO_C" >&6; } ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5' if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { { echo "$as_me:$LINENO: error: your system fails at linking a small KDE application! Check, if your compiler is installed correctly and if you have used the same compiler to compile Qt and kdelibs as you did use now. For more details about this problem, look at the end of config.log." >&5 echo "$as_me: error: your system fails at linking a small KDE application! Check, if your compiler is installed correctly and if you have used the same compiler to compile Qt and kdelibs as you did use now. For more details about this problem, look at the end of config.log." >&2;} { (exit 1); exit 1; }; } fi if eval `KDEDIR= ./conftest 2>&5`; then kde_result=done else kde_result=problems fi KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log kde_have_all_paths=yes kde_cv_all_paths="kde_have_all_paths=\"yes\" \ kde_htmldir=\"$kde_htmldir\" \ kde_appsdir=\"$kde_appsdir\" \ kde_icondir=\"$kde_icondir\" \ kde_sounddir=\"$kde_sounddir\" \ kde_datadir=\"$kde_datadir\" \ kde_locale=\"$kde_locale\" \ kde_cgidir=\"$kde_cgidir\" \ kde_confdir=\"$kde_confdir\" \ kde_kcfgdir=\"$kde_kcfgdir\" \ kde_mimedir=\"$kde_mimedir\" \ kde_toolbardir=\"$kde_toolbardir\" \ kde_wallpaperdir=\"$kde_wallpaperdir\" \ kde_templatesdir=\"$kde_templatesdir\" \ kde_bindir=\"$kde_bindir\" \ kde_servicesdir=\"$kde_servicesdir\" \ kde_servicetypesdir=\"$kde_servicetypesdir\" \ kde_moduledir=\"$kde_moduledir\" \ kde_styledir=\"$kde_styledir\" \ kde_widgetdir=\"$kde_widgetdir\" \ xdg_appsdir=\"$xdg_appsdir\" \ xdg_menudir=\"$xdg_menudir\" \ xdg_directorydir=\"$xdg_directorydir\" \ kde_result=$kde_result" else { { echo "$as_me:$LINENO: error: path checking not yet supported for KDE 2" >&5 echo "$as_me: error: path checking not yet supported for KDE 2" >&2;} { (exit 1); exit 1; }; } fi fi eval "$kde_cv_all_paths" if test -z "$kde_htmldir" || test -z "$kde_appsdir" || test -z "$kde_icondir" || test -z "$kde_sounddir" || test -z "$kde_datadir" || test -z "$kde_locale" || test -z "$kde_cgidir" || test -z "$kde_confdir" || test -z "$kde_kcfgdir" || test -z "$kde_mimedir" || test -z "$kde_toolbardir" || test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" || test -z "$kde_bindir" || test -z "$kde_servicesdir" || test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" || test -z "$kde_styledir" || test -z "kde_widgetdir" || test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_directorydir" || test "x$kde_have_all_paths" != "xyes"; then kde_have_all_paths=no fi kde_result="$kde_result (cache overridden)" fi if test "$kde_have_all_paths" = "no"; then { { echo "$as_me:$LINENO: error: configure could not run a little KDE program to test the environment. Since it had compiled and linked before, it must be a strange problem on your system. Look at config.log for details. If you are not able to fix this, look at http://www.kde.org/faq/installation.html or any www.kde.org mirror. (If you're using an egcs version on Linux, you may update binutils!) " >&5 echo "$as_me: error: configure could not run a little KDE program to test the environment. Since it had compiled and linked before, it must be a strange problem on your system. Look at config.log for details. If you are not able to fix this, look at http://www.kde.org/faq/installation.html or any www.kde.org mirror. (If you're using an egcs version on Linux, you may update binutils!) " >&2;} { (exit 1); exit 1; }; } else rm -f conftest* { echo "$as_me:$LINENO: result: $kde_result" >&5 echo "${ECHO_T}$kde_result" >&6; } fi bindir=$kde_bindir # Check whether --with-arts was given. if test "${with_arts+set}" = set; then withval=$with_arts; build_arts=$withval else build_arts=yes fi if test "$build_arts" '!=' "no"; then include_ARTS_TRUE= include_ARTS_FALSE='#' else include_ARTS_TRUE='#' include_ARTS_FALSE= fi if test "$build_arts" = "no"; then cat >>confdefs.h <<\_ACEOF #define WITHOUT_ARTS 1 _ACEOF fi kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin" test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs" if test -n "$KDEDIRS"; then kde_save_IFS=$IFS IFS=: for dir in $KDEDIRS; do kde_default_bindirs="$dir/bin $kde_default_bindirs " done IFS=$kde_save_IFS fi kde_default_bindirs="$exec_prefix/bin $prefix/bin $kde_libs_prefix/bin $kde_default_bindirs" { echo "$as_me:$LINENO: checking for dcopidl" >&5 echo $ECHO_N "checking for dcopidl... $ECHO_C" >&6; } if test -n "$DCOPIDL"; then kde_cv_path="$DCOPIDL"; else kde_cache=`echo dcopidl | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/dcopidl"; then if test -n "" then evalstr="$dir/dcopidl 2>&1 " if eval $evalstr; then kde_cv_path="$dir/dcopidl" break fi else kde_cv_path="$dir/dcopidl" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program dcopidl was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program dcopidl was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } DCOPIDL=$kde_cv_path fi { echo "$as_me:$LINENO: checking for dcopidl2cpp" >&5 echo $ECHO_N "checking for dcopidl2cpp... $ECHO_C" >&6; } if test -n "$DCOPIDL2CPP"; then kde_cv_path="$DCOPIDL2CPP"; else kde_cache=`echo dcopidl2cpp | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/dcopidl2cpp"; then if test -n "" then evalstr="$dir/dcopidl2cpp 2>&1 " if eval $evalstr; then kde_cv_path="$dir/dcopidl2cpp" break fi else kde_cv_path="$dir/dcopidl2cpp" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program dcopidl2cpp was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program dcopidl2cpp was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } DCOPIDL2CPP=$kde_cv_path fi if test "$build_arts" '!=' "no"; then { echo "$as_me:$LINENO: checking for mcopidl" >&5 echo $ECHO_N "checking for mcopidl... $ECHO_C" >&6; } if test -n "$MCOPIDL"; then kde_cv_path="$MCOPIDL"; else kde_cache=`echo mcopidl | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/mcopidl"; then if test -n "" then evalstr="$dir/mcopidl 2>&1 " if eval $evalstr; then kde_cv_path="$dir/mcopidl" break fi else kde_cv_path="$dir/mcopidl" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program mcopidl was not found! Please check whether you installed aRts correctly or use --without-arts to compile without aRts support (this will remove functionality). " >&5 echo "$as_me: error: The important program mcopidl was not found! Please check whether you installed aRts correctly or use --without-arts to compile without aRts support (this will remove functionality). " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } MCOPIDL=$kde_cv_path fi { echo "$as_me:$LINENO: checking for artsc-config" >&5 echo $ECHO_N "checking for artsc-config... $ECHO_C" >&6; } if test -n "$ARTSCCONFIG"; then kde_cv_path="$ARTSCCONFIG"; else kde_cache=`echo artsc-config | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/artsc-config"; then if test -n "" then evalstr="$dir/artsc-config 2>&1 " if eval $evalstr; then kde_cv_path="$dir/artsc-config" break fi else kde_cv_path="$dir/artsc-config" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program artsc-config was not found! Please check whether you installed aRts correctly or use --without-arts to compile without aRts support (this will remove functionality). " >&5 echo "$as_me: error: The important program artsc-config was not found! Please check whether you installed aRts correctly or use --without-arts to compile without aRts support (this will remove functionality). " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } ARTSCCONFIG=$kde_cv_path fi fi { echo "$as_me:$LINENO: checking for meinproc" >&5 echo $ECHO_N "checking for meinproc... $ECHO_C" >&6; } if test -n "$MEINPROC"; then kde_cv_path="$MEINPROC"; else kde_cache=`echo meinproc | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/meinproc"; then if test -n "" then evalstr="$dir/meinproc 2>&1 " if eval $evalstr; then kde_cv_path="$dir/meinproc" break fi else kde_cv_path="$dir/meinproc" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } MEINPROC=$kde_cv_path fi kde32ornewer=1 kde33ornewer=1 if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then kde32ornewer= kde33ornewer= else if test "$kde_qtver" = "3"; then if test "$kde_qtsubver" -le 1; then kde32ornewer= fi if test "$kde_qtsubver" -le 2; then kde33ornewer= fi fi fi if test -n "$kde32ornewer"; then { echo "$as_me:$LINENO: checking for kconfig_compiler" >&5 echo $ECHO_N "checking for kconfig_compiler... $ECHO_C" >&6; } if test -n "$KCONFIG_COMPILER"; then kde_cv_path="$KCONFIG_COMPILER"; else kde_cache=`echo kconfig_compiler | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/kconfig_compiler"; then if test -n "" then evalstr="$dir/kconfig_compiler 2>&1 " if eval $evalstr; then kde_cv_path="$dir/kconfig_compiler" break fi else kde_cv_path="$dir/kconfig_compiler" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program kconfig_compiler was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program kconfig_compiler was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } KCONFIG_COMPILER=$kde_cv_path fi { echo "$as_me:$LINENO: checking for dcopidlng" >&5 echo $ECHO_N "checking for dcopidlng... $ECHO_C" >&6; } if test -n "$DCOPIDLNG"; then kde_cv_path="$DCOPIDLNG"; else kde_cache=`echo dcopidlng | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/dcopidlng"; then if test -n "" then evalstr="$dir/dcopidlng 2>&1 " if eval $evalstr; then kde_cv_path="$dir/dcopidlng" break fi else kde_cv_path="$dir/dcopidlng" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program dcopidlng was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program dcopidlng was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } DCOPIDLNG=$kde_cv_path fi fi if test -n "$kde33ornewer"; then { echo "$as_me:$LINENO: checking for makekdewidgets" >&5 echo $ECHO_N "checking for makekdewidgets... $ECHO_C" >&6; } if test -n "$MAKEKDEWIDGETS"; then kde_cv_path="$MAKEKDEWIDGETS"; else kde_cache=`echo makekdewidgets | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="$kde_default_bindirs $dirs" else dirs="$dirs $kde_default_bindirs" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/makekdewidgets"; then if test -n "" then evalstr="$dir/makekdewidgets 2>&1 " if eval $evalstr; then kde_cv_path="$dir/makekdewidgets" break fi else kde_cv_path="$dir/makekdewidgets" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: The important program makekdewidgets was not found! Please check whether you installed KDE correctly. " >&5 echo "$as_me: error: The important program makekdewidgets was not found! Please check whether you installed KDE correctly. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } MAKEKDEWIDGETS=$kde_cv_path fi fi { echo "$as_me:$LINENO: checking for xmllint" >&5 echo $ECHO_N "checking for xmllint... $ECHO_C" >&6; } if test -n "$XMLLINT"; then kde_cv_path="$XMLLINT"; else kde_cache=`echo xmllint | sed 'y%./+-%__p_%'` if { as_var=kde_cv_path_$kde_cache; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z ""; then dirs="${prefix}/bin ${exec_prefix}/bin $dirs" else dirs="$dirs ${prefix}/bin ${exec_prefix}/bin" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/xmllint"; then if test -n "" then evalstr="$dir/xmllint 2>&1 " if eval $evalstr; then kde_cv_path="$dir/xmllint" break fi else kde_cv_path="$dir/xmllint" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" fi eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } XMLLINT="" else { echo "$as_me:$LINENO: result: $kde_cv_path" >&5 echo "${ECHO_T}$kde_cv_path" >&6; } XMLLINT=$kde_cv_path fi if test -n "$MEINPROC" && test ! "$MEINPROC" = "compiled"; then kde_sharedirs="/usr/share/kde /usr/local/share /usr/share /opt/kde3/share /opt/kde/share $prefix/share" test -n "$KDEDIR" && kde_sharedirs="$KDEDIR/share $kde_sharedirs" KDE_XSL_STYLESHEET=NO for i in $kde_sharedirs; do for j in apps/ksgmltools2/customization/kde-chunk.xsl; do echo "configure: 18770: $i/$j" >&5 if test -r "$i/$j"; then echo "taking that" >&5 KDE_XSL_STYLESHEET=$i break 2 fi done done if test "$KDE_XSL_STYLESHEET" = "NO"; then KDE_XSL_STYLESHEET="" else KDE_XSL_STYLESHEET="$KDE_XSL_STYLESHEET/apps/ksgmltools2/customization/kde-chunk.xsl" fi fi DCOP_DEPENDENCIES='$(DCOPIDL)' if test -n "$kde32ornewer"; then KCFG_DEPENDENCIES='$(KCONFIG_COMPILER)' DCOP_DEPENDENCIES='$(DCOPIDL) $(DCOPIDLNG)' fi kdeinitdir='$(kde_moduledir)' if test "$kde_qtver" = 1; then kde_minidir="$kde_icondir/mini" else # for KDE 1 - this breaks KDE2 apps using minidir, but # that's the plan ;-/ kde_minidir="/dev/null" fi if test $kde_qtver = 3; then LIB_KDECORE="-lkdecore" LIB_KDEUI="-lkdeui" LIB_KIO="-lkio" LIB_KJS="-lkjs" LIB_SMB="-lsmb" LIB_KAB="-lkab" LIB_KABC="-lkabc" LIB_KHTML="-lkhtml" LIB_KSPELL="-lkspell" LIB_KPARTS="-lkparts" LIB_KDEPRINT="-lkdeprint" LIB_KUTILS="-lkutils" LIB_KDEPIM="-lkdepim" LIB_KIMPROXY="-lkimproxy" LIB_KNEWSTUFF="-lknewstuff" LIB_KDNSSD="-lkdnssd" # these are for backward compatibility LIB_KSYCOCA="-lkio" LIB_KFILE="-lkio" elif test $kde_qtver = 2; then LIB_KDECORE="-lkdecore" LIB_KDEUI="-lkdeui" LIB_KIO="-lkio" LIB_KSYCOCA="-lksycoca" LIB_SMB="-lsmb" LIB_KFILE="-lkfile" LIB_KAB="-lkab" LIB_KHTML="-lkhtml" LIB_KSPELL="-lkspell" LIB_KPARTS="-lkparts" LIB_KDEPRINT="-lkdeprint" else LIB_KDECORE="-lkdecore -lXext $(LIB_QT)" LIB_KDEUI="-lkdeui $(LIB_KDECORE)" LIB_KFM="-lkfm $(LIB_KDECORE)" LIB_KFILE="-lkfile $(LIB_KFM) $(LIB_KDEUI)" LIB_KAB="-lkab $(LIB_KIMGIO) $(LIB_KDECORE)" fi as_ac_File=`echo "ac_cv_file_${kde_includes}/kapplication.h" | $as_tr_sh` { echo "$as_me:$LINENO: checking for ${kde_includes}/kapplication.h" >&5 echo $ECHO_N "checking for ${kde_includes}/kapplication.h... $ECHO_C" >&6; } if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else test "$cross_compiling" = yes && { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} { (exit 1); exit 1; }; } if test -r "${kde_includes}/kapplication.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi ac_res=`eval echo '${'$as_ac_File'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_File'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_${kde_includes}/kapplication.h" | $as_tr_cpp` 1 _ACEOF else { { echo "$as_me:$LINENO: error: kde header files missing (kdelibs3-devel package)" >&5 echo "$as_me: error: kde header files missing (kdelibs3-devel package)" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<\_ACEOF #define HAVE_KDE 1 _ACEOF echo "INCLUDEPATH += ${kde_includes}" >> $QT_INCL_PRO echo "LIBS += -L${kde_libraries} -lkdecore -lkdeui" >> $QT_INCL_PRO echo "LIBS += -L${TWINKLE_KDE_PREFIX}/lib -lkabc" >> $QT_INCL_PRO else include_x11_FALSE="yes" include_ARTS_FALSE="yes" fi # Check for libbbind or libresolv. libbind is preferred as libresolv gives # GLIBC_PRIVATE on Fedora. { echo "$as_me:$LINENO: checking for main in -lbind" >&5 echo $ECHO_N "checking for main in -lbind... $ECHO_C" >&6; } if test "${ac_cv_lib_bind_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbind $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bind_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bind_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bind_main" >&5 echo "${ECHO_T}$ac_cv_lib_bind_main" >&6; } if test $ac_cv_lib_bind_main = yes; then LIBS="-lbind $LIBS" echo "LIBS += -lbind" >> $QT_INCL_PRO else LIBS="-lresolv $LIBS" echo "LIBS += -lresolv" >> $QT_INCL_PRO fi # Check if sndfile library is available if test "${ac_cv_header_sndfile_h+set}" = set; then { echo "$as_me:$LINENO: checking for sndfile.h" >&5 echo $ECHO_N "checking for sndfile.h... $ECHO_C" >&6; } if test "${ac_cv_header_sndfile_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_sndfile_h" >&5 echo "${ECHO_T}$ac_cv_header_sndfile_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking sndfile.h usability" >&5 echo $ECHO_N "checking sndfile.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking sndfile.h presence" >&5 echo $ECHO_N "checking sndfile.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sndfile.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sndfile.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sndfile.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sndfile.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sndfile.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sndfile.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sndfile.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sndfile.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sndfile.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sndfile.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sndfile.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sndfile.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sndfile.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sndfile.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sndfile.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sndfile.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for sndfile.h" >&5 echo $ECHO_N "checking for sndfile.h... $ECHO_C" >&6; } if test "${ac_cv_header_sndfile_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sndfile_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_sndfile_h" >&5 echo "${ECHO_T}$ac_cv_header_sndfile_h" >&6; } fi if test $ac_cv_header_sndfile_h = yes; then : else { { echo "$as_me:$LINENO: error: sndfile header files missing (libsndfile-devel package)" >&5 echo "$as_me: error: sndfile header files missing (libsndfile-devel package)" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for sf_open in -lsndfile" >&5 echo $ECHO_N "checking for sf_open in -lsndfile... $ECHO_C" >&6; } if test "${ac_cv_lib_sndfile_sf_open+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsndfile $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sf_open (); int main () { return sf_open (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_sndfile_sf_open=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_sndfile_sf_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_sndfile_sf_open" >&5 echo "${ECHO_T}$ac_cv_lib_sndfile_sf_open" >&6; } if test $ac_cv_lib_sndfile_sf_open = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSNDFILE 1 _ACEOF LIBS="-lsndfile $LIBS" else { { echo "$as_me:$LINENO: error: libsndfile library is missing." >&5 echo "$as_me: error: libsndfile library is missing." >&2;} { (exit 1); exit 1; }; } fi # Check if magic library is available if test "${ac_cv_header_magic_h+set}" = set; then { echo "$as_me:$LINENO: checking for magic.h" >&5 echo $ECHO_N "checking for magic.h... $ECHO_C" >&6; } if test "${ac_cv_header_magic_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_magic_h" >&5 echo "${ECHO_T}$ac_cv_header_magic_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking magic.h usability" >&5 echo $ECHO_N "checking magic.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking magic.h presence" >&5 echo $ECHO_N "checking magic.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: magic.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: magic.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: magic.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: magic.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: magic.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: magic.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: magic.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: magic.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: magic.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: magic.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: magic.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: magic.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: magic.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: magic.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: magic.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: magic.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for magic.h" >&5 echo $ECHO_N "checking for magic.h... $ECHO_C" >&6; } if test "${ac_cv_header_magic_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_magic_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_magic_h" >&5 echo "${ECHO_T}$ac_cv_header_magic_h" >&6; } fi if test $ac_cv_header_magic_h = yes; then : else { { echo "$as_me:$LINENO: error: magic.h is missing (file-devel or libmagic-dev package)" >&5 echo "$as_me: error: magic.h is missing (file-devel or libmagic-dev package)" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for magic_open in -lmagic" >&5 echo $ECHO_N "checking for magic_open in -lmagic... $ECHO_C" >&6; } if test "${ac_cv_lib_magic_magic_open+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmagic $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char magic_open (); int main () { return magic_open (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_magic_magic_open=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_magic_magic_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_magic_magic_open" >&5 echo "${ECHO_T}$ac_cv_lib_magic_magic_open" >&6; } if test $ac_cv_lib_magic_magic_open = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBMAGIC 1 _ACEOF LIBS="-lmagic $LIBS" else { { echo "$as_me:$LINENO: error: libmagic library is missing (file or libmagic package)" >&5 echo "$as_me: error: libmagic library is missing (file or libmagic package)" >&2;} { (exit 1); exit 1; }; } fi # This check does not work on all platforms # Check if libgsm is available # AC_CHECK_LIB(gsm, sf_open, [ # AC_CHECK_HEADER(gsm.h, [], # [AC_MSG_ERROR([gsm header files missing (gsm.h)])]) # AC_DEFINE(HAVE_GSM, 1, [Define to 1 if you have the library.]) # GSM_LIBS="-lgsm" # echo "LIBS += -lgsm" >> $QT_INCL_PRO # have_gsm="yes" ], [ # have_gsm="no" # GSM_LIBS="\$(top_builddir)/src/audio/gsm/libgsm.a" # echo "LIBS += ../audio/gsm/libgsm.a" >> $QT_INCL_PRO ]) have_gsm="no" GSM_LIBS="\$(top_builddir)/src/audio/gsm/libgsm.a" echo "LIBS += ../audio/gsm/libgsm.a" >> $QT_INCL_PRO # Check if ALSA is available { echo "$as_me:$LINENO: checking for main in -lasound" >&5 echo $ECHO_N "checking for main in -lasound... $ECHO_C" >&6; } if test "${ac_cv_lib_asound_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lasound $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_asound_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_asound_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_asound_main" >&5 echo "${ECHO_T}$ac_cv_lib_asound_main" >&6; } if test $ac_cv_lib_asound_main = yes; then if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then { echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5 echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6; } if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5 echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking alsa/asoundlib.h usability" >&5 echo $ECHO_N "checking alsa/asoundlib.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking alsa/asoundlib.h presence" >&5 echo $ECHO_N "checking alsa/asoundlib.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5 echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6; } if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_alsa_asoundlib_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5 echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6; } fi if test $ac_cv_header_alsa_asoundlib_h = yes; then : else { { echo "$as_me:$LINENO: error: alsa header files missing (alsa-devel package)" >&5 echo "$as_me: error: alsa header files missing (alsa-devel package)" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<\_ACEOF #define HAVE_LIBASOUND 1 _ACEOF LIBS="-lasound $LIBS" echo "LIBS += -lasound" >> $QT_INCL_PRO have_libasound="yes" else have_libasound="no" fi # Check if SPEEX (libspeex & libspeexdsp) is available if test "x$ac_cv_speex" = "xyes" then { echo "$as_me:$LINENO: checking for main in -lspeex" >&5 echo $ECHO_N "checking for main in -lspeex... $ECHO_C" >&6; } if test "${ac_cv_lib_speex_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lspeex $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_speex_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_speex_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_speex_main" >&5 echo "${ECHO_T}$ac_cv_lib_speex_main" >&6; } if test $ac_cv_lib_speex_main = yes; then if test "${ac_cv_header_speex_speex_h+set}" = set; then { echo "$as_me:$LINENO: checking for speex/speex.h" >&5 echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; } if test "${ac_cv_header_speex_speex_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5 echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking speex/speex.h usability" >&5 echo $ECHO_N "checking speex/speex.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking speex/speex.h presence" >&5 echo $ECHO_N "checking speex/speex.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: speex/speex.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: speex/speex.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: speex/speex.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: speex/speex.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: speex/speex.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: speex/speex.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: speex/speex.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for speex/speex.h" >&5 echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; } if test "${ac_cv_header_speex_speex_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_speex_speex_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5 echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; } fi if test $ac_cv_header_speex_speex_h = yes; then : else { { echo "$as_me:$LINENO: error: speex header files missing" >&5 echo "$as_me: error: speex header files missing" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for main in -lspeexdsp" >&5 echo $ECHO_N "checking for main in -lspeexdsp... $ECHO_C" >&6; } if test "${ac_cv_lib_speexdsp_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lspeexdsp $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_speexdsp_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_speexdsp_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_speexdsp_main" >&5 echo "${ECHO_T}$ac_cv_lib_speexdsp_main" >&6; } if test $ac_cv_lib_speexdsp_main = yes; then for ac_header in speex/speex_preprocess.h speex/speex_echo.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else { { echo "$as_me:$LINENO: error: speexdsp header files missing" >&5 echo "$as_me: error: speexdsp header files missing" >&2;} { (exit 1); exit 1; }; } fi done cat >>confdefs.h <<\_ACEOF #define HAVE_SPEEX 1 _ACEOF LIBS="-lspeex -lspeexdsp $LIBS" echo "LIBS += -lspeex" >> $QT_INCL_PRO echo "LIBS += -lspeexdsp" >> $QT_INCL_PRO have_speex="yes" else have_speex="no" fi else have_speex="no" fi else have_speex="no" fi # iLBC if test "x$ac_cv_ilbc" = "xyes" then { echo "$as_me:$LINENO: checking for iLBC_decode in -lilbc" >&5 echo $ECHO_N "checking for iLBC_decode in -lilbc... $ECHO_C" >&6; } if test "${ac_cv_lib_ilbc_iLBC_decode+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lilbc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char iLBC_decode (); int main () { return iLBC_decode (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ilbc_iLBC_decode=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ilbc_iLBC_decode=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ilbc_iLBC_decode" >&5 echo "${ECHO_T}$ac_cv_lib_ilbc_iLBC_decode" >&6; } if test $ac_cv_lib_ilbc_iLBC_decode = yes; then if test "${ac_cv_header_ilbc_iLBC_define_h+set}" = set; then { echo "$as_me:$LINENO: checking for ilbc/iLBC_define.h" >&5 echo $ECHO_N "checking for ilbc/iLBC_define.h... $ECHO_C" >&6; } if test "${ac_cv_header_ilbc_iLBC_define_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_ilbc_iLBC_define_h" >&5 echo "${ECHO_T}$ac_cv_header_ilbc_iLBC_define_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking ilbc/iLBC_define.h usability" >&5 echo $ECHO_N "checking ilbc/iLBC_define.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking ilbc/iLBC_define.h presence" >&5 echo $ECHO_N "checking ilbc/iLBC_define.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: ilbc/iLBC_define.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: ilbc/iLBC_define.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for ilbc/iLBC_define.h" >&5 echo $ECHO_N "checking for ilbc/iLBC_define.h... $ECHO_C" >&6; } if test "${ac_cv_header_ilbc_iLBC_define_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_ilbc_iLBC_define_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_ilbc_iLBC_define_h" >&5 echo "${ECHO_T}$ac_cv_header_ilbc_iLBC_define_h" >&6; } fi if test $ac_cv_header_ilbc_iLBC_define_h = yes; then : else { { echo "$as_me:$LINENO: error: ilbc header files missing" >&5 echo "$as_me: error: ilbc header files missing" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<\_ACEOF #define HAVE_ILBC 1 _ACEOF LIBS="-lilbc $LIBS" echo "LIBS += -lilbc" >> $QT_INCL_PRO have_ilbc="yes" else have_ilbc="no" fi if test "x$ac_cv_ilbc_cpp" = "xyes" then cat >>confdefs.h <<\_ACEOF #define HAVE_ILBC_CPP 1 _ACEOF fi else have_ilbc="no" fi # Check if zrtp is available if test "x$ac_cv_zrtp" = "xyes" then succeeded=no if test -z "$PKG_CONFIG"; then # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 echo "${ECHO_T}$PKG_CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test "$PKG_CONFIG" = "no" ; then echo "*** The pkg-config script could not be found. Make sure it is" echo "*** in your path, or set the PKG_CONFIG environment variable" echo "*** to the full path to pkg-config." echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." else PKG_CONFIG_MIN_VERSION=0.9.0 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then { echo "$as_me:$LINENO: checking for libzrtpcpp >= 1.3.0" >&5 echo $ECHO_N "checking for libzrtpcpp >= 1.3.0... $ECHO_C" >&6; } if $PKG_CONFIG --exists "libzrtpcpp >= 1.3.0" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } succeeded=yes { echo "$as_me:$LINENO: checking ZRTP_CFLAGS" >&5 echo $ECHO_N "checking ZRTP_CFLAGS... $ECHO_C" >&6; } ZRTP_CFLAGS=`$PKG_CONFIG --cflags "libzrtpcpp >= 1.3.0"` { echo "$as_me:$LINENO: result: $ZRTP_CFLAGS" >&5 echo "${ECHO_T}$ZRTP_CFLAGS" >&6; } { echo "$as_me:$LINENO: checking ZRTP_LIBS" >&5 echo $ECHO_N "checking ZRTP_LIBS... $ECHO_C" >&6; } ZRTP_LIBS=`$PKG_CONFIG --libs "libzrtpcpp >= 1.3.0"` { echo "$as_me:$LINENO: result: $ZRTP_LIBS" >&5 echo "${ECHO_T}$ZRTP_LIBS" >&6; } else ZRTP_CFLAGS="" ZRTP_LIBS="" ## If we have a custom action on failure, don't print errors, but ## do set a variable so people can do so. ZRTP_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libzrtpcpp >= 1.3.0"` echo $ZRTP_PKG_ERRORS fi else echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." echo "*** See http://www.freedesktop.org/software/pkgconfig" fi fi if test $succeeded = yes; then : else { { echo "$as_me:$LINENO: error: Library requirements (libzrtpcpp >= 1.3.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 echo "$as_me: error: Library requirements (libzrtpcpp >= 1.3.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for main in -lzrtpcpp" >&5 echo $ECHO_N "checking for main in -lzrtpcpp... $ECHO_C" >&6; } if test "${ac_cv_lib_zrtpcpp_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lzrtpcpp $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_zrtpcpp_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_zrtpcpp_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_zrtpcpp_main" >&5 echo "${ECHO_T}$ac_cv_lib_zrtpcpp_main" >&6; } if test $ac_cv_lib_zrtpcpp_main = yes; then if test "${ac_cv_header_libzrtpcpp_ZrtpQueue_h+set}" = set; then { echo "$as_me:$LINENO: checking for libzrtpcpp/ZrtpQueue.h" >&5 echo $ECHO_N "checking for libzrtpcpp/ZrtpQueue.h... $ECHO_C" >&6; } if test "${ac_cv_header_libzrtpcpp_ZrtpQueue_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_libzrtpcpp_ZrtpQueue_h" >&5 echo "${ECHO_T}$ac_cv_header_libzrtpcpp_ZrtpQueue_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking libzrtpcpp/ZrtpQueue.h usability" >&5 echo $ECHO_N "checking libzrtpcpp/ZrtpQueue.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking libzrtpcpp/ZrtpQueue.h presence" >&5 echo $ECHO_N "checking libzrtpcpp/ZrtpQueue.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: libzrtpcpp/ZrtpQueue.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: libzrtpcpp/ZrtpQueue.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for libzrtpcpp/ZrtpQueue.h" >&5 echo $ECHO_N "checking for libzrtpcpp/ZrtpQueue.h... $ECHO_C" >&6; } if test "${ac_cv_header_libzrtpcpp_ZrtpQueue_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_libzrtpcpp_ZrtpQueue_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_libzrtpcpp_ZrtpQueue_h" >&5 echo "${ECHO_T}$ac_cv_header_libzrtpcpp_ZrtpQueue_h" >&6; } fi if test $ac_cv_header_libzrtpcpp_ZrtpQueue_h = yes; then : else { { echo "$as_me:$LINENO: error: zrtp header files missing" >&5 echo "$as_me: error: zrtp header files missing" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<\_ACEOF #define HAVE_ZRTP 1 _ACEOF LIBS="-lzrtpcpp $LIBS" echo "LIBS += -lzrtpcpp" >> $QT_INCL_PRO have_zrtp="yes" else have_zrtp="no" fi else have_zrtp="no" fi # check if GNU readline or readline compatible libraries are avaliable { echo "$as_me:$LINENO: checking for a readline compatible library" >&5 echo $ECHO_N "checking for a readline compatible library... $ECHO_C" >&6; } if test "${vl_cv_lib_readline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ORIG_LIBS="$LIBS" for readline_lib in readline edit editline; do for termcap_lib in "" termcap curses ncurses; do if test -z "$termcap_lib"; then TRY_LIB="-l$readline_lib" else TRY_LIB="-l$readline_lib -l$termcap_lib" fi LIBS="$ORIG_LIBS $TRY_LIB" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then vl_cv_lib_readline="$TRY_LIB" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -n "$vl_cv_lib_readline"; then break fi done if test -n "$vl_cv_lib_readline"; then break fi done if test -z "$vl_cv_lib_readline"; then vl_cv_lib_readline="no" LIBS="$ORIG_LIBS" fi fi { echo "$as_me:$LINENO: result: $vl_cv_lib_readline" >&5 echo "${ECHO_T}$vl_cv_lib_readline" >&6; } if test "$vl_cv_lib_readline" != "no"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF for ac_header in readline.h readline/readline.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether readline supports history" >&5 echo $ECHO_N "checking whether readline supports history... $ECHO_C" >&6; } if test "${vl_cv_lib_readline_history+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else vl_cv_lib_readline_history="no" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char add_history (); int main () { return add_history (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then vl_cv_lib_readline_history="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $vl_cv_lib_readline_history" >&5 echo "${ECHO_T}$vl_cv_lib_readline_history" >&6; } if test "$vl_cv_lib_readline_history" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_READLINE_HISTORY 1 _ACEOF for ac_header in history.h readline/history.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done fi fi if test "x$vl_cv_lib_readline" == "xno" then { { echo "$as_me:$LINENO: error: readline-devel package is not installed" >&5 echo "$as_me: error: readline-devel package is not installed" >&2;} { (exit 1); exit 1; }; } fi # Check if boost regex is available if test "${ac_cv_header_boost_regex_h+set}" = set; then { echo "$as_me:$LINENO: checking for boost/regex.h" >&5 echo $ECHO_N "checking for boost/regex.h... $ECHO_C" >&6; } if test "${ac_cv_header_boost_regex_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_boost_regex_h" >&5 echo "${ECHO_T}$ac_cv_header_boost_regex_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking boost/regex.h usability" >&5 echo $ECHO_N "checking boost/regex.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking boost/regex.h presence" >&5 echo $ECHO_N "checking boost/regex.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: boost/regex.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: boost/regex.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: boost/regex.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: boost/regex.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: boost/regex.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: boost/regex.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: boost/regex.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: boost/regex.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: boost/regex.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: boost/regex.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: boost/regex.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: boost/regex.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: boost/regex.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: boost/regex.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: boost/regex.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: boost/regex.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for boost/regex.h" >&5 echo $ECHO_N "checking for boost/regex.h... $ECHO_C" >&6; } if test "${ac_cv_header_boost_regex_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_boost_regex_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_boost_regex_h" >&5 echo "${ECHO_T}$ac_cv_header_boost_regex_h" >&6; } fi if test $ac_cv_header_boost_regex_h = yes; then : else { { echo "$as_me:$LINENO: error: boost/regex.h missing (boost-devel package)" >&5 echo "$as_me: error: boost/regex.h missing (boost-devel package)" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for main in -lboost_regex" >&5 echo $ECHO_N "checking for main in -lboost_regex... $ECHO_C" >&6; } if test "${ac_cv_lib_boost_regex_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lboost_regex $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_boost_regex_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_boost_regex_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_boost_regex_main" >&5 echo "${ECHO_T}$ac_cv_lib_boost_regex_main" >&6; } if test $ac_cv_lib_boost_regex_main = yes; then LIBS="-lboost_regex $LIBS" echo "LIBS += -lboost_regex" >> $QT_INCL_PRO else { echo "$as_me:$LINENO: checking for main in -lboost_regex-gcc" >&5 echo $ECHO_N "checking for main in -lboost_regex-gcc... $ECHO_C" >&6; } if test "${ac_cv_lib_boost_regex_gcc_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lboost_regex-gcc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_boost_regex_gcc_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_boost_regex_gcc_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_boost_regex_gcc_main" >&5 echo "${ECHO_T}$ac_cv_lib_boost_regex_gcc_main" >&6; } if test $ac_cv_lib_boost_regex_gcc_main = yes; then LIBS="-lboost_regex-gcc $LIBS" echo "LIBS += -lboost_regex-gcc" >> $QT_INCL_PRO else { { echo "$as_me:$LINENO: error: libboost_regex library is missing (boost package)." >&5 echo "$as_me: error: libboost_regex library is missing (boost package)." >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: checking LRELEASE OPTIONS" >&5 echo $ECHO_N "checking LRELEASE OPTIONS... $ECHO_C" >&6; } if lrelease -compress /dev/null -qm /dev/null 1>/dev/null 2>&1 then { echo "$as_me:$LINENO: result: compress" >&5 echo "${ECHO_T}compress" >&6; } LRELEASEOPTION="-compress" else { echo "$as_me:$LINENO: result: nocompress" >&5 echo "${ECHO_T}nocompress" >&6; } LRELEASEOPTION="" fi ac_config_commands="$ac_config_commands src/gui/Makefile" ac_config_files="$ac_config_files Makefile src/Makefile src/audio/Makefile src/audio/gsm/Makefile src/audits/Makefile src/sdp/Makefile src/parser/Makefile src/sockets/Makefile src/stun/Makefile src/threads/Makefile src/gui/lang/Makefile src/mwi/Makefile src/im/Makefile src/patterns/Makefile src/utils/Makefile src/presence/Makefile twinkle.spec" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${include_x11_TRUE}" && test -z "${include_x11_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"include_x11\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"include_x11\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${include_ARTS_TRUE}" && test -z "${include_ARTS_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"include_ARTS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"include_ARTS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # Find out whether ``test -x'' works. Don't use a zero-byte file, as # systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then as_executable_p="test -x" else as_executable_p=: fi rm -f conf$$.file # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.60. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.60, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" kde_libraries=${kde_libraries} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/twinkle_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/twinkle_config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "src/gui/Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS src/gui/Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/audio/Makefile") CONFIG_FILES="$CONFIG_FILES src/audio/Makefile" ;; "src/audio/gsm/Makefile") CONFIG_FILES="$CONFIG_FILES src/audio/gsm/Makefile" ;; "src/audits/Makefile") CONFIG_FILES="$CONFIG_FILES src/audits/Makefile" ;; "src/sdp/Makefile") CONFIG_FILES="$CONFIG_FILES src/sdp/Makefile" ;; "src/parser/Makefile") CONFIG_FILES="$CONFIG_FILES src/parser/Makefile" ;; "src/sockets/Makefile") CONFIG_FILES="$CONFIG_FILES src/sockets/Makefile" ;; "src/stun/Makefile") CONFIG_FILES="$CONFIG_FILES src/stun/Makefile" ;; "src/threads/Makefile") CONFIG_FILES="$CONFIG_FILES src/threads/Makefile" ;; "src/gui/lang/Makefile") CONFIG_FILES="$CONFIG_FILES src/gui/lang/Makefile" ;; "src/mwi/Makefile") CONFIG_FILES="$CONFIG_FILES src/mwi/Makefile" ;; "src/im/Makefile") CONFIG_FILES="$CONFIG_FILES src/im/Makefile" ;; "src/patterns/Makefile") CONFIG_FILES="$CONFIG_FILES src/patterns/Makefile" ;; "src/utils/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/Makefile" ;; "src/presence/Makefile") CONFIG_FILES="$CONFIG_FILES src/presence/Makefile" ;; "twinkle.spec") CONFIG_FILES="$CONFIG_FILES twinkle.spec" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim target!$target$ac_delim target_cpu!$target_cpu$ac_delim target_vendor!$target_vendor$ac_delim target_os!$target_os$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim CYGPATH_W!$CYGPATH_W$ac_delim PACKAGE!$PACKAGE$ac_delim VERSION!$VERSION$ac_delim ACLOCAL!$ACLOCAL$ac_delim AUTOCONF!$AUTOCONF$ac_delim AUTOMAKE!$AUTOMAKE$ac_delim AUTOHEADER!$AUTOHEADER$ac_delim MAKEINFO!$MAKEINFO$ac_delim install_sh!$install_sh$ac_delim STRIP!$STRIP$ac_delim INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim mkdir_p!$mkdir_p$ac_delim AWK!$AWK$ac_delim SET_MAKE!$SET_MAKE$ac_delim am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim am__quote!$am__quote$ac_delim AMDEP_TRUE!$AMDEP_TRUE$ac_delim AMDEP_FALSE!$AMDEP_FALSE$ac_delim AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim CCDEPMODE!$CCDEPMODE$ac_delim am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim CXXDEPMODE!$CXXDEPMODE$ac_delim am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim CPP!$CPP$ac_delim CXXCPP!$CXXCPP$ac_delim RANLIB!$RANLIB$ac_delim LEX!$LEX$ac_delim LEXLIB!$LEXLIB$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF LEX_OUTPUT_ROOT!$LEX_OUTPUT_ROOT$ac_delim YACC!$YACC$ac_delim YFLAGS!$YFLAGS$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim CCGNU2_CONFIG!$CCGNU2_CONFIG$ac_delim SINGLE_LIBS!$SINGLE_LIBS$ac_delim SINGLE_FLAGS!$SINGLE_FLAGS$ac_delim GNULIBS!$GNULIBS$ac_delim EXTLIBS!$EXTLIBS$ac_delim PKG_CONFIG!$PKG_CONFIG$ac_delim CCRTP_CFLAGS!$CCRTP_CFLAGS$ac_delim CCRTP_LIBS!$CCRTP_LIBS$ac_delim XML2_CFLAGS!$XML2_CFLAGS$ac_delim XML2_LIBS!$XML2_LIBS$ac_delim QT_CFLAGS!$QT_CFLAGS$ac_delim QT_LIBS!$QT_LIBS$ac_delim LIBUTIL!$LIBUTIL$ac_delim LIBCOMPAT!$LIBCOMPAT$ac_delim LIBCRYPT!$LIBCRYPT$ac_delim LIBRESOLV!$LIBRESOLV$ac_delim LIB_POLL!$LIB_POLL$ac_delim FRAMEWORK_COREAUDIO!$FRAMEWORK_COREAUDIO$ac_delim LIBSOCKET!$LIBSOCKET$ac_delim X_EXTRA_LIBS!$X_EXTRA_LIBS$ac_delim LIBUCB!$LIBUCB$ac_delim LIBDL!$LIBDL$ac_delim include_x11_TRUE!$include_x11_TRUE$ac_delim include_x11_FALSE!$include_x11_FALSE$ac_delim XMKMF!$XMKMF$ac_delim X_PRE_LIBS!$X_PRE_LIBS$ac_delim LIB_X11!$LIB_X11$ac_delim LIB_XRENDER!$LIB_XRENDER$ac_delim LIBSM!$LIBSM$ac_delim X_INCLUDES!$X_INCLUDES$ac_delim X_LDFLAGS!$X_LDFLAGS$ac_delim x_includes!$x_includes$ac_delim x_libraries!$x_libraries$ac_delim QTE_NORTTI!$QTE_NORTTI$ac_delim LIB_XEXT!$LIB_XEXT$ac_delim LIBPTHREAD!$LIBPTHREAD$ac_delim USE_THREADS!$USE_THREADS$ac_delim KDE_MT_LDFLAGS!$KDE_MT_LDFLAGS$ac_delim KDE_MT_LIBS!$KDE_MT_LIBS$ac_delim USER_INCLUDES!$USER_INCLUDES$ac_delim USER_LDFLAGS!$USER_LDFLAGS$ac_delim LIBZ!$LIBZ$ac_delim LIBPNG!$LIBPNG$ac_delim LIBJPEG!$LIBJPEG$ac_delim qt_libraries!$qt_libraries$ac_delim qt_includes!$qt_includes$ac_delim QT_INCLUDES!$QT_INCLUDES$ac_delim QT_LDFLAGS!$QT_LDFLAGS$ac_delim PERL!$PERL$ac_delim MOC!$MOC$ac_delim UIC!$UIC$ac_delim UIC_TR!$UIC_TR$ac_delim LIB_QT!$LIB_QT$ac_delim LIB_QPE!$LIB_QPE$ac_delim kde_qtver!$kde_qtver$ac_delim have_lrelease!$have_lrelease$ac_delim have_kde!$have_kde$ac_delim KDECONFIG!$KDECONFIG$ac_delim kde_libs_prefix!$kde_libs_prefix$ac_delim kde_libs_htmldir!$kde_libs_htmldir$ac_delim CONF_FILES!$CONF_FILES$ac_delim KDE_EXTRA_RPATH!$KDE_EXTRA_RPATH$ac_delim KDE_RPATH!$KDE_RPATH$ac_delim X_RPATH!$X_RPATH$ac_delim kde_libraries!$kde_libraries$ac_delim kde_includes!$kde_includes$ac_delim KDE_LDFLAGS!$KDE_LDFLAGS$ac_delim KDE_INCLUDES!$KDE_INCLUDES$ac_delim all_includes!$all_includes$ac_delim all_libraries!$all_libraries$ac_delim AUTODIRS!$AUTODIRS$ac_delim include_ARTS_TRUE!$include_ARTS_TRUE$ac_delim include_ARTS_FALSE!$include_ARTS_FALSE$ac_delim MAKEKDEWIDGETS!$MAKEKDEWIDGETS$ac_delim KCONFIG_COMPILER!$KCONFIG_COMPILER$ac_delim KCFG_DEPENDENCIES!$KCFG_DEPENDENCIES$ac_delim DCOPIDLNG!$DCOPIDLNG$ac_delim DCOPIDL!$DCOPIDL$ac_delim DCOPIDL2CPP!$DCOPIDL2CPP$ac_delim DCOP_DEPENDENCIES!$DCOP_DEPENDENCIES$ac_delim MCOPIDL!$MCOPIDL$ac_delim ARTSCCONFIG!$ARTSCCONFIG$ac_delim MEINPROC!$MEINPROC$ac_delim KDE_XSL_STYLESHEET!$KDE_XSL_STYLESHEET$ac_delim XMLLINT!$XMLLINT$ac_delim kde_htmldir!$kde_htmldir$ac_delim kde_appsdir!$kde_appsdir$ac_delim kde_icondir!$kde_icondir$ac_delim kde_sounddir!$kde_sounddir$ac_delim kde_datadir!$kde_datadir$ac_delim kde_locale!$kde_locale$ac_delim kde_confdir!$kde_confdir$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF kde_kcfgdir!$kde_kcfgdir$ac_delim kde_mimedir!$kde_mimedir$ac_delim kde_wallpaperdir!$kde_wallpaperdir$ac_delim kde_bindir!$kde_bindir$ac_delim xdg_appsdir!$xdg_appsdir$ac_delim xdg_menudir!$xdg_menudir$ac_delim xdg_directorydir!$xdg_directorydir$ac_delim kde_templatesdir!$kde_templatesdir$ac_delim kde_servicesdir!$kde_servicesdir$ac_delim kde_servicetypesdir!$kde_servicetypesdir$ac_delim kde_moduledir!$kde_moduledir$ac_delim kdeinitdir!$kdeinitdir$ac_delim kde_styledir!$kde_styledir$ac_delim kde_widgetdir!$kde_widgetdir$ac_delim LIB_KDECORE!$LIB_KDECORE$ac_delim LIB_KDEUI!$LIB_KDEUI$ac_delim LIB_KIO!$LIB_KIO$ac_delim LIB_KJS!$LIB_KJS$ac_delim LIB_SMB!$LIB_SMB$ac_delim LIB_KAB!$LIB_KAB$ac_delim LIB_KABC!$LIB_KABC$ac_delim LIB_KHTML!$LIB_KHTML$ac_delim LIB_KSPELL!$LIB_KSPELL$ac_delim LIB_KPARTS!$LIB_KPARTS$ac_delim LIB_KDEPRINT!$LIB_KDEPRINT$ac_delim LIB_KUTILS!$LIB_KUTILS$ac_delim LIB_KDEPIM!$LIB_KDEPIM$ac_delim LIB_KIMPROXY!$LIB_KIMPROXY$ac_delim LIB_KNEWSTUFF!$LIB_KNEWSTUFF$ac_delim LIB_KDNSSD!$LIB_KDNSSD$ac_delim LIB_KSYCOCA!$LIB_KSYCOCA$ac_delim LIB_KFILE!$LIB_KFILE$ac_delim LIB_KFM!$LIB_KFM$ac_delim GSM_LIBS!$GSM_LIBS$ac_delim ZRTP_CFLAGS!$ZRTP_CFLAGS$ac_delim ZRTP_LIBS!$ZRTP_LIBS$ac_delim LRELEASEOPTION!$LRELEASEOPTION$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 39; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-3.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed -f "$tmp/subs-3.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" # Compute $ac_file's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $ac_file | $ac_file:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X$ac_file : 'X\(//\)[^/]' \| \ X$ac_file : 'X\(//\)$' \| \ X$ac_file : 'X\(/\)' \| . 2>/dev/null || echo X$ac_file | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; "src/gui/Makefile":C) $QTDIR/bin/qmake -o src/gui/Makefile $srcdir/src/gui/twinkle.pro echo "distdir:" >> src/gui/Makefile echo "check:" >> src/gui/Makefile if test -n "$kde_libraries" then sed -i -e "s|\(LIBS *= \)|\1-L${kde_libraries} |" src/gui/Makefile fi ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi { echo "$as_me:$LINENO: result: " >&5 echo "${ECHO_T}" >&6; } { echo "$as_me:$LINENO: result: Configured optional components:" >&5 echo "${ECHO_T}Configured optional components:" >&6; } { echo "$as_me:$LINENO: result: KDE support: $have_kde" >&5 echo "${ECHO_T}KDE support: $have_kde" >&6; } { echo "$as_me:$LINENO: result: ALSA: $have_libasound" >&5 echo "${ECHO_T}ALSA: $have_libasound" >&6; } { echo "$as_me:$LINENO: result: Speex: $have_speex" >&5 echo "${ECHO_T}Speex: $have_speex" >&6; } { echo "$as_me:$LINENO: result: iLBC: $have_ilbc" >&5 echo "${ECHO_T}iLBC: $have_ilbc" >&6; } { echo "$as_me:$LINENO: result: ZRTP: $have_zrtp" >&5 echo "${ECHO_T}ZRTP: $have_zrtp" >&6; } twinkle-1.4.2/configure.in0000644000175000001440000002530011151047500012413 00000000000000AC_INIT(src/phone.h) AC_CANONICAL_SYSTEM AM_CONFIG_HEADER(src/twinkle_config.h) AC_ARG_ENABLE(qt-check, AC_HELP_STRING([--disable-qt-check], [do not check Qt installation]), [ac_cv_qt_check=$enableval], [ac_cv_qt_check=yes]) AC_ARG_WITH(kde, AC_HELP_STRING([--without-kde], [do not compile KDE features]), [ac_cv_kde=$withval], [ac_cv_kde=yes]) AC_ARG_WITH(ilbc, AC_HELP_STRING([--without-ilbc], [do not compile iLBC]), [ac_cv_ilbc=$withval], [ac_cv_ilbc=yes]) AC_ARG_WITH(speex, AC_HELP_STRING([--without-speex], [do not compile speex]), [ac_cv_speex=$withval], [ac_cv_speex=yes]) AC_ARG_WITH(zrtp, AC_HELP_STRING([--without-zrtp], [do not compile zrtp support]), [ac_cv_zrtp=$withval], [ac_cv_zrtp=yes]) AC_ARG_ENABLE(ilbc-cpp, AC_HELP_STRING([--enable-ilbc-cpp], [your ilbc library is built for C++ instead of C]), [ac_cv_ilbc_cpp=$enableval], [ac_cv_ilbc_cpp=no]) AM_INIT_AUTOMAKE(twinkle,"1.4.2") AC_DEFINE(VERSION_DATE,["February 25 2009"],[Version release date]) AC_PROG_CC AC_PROG_CXX AC_PROG_CPP AC_PROG_CXXCPP AC_PROG_RANLIB AC_PROG_LEX AC_PROG_YACC AC_C_BIGENDIAN AC_LANG(C++) AC_FUNC_STRERROR_R AC_CHECK_HEADERS([linux/types.h]) AC_CHECK_HEADERS([linux/errqueue.h],[],[],[ #if HAVE_LINUX_TYPES_H #include #endif]) # Check version of the Common C++ library. # This also sets the cc++2 include directory in CXXFLAGS OST_CCXX2_VERSION(1.6.0,,exit) # Temporarily add some default directories to PKG_CONFIG_PATH such that # the user will not be burdened with setting PKG_CONFIG_PATH OLD_PKG_CONFIG_PATH=$PKG_CONFIG_PATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig if test "x${prefix}" != "xNONE" then PKG_CONFIG_PATH=$PKG_CONFIG_PATH:${prefix}/lib/pkgconfig fi if test -n "$QTDIR" then PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$QTDIR/lib/pkgconfig fi export PKG_CONFIG_PATH PKG_CHECK_MODULES(CCRTP, libccrtp1 >= 1.6.0) PKG_CHECK_MODULES(XML2, libxml-2.0) # AC_CHECK_HEADER(libxml/tree.h, [], # [AC_MSG_ERROR([libxml2 header files missing (libxml2-devel package)])]) if test "x$ac_cv_qt_check" = "xyes" then PKG_CHECK_MODULES(QT, qt-mt >= 3.3.0 qt-mt < 4.0) fi # Restore the original value of PKG_CONFIG_PATH PKG_CONFIG_PATH=$OLD_PKG_CONFIG_PATH export PKG_CONFIG_PATH # Check if QTDIR variable is set AC_MSG_CHECKING([value of \$QTDIR]) if test -n "$QTDIR" then AC_MSG_RESULT([$QTDIR]) else AC_MSG_RESULT([not set]) AC_MSG_ERROR([Set \$QTDIR to the Qt directory, eg. /usr/lib/qt3]) fi AC_MSG_CHECKING([for qmake]) if test -x $QTDIR/bin/qmake then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_ERROR([Cannot find qmake in \$QTDIR/bin. \$QTDIR is incorrect.]) fi # Without this macro, compiling on non-kde systems does not work AC_PATH_QT # Check if lrelease is available AC_CHECK_PROG(have_lrelease, lrelease, yes, no) if test "x$have_lrelease" = "xno" then AC_MSG_ERROR([lrelease is missing (qt3-devel-tools package)]) fi dnl Create a Qt include project file for platform dependend variables dnl This file will be included by the project file in the gui directory dnl Determine include files and dynamic libs. dnl Creation of qtccxxincl.pro is good to be in AC_CONFIG_COMMANDS dnl macro so that config.status to be able to create it too. dnl In this case we benefit from more ac_xxx variables. dnl Disadvantage is autoconf don't group commands with same tag dnl and we should use different tags. In result AC_OUTPUT will dnl show all of them. QT_INCL_PRO=qtccxxincl.pro AC_MSG_NOTICE([creating $QT_INCL_PRO (include project file for Qt)]) # first set include path to generated files echo "INCLUDEPATH += `pwd`/src" > $QT_INCL_PRO # next get includes specified on command line ( set -- $CPPFLAGS while test -n "$1"; do echo $1 shift done ) | grep '^-I' | sed -e 's|^-I||' | xargs echo INCLUDEPATH += >> $QT_INCL_PRO #echo "INCLUDEPATH += `$CCGNU2_CONFIG --includes`" | sed -e s/-I//g > $QT_INCL_PRO # libccrtp1(ccrtp) depend from libccgnu2(commoncpp2) and # should include above flags ! echo "INCLUDEPATH += `$PKG_CONFIG --cflags-only-I libccrtp1`" | sed -e s/-I//g >> $QT_INCL_PRO echo "INCLUDEPATH += `$PKG_CONFIG --cflags-only-I libxml-2.0`" | sed -e s/-I//g >> $QT_INCL_PRO # get libraries specified on command line echo $LDFLAGS | xargs echo LIBS += >> $QT_INCL_PRO echo "LIBS += `$CCGNU2_CONFIG --stdlibs`" >> $QT_INCL_PRO echo "LIBS += $CCRTP_LIBS" >> $QT_INCL_PRO echo "LIBS += $XML2_LIBS" >> $QT_INCL_PRO # Check if KDE is available if test "x$ac_cv_kde" = "xyes" then AC_CHECK_PROG(have_kde, kde-config, yes, no) else have_kde="no" fi if test "x$have_kde" = "xyes" then KDE_SET_PREFIX AC_PATH_KDE AC_CHECK_FILES(${kde_includes}/kapplication.h, [], [AC_MSG_ERROR([kde header files missing (kdelibs3-devel package)])]) AC_DEFINE(HAVE_KDE, 1, [Define to 1 if you have KDE.]) echo "INCLUDEPATH += ${kde_includes}" >> $QT_INCL_PRO echo "LIBS += -L${kde_libraries} -lkdecore -lkdeui" >> $QT_INCL_PRO echo "LIBS += -L${TWINKLE_KDE_PREFIX}/lib -lkabc" >> $QT_INCL_PRO else include_x11_FALSE="yes" include_ARTS_FALSE="yes" AC_PREFIX_DEFAULT(${prefix:-/usr/local}) fi # Check for libbbind or libresolv. libbind is preferred as libresolv gives # GLIBC_PRIVATE on Fedora. AC_CHECK_LIB(bind, main, [ LIBS="-lbind $LIBS" echo "LIBS += -lbind" >> $QT_INCL_PRO], [ LIBS="-lresolv $LIBS" echo "LIBS += -lresolv" >> $QT_INCL_PRO]) # Check if sndfile library is available AC_CHECK_HEADER(sndfile.h, [], [AC_MSG_ERROR([sndfile header files missing (libsndfile-devel package)])]) AC_CHECK_LIB(sndfile, sf_open, [], [AC_MSG_ERROR([libsndfile library is missing.])]) # Check if magic library is available AC_CHECK_HEADER(magic.h, [], [AC_MSG_ERROR([magic.h is missing (file-devel or libmagic-dev package)])]) AC_CHECK_LIB(magic, magic_open, [], [AC_MSG_ERROR([libmagic library is missing (file or libmagic package)])]) # This check does not work on all platforms # Check if libgsm is available # AC_CHECK_LIB(gsm, sf_open, [ # AC_CHECK_HEADER(gsm.h, [], # [AC_MSG_ERROR([gsm header files missing (gsm.h)])]) # AC_DEFINE(HAVE_GSM, 1, [Define to 1 if you have the library.]) # GSM_LIBS="-lgsm" # echo "LIBS += -lgsm" >> $QT_INCL_PRO # have_gsm="yes" ], [ # have_gsm="no" # GSM_LIBS="\$(top_builddir)/src/audio/gsm/libgsm.a" # echo "LIBS += ../audio/gsm/libgsm.a" >> $QT_INCL_PRO ]) have_gsm="no" GSM_LIBS="\$(top_builddir)/src/audio/gsm/libgsm.a" echo "LIBS += ../audio/gsm/libgsm.a" >> $QT_INCL_PRO AC_SUBST(GSM_LIBS) # Check if ALSA is available AC_CHECK_LIB(asound, main, [ AC_CHECK_HEADER(alsa/asoundlib.h, [], [AC_MSG_ERROR([alsa header files missing (alsa-devel package)])]) AC_DEFINE(HAVE_LIBASOUND, 1, [Define to 1 if you have the library.]) LIBS="-lasound $LIBS" echo "LIBS += -lasound" >> $QT_INCL_PRO have_libasound="yes" ], [have_libasound="no"]) # Check if SPEEX (libspeex & libspeexdsp) is available if test "x$ac_cv_speex" = "xyes" then AC_CHECK_LIB(speex, main, [ AC_CHECK_HEADER(speex/speex.h, [], [AC_MSG_ERROR([speex header files missing])]) AC_CHECK_LIB(speexdsp, main, [ AC_CHECK_HEADERS([speex/speex_preprocess.h speex/speex_echo.h], [], [AC_MSG_ERROR([speexdsp header files missing])]) AC_DEFINE(HAVE_SPEEX, 1, [Define to 1 if you have the library.]) LIBS="-lspeex -lspeexdsp $LIBS" echo "LIBS += -lspeex" >> $QT_INCL_PRO echo "LIBS += -lspeexdsp" >> $QT_INCL_PRO have_speex="yes" ], [have_speex="no"]) ], [have_speex="no"]) else have_speex="no" fi # iLBC if test "x$ac_cv_ilbc" = "xyes" then AC_CHECK_LIB(ilbc, iLBC_decode, [ AC_CHECK_HEADER(ilbc/iLBC_define.h, [], [AC_MSG_ERROR([ilbc header files missing])]) AC_DEFINE(HAVE_ILBC, 1, [Define to 1 if you have the library.]) LIBS="-lilbc $LIBS" echo "LIBS += -lilbc" >> $QT_INCL_PRO have_ilbc="yes" ], [have_ilbc="no"]) if test "x$ac_cv_ilbc_cpp" = "xyes" then AC_DEFINE(HAVE_ILBC_CPP, 1, [Define to 1 if you have a C++ ilbc library.]) fi else have_ilbc="no" fi # Check if zrtp is available if test "x$ac_cv_zrtp" = "xyes" then PKG_CHECK_MODULES(ZRTP, libzrtpcpp >= 1.3.0) AC_CHECK_LIB(zrtpcpp, main, [ AC_CHECK_HEADER(libzrtpcpp/ZrtpQueue.h, [], [AC_MSG_ERROR([zrtp header files missing])]) AC_DEFINE(HAVE_ZRTP, 1, [Define to 1 if you have the library.]) LIBS="-lzrtpcpp $LIBS" echo "LIBS += -lzrtpcpp" >> $QT_INCL_PRO have_zrtp="yes" ], [have_zrtp="no"]) else have_zrtp="no" fi # check if GNU readline or readline compatible libraries are avaliable VL_LIB_READLINE() if test "x$vl_cv_lib_readline" == "xno" then AC_MSG_ERROR([readline-devel package is not installed]) fi # Check if boost regex is available AC_CHECK_HEADER(boost/regex.h, [], [AC_MSG_ERROR([boost/regex.h missing (boost-devel package)])]) AC_CHECK_LIB(boost_regex, main, [ LIBS="-lboost_regex $LIBS" echo "LIBS += -lboost_regex" >> $QT_INCL_PRO], [ AC_CHECK_LIB(boost_regex-gcc, main, [ LIBS="-lboost_regex-gcc $LIBS" echo "LIBS += -lboost_regex-gcc" >> $QT_INCL_PRO], [AC_MSG_ERROR([libboost_regex library is missing (boost package).])])]) ms_CHECK_LRELEASE() dnl $QTDIR/bin/qmake -o src/gui/Makefile src/gui/twinkle.pro dnl Command above is incorrect because srcdir may differ from builddir dnl dnl $QTDIR/bin/qmake -o src/gui/Makefile $srcdir/src/gui/twinkle.pro dnl Command above although is correct in both cases, i.e. when srcdir dnl is equal or differ from builddir will not generate proper Makefile. dnl Reason is unknown. dnl dnl The sed command adds the KDE3 libraries in front of the LIB path. dnl This is needed to correctly build on a KDE4 system. Otherwise dnl gcc will link against KDE4 libraries. AC_CONFIG_COMMANDS([src/gui/Makefile], [ $QTDIR/bin/qmake -o src/gui/Makefile $srcdir/src/gui/twinkle.pro echo "distdir:" >> src/gui/Makefile echo "check:" >> src/gui/Makefile if test -n "$kde_libraries" then sed -i -e "s|\(LIBS *= \)|\1-L${kde_libraries} |" src/gui/Makefile fi ], [kde_libraries=${kde_libraries}] ) dnl Next is useless. See comments in src/parser/Makefile.am . dnl # Strip the -O2 flag from CXXFLAGS for building the SIP parser. dnl # g++ cannot compile the generated C code from bison with -O2 or -Os dnl # Note: -Os is used on VIA C3 processor dnl PARSER_CXXFLAGS=`echo $CXXFLAGS | sed -e "s/\-O2//;s/\-Os//"` dnl AC_SUBST(PARSER_CXXFLAGS) AC_OUTPUT(Makefile src/Makefile src/audio/Makefile src/audio/gsm/Makefile \ src/audits/Makefile src/sdp/Makefile src/parser/Makefile \ src/sockets/Makefile src/stun/Makefile src/threads/Makefile \ src/gui/lang/Makefile src/mwi/Makefile src/im/Makefile \ src/patterns/Makefile src/utils/Makefile src/presence/Makefile \ twinkle.spec) AC_MSG_RESULT([]) AC_MSG_RESULT([Configured optional components:]) AC_MSG_RESULT([KDE support: $have_kde]) AC_MSG_RESULT([ALSA: $have_libasound]) AC_MSG_RESULT([Speex: $have_speex]) AC_MSG_RESULT([iLBC: $have_ilbc]) AC_MSG_RESULT([ZRTP: $have_zrtp]) twinkle-1.4.2/sip.protocol0000644000175000001440000000024410503576710012472 00000000000000[Protocol] exec=twinkle --call %u protocol=sip input=none output=none helper=true listing= reading=false writing=false makedir=false deleting=false Icon=multimedia twinkle-1.4.2/config.guess0000755000175000001440000012655111151323411012432 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2006-05-13' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}" in i?86) test -z "$VENDOR" && VENDOR=pc ;; *) test -z "$VENDOR" && VENDOR=unknown ;; esac test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[345]*) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T:Interix*:[345]*) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-${VENDOR}-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-${VENDOR}-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-${VENDOR}-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-${VENDOR}-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-${VENDOR}-linux-gnu ;; PA8*) echo hppa2.0-${VENDOR}-linux-gnu ;; *) echo hppa-${VENDOR}-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-${VENDOR}-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-${VENDOR}-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-${VENDOR}-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-${VENDOR}-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-${VENDOR}-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-${VENDOR}-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: twinkle-1.4.2/install-sh0000755000175000001440000002202111151323403012102 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2005-05-14.22 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit $?;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit $?;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` shift IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit 1 } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit 1; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit 0 } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: twinkle-1.4.2/config.sub0000755000175000001440000007724211151323411012077 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2006-05-13' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: twinkle-1.4.2/missing0000755000175000001440000002540611151323403011507 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2005-06-08.21 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: twinkle-1.4.2/Makefile.am0000644000175000001440000000164011127672771012160 00000000000000# The Makefile for the Qt-part of the program is created by qmake. # That Makefile builts the executable. # So here the executable is defined as a script such that it will # only be installed and not built. ACLOCAL_AMFLAGS = -I m4 pkglangdir = $(pkgdatadir)/lang bin_SCRIPTS = src/gui/twinkle noinst_SCRIPTS = twinkle.desktop pkgdata_DATA = data/ringback.wav data/ringtone.wav \ data/providers.csv \ src/gui/images/twinkle16.png src/gui/images/twinkle32.png \ src/gui/images/twinkle48.png EXTRA_DIST = src/gui/*.ui src/gui/*.h src/gui/*.cpp src/gui/Makefile \ src/gui/twinkle.pro src/gui/images/* \ data/ringback.wav data/ringtone.wav data/providers.csv \ m4/*.m4 \ sip.protocol twinkle.desktop.in Doxyfile SUBDIRS = src edit = sed \ -e 's,@datadir\@,$(pkgdatadir),g' \ -e 's,@prefix\@,$(prefix),g' twinkle.desktop: Makefile $(srcdir)/twinkle.desktop.in $(edit) $(srcdir)/twinkle.desktop.in >twinkle.desktop twinkle-1.4.2/Makefile.in0000644000175000001440000006100311151323412012146 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # The Makefile for the Qt-part of the program is created by qmake. # That Makefile builts the executable. # So here the executable is defined as a script such that it will # only be installed and not built. srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/twinkle.spec.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ THANKS config.guess config.sub depcomp install-sh missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/vl_lib_readline.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/twinkle_config.h CONFIG_CLEAN_FILES = twinkle.spec am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" binSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS) SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; pkgdataDATA_INSTALL = $(INSTALL_DATA) DATA = $(pkgdata_DATA) ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ ARTSCCONFIG = @ARTSCCONFIG@ AUTOCONF = @AUTOCONF@ AUTODIRS = @AUTODIRS@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCGNU2_CONFIG = @CCGNU2_CONFIG@ CCRTP_CFLAGS = @CCRTP_CFLAGS@ CCRTP_LIBS = @CCRTP_LIBS@ CFLAGS = @CFLAGS@ CONF_FILES = @CONF_FILES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DCOPIDL = @DCOPIDL@ DCOPIDL2CPP = @DCOPIDL2CPP@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTLIBS = @EXTLIBS@ FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ GNULIBS = @GNULIBS@ GREP = @GREP@ GSM_LIBS = @GSM_LIBS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ KCONFIG_COMPILER = @KCONFIG_COMPILER@ KDECONFIG = @KDECONFIG@ KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ KDE_INCLUDES = @KDE_INCLUDES@ KDE_LDFLAGS = @KDE_LDFLAGS@ KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ KDE_MT_LIBS = @KDE_MT_LIBS@ KDE_RPATH = @KDE_RPATH@ KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCOMPAT = @LIBCOMPAT@ LIBCRYPT = @LIBCRYPT@ LIBDL = @LIBDL@ LIBJPEG = @LIBJPEG@ LIBOBJS = @LIBOBJS@ LIBPNG = @LIBPNG@ LIBPTHREAD = @LIBPTHREAD@ LIBRESOLV = @LIBRESOLV@ LIBS = @LIBS@ LIBSM = @LIBSM@ LIBSOCKET = @LIBSOCKET@ LIBUCB = @LIBUCB@ LIBUTIL = @LIBUTIL@ LIBZ = @LIBZ@ LIB_KAB = @LIB_KAB@ LIB_KABC = @LIB_KABC@ LIB_KDECORE = @LIB_KDECORE@ LIB_KDEPIM = @LIB_KDEPIM@ LIB_KDEPRINT = @LIB_KDEPRINT@ LIB_KDEUI = @LIB_KDEUI@ LIB_KDNSSD = @LIB_KDNSSD@ LIB_KFILE = @LIB_KFILE@ LIB_KFM = @LIB_KFM@ LIB_KHTML = @LIB_KHTML@ LIB_KIMPROXY = @LIB_KIMPROXY@ LIB_KIO = @LIB_KIO@ LIB_KJS = @LIB_KJS@ LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ LIB_KPARTS = @LIB_KPARTS@ LIB_KSPELL = @LIB_KSPELL@ LIB_KSYCOCA = @LIB_KSYCOCA@ LIB_KUTILS = @LIB_KUTILS@ LIB_POLL = @LIB_POLL@ LIB_QPE = @LIB_QPE@ LIB_QT = @LIB_QT@ LIB_SMB = @LIB_SMB@ LIB_X11 = @LIB_X11@ LIB_XEXT = @LIB_XEXT@ LIB_XRENDER = @LIB_XRENDER@ LRELEASEOPTION = @LRELEASEOPTION@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MOC = @MOC@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ QTE_NORTTI = @QTE_NORTTI@ QT_CFLAGS = @QT_CFLAGS@ QT_INCLUDES = @QT_INCLUDES@ QT_LDFLAGS = @QT_LDFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SINGLE_FLAGS = @SINGLE_FLAGS@ SINGLE_LIBS = @SINGLE_LIBS@ STRIP = @STRIP@ UIC = @UIC@ UIC_TR = @UIC_TR@ USER_INCLUDES = @USER_INCLUDES@ USER_LDFLAGS = @USER_LDFLAGS@ USE_THREADS = @USE_THREADS@ VERSION = @VERSION@ XMKMF = @XMKMF@ XML2_CFLAGS = @XML2_CFLAGS@ XML2_LIBS = @XML2_LIBS@ XMLLINT = @XMLLINT@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_INCLUDES = @X_INCLUDES@ X_LDFLAGS = @X_LDFLAGS@ X_PRE_LIBS = @X_PRE_LIBS@ X_RPATH = @X_RPATH@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZRTP_CFLAGS = @ZRTP_CFLAGS@ ZRTP_LIBS = @ZRTP_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ all_includes = @all_includes@ all_libraries = @all_libraries@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_kde = @have_kde@ have_lrelease = @have_lrelease@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ include_ARTS_FALSE = @include_ARTS_FALSE@ include_ARTS_TRUE = @include_ARTS_TRUE@ include_x11_FALSE = @include_x11_FALSE@ include_x11_TRUE = @include_x11_TRUE@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ kde_appsdir = @kde_appsdir@ kde_bindir = @kde_bindir@ kde_confdir = @kde_confdir@ kde_datadir = @kde_datadir@ kde_htmldir = @kde_htmldir@ kde_icondir = @kde_icondir@ kde_includes = @kde_includes@ kde_kcfgdir = @kde_kcfgdir@ kde_libraries = @kde_libraries@ kde_libs_htmldir = @kde_libs_htmldir@ kde_libs_prefix = @kde_libs_prefix@ kde_locale = @kde_locale@ kde_mimedir = @kde_mimedir@ kde_moduledir = @kde_moduledir@ kde_qtver = @kde_qtver@ kde_servicesdir = @kde_servicesdir@ kde_servicetypesdir = @kde_servicetypesdir@ kde_sounddir = @kde_sounddir@ kde_styledir = @kde_styledir@ kde_templatesdir = @kde_templatesdir@ kde_wallpaperdir = @kde_wallpaperdir@ kde_widgetdir = @kde_widgetdir@ kdeinitdir = @kdeinitdir@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ qt_includes = @qt_includes@ qt_libraries = @qt_libraries@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ x_includes = @x_includes@ x_libraries = @x_libraries@ xdg_appsdir = @xdg_appsdir@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ ACLOCAL_AMFLAGS = -I m4 pkglangdir = $(pkgdatadir)/lang bin_SCRIPTS = src/gui/twinkle noinst_SCRIPTS = twinkle.desktop pkgdata_DATA = data/ringback.wav data/ringtone.wav \ data/providers.csv \ src/gui/images/twinkle16.png src/gui/images/twinkle32.png \ src/gui/images/twinkle48.png EXTRA_DIST = src/gui/*.ui src/gui/*.h src/gui/*.cpp src/gui/Makefile \ src/gui/twinkle.pro src/gui/images/* \ data/ringback.wav data/ringtone.wav data/providers.csv \ m4/*.m4 \ sip.protocol twinkle.desktop.in Doxyfile SUBDIRS = src edit = sed \ -e 's,@datadir\@,$(pkgdatadir),g' \ -e 's,@prefix\@,$(prefix),g' all: all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ cd $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) twinkle.spec: $(top_builddir)/config.status $(srcdir)/twinkle.spec.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" @list='$(bin_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ else :; fi; \ done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done uninstall-info-am: install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgdatadir)" @list='$(pkgdata_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \ $(pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(pkgdata_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \ rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkdir_p) $(distdir)/. $(distdir)/data $(distdir)/m4 $(distdir)/src/gui $(distdir)/src/gui/images @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(SCRIPTS) $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-pkgdataDATA install-exec-am: install-binSCRIPTS install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binSCRIPTS uninstall-info-am \ uninstall-pkgdataDATA uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-recursive ctags \ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \ dist-tarZ dist-zip distcheck distclean distclean-generic \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-binSCRIPTS install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-pkgdataDATA install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-binSCRIPTS uninstall-info-am \ uninstall-pkgdataDATA twinkle.desktop: Makefile $(srcdir)/twinkle.desktop.in $(edit) $(srcdir)/twinkle.desktop.in >twinkle.desktop # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: twinkle-1.4.2/acinclude.m40000644000175000001440000131234210723100561012302 00000000000000## -*- autoconf -*- dnl This file is part of the KDE libraries/packages dnl Copyright (C) 1997 Janos Farkas (chexum@shadow.banki.hu) dnl (C) 1997,98,99 Stephan Kulow (coolo@kde.org) dnl This file is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Library General Public dnl License as published by the Free Software Foundation; either dnl version 2 of the License, or (at your option) any later version. dnl This library is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl Library General Public License for more details. dnl You should have received a copy of the GNU Library General Public License dnl along with this library; see the file COPYING.LIB. If not, write to dnl the Free Software Foundation, Inc., 59 Temple Place - Suite 330, dnl Boston, MA 02111-1307, USA. dnl IMPORTANT NOTE: dnl Please do not modify this file unless you expect your modifications to be dnl carried into every other module in the repository. dnl dnl Single-module modifications are best placed in configure.in for kdelibs dnl and kdebase or configure.in.in if present. # KDE_PATH_X_DIRECT dnl Internal subroutine of AC_PATH_X. dnl Set ac_x_includes and/or ac_x_libraries. AC_DEFUN([KDE_PATH_X_DIRECT], [ AC_REQUIRE([KDE_CHECK_LIB64]) if test "$ac_x_includes" = NO; then # Guess where to find include files, by looking for this one X11 .h file. test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h # First, try using that file with no special directory specified. AC_TRY_CPP([#include <$x_direct_test_include>], [# We can compile using X headers with no special include directory. ac_x_includes=], [# Look for the header file in a standard set of common directories. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in \ /usr/X11/include \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ /usr/include/X11 \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ /usr/local/X11/include \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ /usr/local/include/X11 \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ \ /usr/include \ /usr/local/include \ /usr/unsupported/include \ /usr/athena/include \ /usr/local/x11r5/include \ /usr/lpp/Xamples/include \ \ /usr/openwin/include \ /usr/openwin/share/include \ ; \ do if test -r "$ac_dir/$x_direct_test_include"; then ac_x_includes=$ac_dir break fi done]) fi # $ac_x_includes = NO if test "$ac_x_libraries" = NO; then # Check for the libraries. test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" AC_TRY_LINK([#include ], [${x_direct_test_function}(1)], [LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries=], [LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib${kdelibsuff}/` \ /usr/X11/lib${kdelibsuff} \ /usr/X11R6/lib${kdelibsuff} \ /usr/X11R5/lib${kdelibsuff} \ /usr/X11R4/lib${kdelibsuff} \ \ /usr/lib${kdelibsuff}/X11 \ /usr/lib${kdelibsuff}/X11R6 \ /usr/lib${kdelibsuff}/X11R5 \ /usr/lib${kdelibsuff}/X11R4 \ \ /usr/local/X11/lib${kdelibsuff} \ /usr/local/X11R6/lib${kdelibsuff} \ /usr/local/X11R5/lib${kdelibsuff} \ /usr/local/X11R4/lib${kdelibsuff} \ \ /usr/local/lib${kdelibsuff}/X11 \ /usr/local/lib${kdelibsuff}/X11R6 \ /usr/local/lib${kdelibsuff}/X11R5 \ /usr/local/lib${kdelibsuff}/X11R4 \ \ /usr/X386/lib${kdelibsuff} \ /usr/x386/lib${kdelibsuff} \ /usr/XFree86/lib${kdelibsuff}/X11 \ \ /usr/lib${kdelibsuff} \ /usr/local/lib${kdelibsuff} \ /usr/unsupported/lib${kdelibsuff} \ /usr/athena/lib${kdelibsuff} \ /usr/local/x11r5/lib${kdelibsuff} \ /usr/lpp/Xamples/lib${kdelibsuff} \ /lib/usr/lib${kdelibsuff}/X11 \ \ /usr/openwin/lib${kdelibsuff} \ /usr/openwin/share/lib${kdelibsuff} \ ; \ do dnl Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl; do if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done]) fi # $ac_x_libraries = NO ]) dnl ------------------------------------------------------------------------ dnl Find a file (or one of more files in a list of dirs) dnl ------------------------------------------------------------------------ dnl AC_DEFUN([AC_FIND_FILE], [ $3=NO for i in $2; do for j in $1; do echo "configure: __oline__: $i/$j" >&AC_FD_CC if test -r "$i/$j"; then echo "taking that" >&AC_FD_CC $3=$i break 2 fi done done ]) dnl KDE_FIND_PATH(program-name, variable-name, list-of-dirs, dnl if-not-found, test-parameter, prepend-path) dnl dnl Look for program-name in list-of-dirs+$PATH. dnl If prepend-path is set, look in $PATH+list-of-dirs instead. dnl If found, $variable-name is set. If not, if-not-found is evaluated. dnl test-parameter: if set, the program is executed with this arg, dnl and only a successful exit code is required. AC_DEFUN([KDE_FIND_PATH], [ AC_MSG_CHECKING([for $1]) if test -n "$$2"; then kde_cv_path="$$2"; else kde_cache=`echo $1 | sed 'y%./+-%__p_%'` AC_CACHE_VAL(kde_cv_path_$kde_cache, [ kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' dirs="" for dir in $PATH; do dirs="$dirs $dir" done if test -z "$6"; then dnl Append dirs in PATH (default) dirs="$3 $dirs" else dnl Prepend dirs in PATH (if 6th arg is set) dirs="$dirs $3" fi IFS=$kde_save_IFS for dir in $dirs; do if test -x "$dir/$1"; then if test -n "$5" then evalstr="$dir/$1 $5 2>&1 " if eval $evalstr; then kde_cv_path="$dir/$1" break fi else kde_cv_path="$dir/$1" break fi fi done eval "kde_cv_path_$kde_cache=$kde_cv_path" ]) eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" fi if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then AC_MSG_RESULT(not found) $4 else AC_MSG_RESULT($kde_cv_path) $2=$kde_cv_path fi ]) AC_DEFUN([KDE_MOC_ERROR_MESSAGE], [ AC_MSG_ERROR([No Qt meta object compiler (moc) found! Please check whether you installed Qt correctly. You need to have a running moc binary. configure tried to run $ac_cv_path_moc and the test didn't succeed. If configure shouldn't have tried this one, set the environment variable MOC to the right one before running configure. ]) ]) AC_DEFUN([KDE_UIC_ERROR_MESSAGE], [ AC_MSG_WARN([No Qt ui compiler (uic) found! Please check whether you installed Qt correctly. You need to have a running uic binary. configure tried to run $ac_cv_path_uic and the test didn't succeed. If configure shouldn't have tried this one, set the environment variable UIC to the right one before running configure. ]) ]) AC_DEFUN([KDE_CHECK_UIC_FLAG], [ AC_MSG_CHECKING([whether uic supports -$1 ]) kde_cache=`echo $1 | sed 'y% .=/+-%____p_%'` AC_CACHE_VAL(kde_cv_prog_uic_$kde_cache, [ cat >conftest.ui < EOT ac_uic_testrun="$UIC_PATH -$1 $2 conftest.ui >/dev/null" if AC_TRY_EVAL(ac_uic_testrun); then eval "kde_cv_prog_uic_$kde_cache=yes" else eval "kde_cv_prog_uic_$kde_cache=no" fi rm -f conftest* ]) if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then AC_MSG_RESULT([yes]) : $3 else AC_MSG_RESULT([no]) : $4 fi ]) dnl ------------------------------------------------------------------------ dnl Find the meta object compiler and the ui compiler in the PATH, dnl in $QTDIR/bin, and some more usual places dnl ------------------------------------------------------------------------ dnl AC_DEFUN([AC_PATH_QT_MOC_UIC], [ AC_REQUIRE([KDE_CHECK_PERL]) qt_bindirs="" for dir in $kde_qt_dirs; do qt_bindirs="$qt_bindirs $dir/bin $dir/src/moc" done qt_bindirs="$qt_bindirs /usr/bin /usr/X11R6/bin /usr/local/qt/bin" if test ! "$ac_qt_bindir" = "NO"; then qt_bindirs="$ac_qt_bindir $qt_bindirs" fi KDE_FIND_PATH(moc, MOC, [$qt_bindirs], [KDE_MOC_ERROR_MESSAGE]) if test -z "$UIC_NOT_NEEDED"; then KDE_FIND_PATH(uic, UIC_PATH, [$qt_bindirs], [UIC_PATH=""]) if test -z "$UIC_PATH" ; then KDE_UIC_ERROR_MESSAGE exit 1 else UIC=$UIC_PATH if test $kde_qtver = 3; then KDE_CHECK_UIC_FLAG(L,[/nonexistent],ac_uic_supports_libpath=yes,ac_uic_supports_libpath=no) KDE_CHECK_UIC_FLAG(nounload,,ac_uic_supports_nounload=yes,ac_uic_supports_nounload=no) if test x$ac_uic_supports_libpath = xyes; then UIC="$UIC -L \$(kde_widgetdir)" fi if test x$ac_uic_supports_nounload = xyes; then UIC="$UIC -nounload" fi fi fi else UIC="echo uic not available: " fi AC_SUBST(MOC) AC_SUBST(UIC) UIC_TR="i18n" if test $kde_qtver = 3; then UIC_TR="tr2i18n" fi AC_SUBST(UIC_TR) ]) AC_DEFUN([KDE_1_CHECK_PATHS], [ KDE_1_CHECK_PATH_HEADERS KDE_TEST_RPATH= if test -n "$USE_RPATH"; then if test -n "$kde_libraries"; then KDE_TEST_RPATH="-R $kde_libraries" fi if test -n "$qt_libraries"; then KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries" fi if test -n "$x_libraries"; then KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries" fi KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH" fi AC_MSG_CHECKING([for KDE libraries installed]) ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5' if AC_TRY_EVAL(ac_link) && test -s conftest; then AC_MSG_RESULT(yes) else AC_MSG_ERROR([your system fails at linking a small KDE application! Check, if your compiler is installed correctly and if you have used the same compiler to compile Qt and kdelibs as you did use now. For more details about this problem, look at the end of config.log.]) fi if eval `KDEDIR= ./conftest 2>&5`; then kde_result=done else kde_result=problems fi KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log kde_have_all_paths=yes KDE_SET_PATHS($kde_result) ]) AC_DEFUN([KDE_SET_PATHS], [ kde_cv_all_paths="kde_have_all_paths=\"yes\" \ kde_htmldir=\"$kde_htmldir\" \ kde_appsdir=\"$kde_appsdir\" \ kde_icondir=\"$kde_icondir\" \ kde_sounddir=\"$kde_sounddir\" \ kde_datadir=\"$kde_datadir\" \ kde_locale=\"$kde_locale\" \ kde_cgidir=\"$kde_cgidir\" \ kde_confdir=\"$kde_confdir\" \ kde_kcfgdir=\"$kde_kcfgdir\" \ kde_mimedir=\"$kde_mimedir\" \ kde_toolbardir=\"$kde_toolbardir\" \ kde_wallpaperdir=\"$kde_wallpaperdir\" \ kde_templatesdir=\"$kde_templatesdir\" \ kde_bindir=\"$kde_bindir\" \ kde_servicesdir=\"$kde_servicesdir\" \ kde_servicetypesdir=\"$kde_servicetypesdir\" \ kde_moduledir=\"$kde_moduledir\" \ kde_styledir=\"$kde_styledir\" \ kde_widgetdir=\"$kde_widgetdir\" \ xdg_appsdir=\"$xdg_appsdir\" \ xdg_menudir=\"$xdg_menudir\" \ xdg_directorydir=\"$xdg_directorydir\" \ kde_result=$1" ]) AC_DEFUN([KDE_SET_DEFAULT_PATHS], [ if test "$1" = "default"; then if test -z "$kde_htmldir"; then kde_htmldir='\${datadir}/doc/HTML' fi if test -z "$kde_appsdir"; then kde_appsdir='\${datadir}/applnk' fi if test -z "$kde_icondir"; then kde_icondir='\${datadir}/icons' fi if test -z "$kde_sounddir"; then kde_sounddir='\${datadir}/sounds' fi if test -z "$kde_datadir"; then kde_datadir='\${datadir}/apps' fi if test -z "$kde_locale"; then kde_locale='\${datadir}/locale' fi if test -z "$kde_cgidir"; then kde_cgidir='\${exec_prefix}/cgi-bin' fi if test -z "$kde_confdir"; then kde_confdir='\${datadir}/config' fi if test -z "$kde_kcfgdir"; then kde_kcfgdir='\${datadir}/config.kcfg' fi if test -z "$kde_mimedir"; then kde_mimedir='\${datadir}/mimelnk' fi if test -z "$kde_toolbardir"; then kde_toolbardir='\${datadir}/toolbar' fi if test -z "$kde_wallpaperdir"; then kde_wallpaperdir='\${datadir}/wallpapers' fi if test -z "$kde_templatesdir"; then kde_templatesdir='\${datadir}/templates' fi if test -z "$kde_bindir"; then kde_bindir='\${exec_prefix}/bin' fi if test -z "$kde_servicesdir"; then kde_servicesdir='\${datadir}/services' fi if test -z "$kde_servicetypesdir"; then kde_servicetypesdir='\${datadir}/servicetypes' fi if test -z "$kde_moduledir"; then if test "$kde_qtver" = "2"; then kde_moduledir='\${libdir}/kde2' else kde_moduledir='\${libdir}/kde3' fi fi if test -z "$kde_styledir"; then kde_styledir='\${libdir}/kde3/plugins/styles' fi if test -z "$kde_widgetdir"; then kde_widgetdir='\${libdir}/kde3/plugins/designer' fi if test -z "$xdg_appsdir"; then xdg_appsdir='\${datadir}/applications/kde' fi if test -z "$xdg_menudir"; then xdg_menudir='\${sysconfdir}/xdg/menus' fi if test -z "$xdg_directorydir"; then xdg_directorydir='\${datadir}/desktop-directories' fi KDE_SET_PATHS(defaults) else if test $kde_qtver = 1; then AC_MSG_RESULT([compiling]) KDE_1_CHECK_PATHS else AC_MSG_ERROR([path checking not yet supported for KDE 2]) fi fi ]) AC_DEFUN([KDE_CHECK_PATHS_FOR_COMPLETENESS], [ if test -z "$kde_htmldir" || test -z "$kde_appsdir" || test -z "$kde_icondir" || test -z "$kde_sounddir" || test -z "$kde_datadir" || test -z "$kde_locale" || test -z "$kde_cgidir" || test -z "$kde_confdir" || test -z "$kde_kcfgdir" || test -z "$kde_mimedir" || test -z "$kde_toolbardir" || test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" || test -z "$kde_bindir" || test -z "$kde_servicesdir" || test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" || test -z "$kde_styledir" || test -z "kde_widgetdir" || test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_directorydir" || test "x$kde_have_all_paths" != "xyes"; then kde_have_all_paths=no fi ]) AC_DEFUN([KDE_MISSING_PROG_ERROR], [ AC_MSG_ERROR([The important program $1 was not found! Please check whether you installed KDE correctly. ]) ]) AC_DEFUN([KDE_MISSING_ARTS_ERROR], [ AC_MSG_ERROR([The important program $1 was not found! Please check whether you installed aRts correctly or use --without-arts to compile without aRts support (this will remove functionality). ]) ]) AC_DEFUN([KDE_SET_DEFAULT_BINDIRS], [ kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin" test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs" if test -n "$KDEDIRS"; then kde_save_IFS=$IFS IFS=: for dir in $KDEDIRS; do kde_default_bindirs="$dir/bin $kde_default_bindirs " done IFS=$kde_save_IFS fi ]) AC_DEFUN([KDE_SUBST_PROGRAMS], [ AC_ARG_WITH(arts, AC_HELP_STRING([--without-arts],[build without aRts [default=no]]), [build_arts=$withval], [build_arts=yes] ) AM_CONDITIONAL(include_ARTS, test "$build_arts" '!=' "no") if test "$build_arts" = "no"; then AC_DEFINE(WITHOUT_ARTS, 1, [Defined if compiling without arts]) fi KDE_SET_DEFAULT_BINDIRS kde_default_bindirs="$exec_prefix/bin $prefix/bin $kde_libs_prefix/bin $kde_default_bindirs" KDE_FIND_PATH(dcopidl, DCOPIDL, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl)]) KDE_FIND_PATH(dcopidl2cpp, DCOPIDL2CPP, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl2cpp)]) if test "$build_arts" '!=' "no"; then KDE_FIND_PATH(mcopidl, MCOPIDL, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(mcopidl)]) KDE_FIND_PATH(artsc-config, ARTSCCONFIG, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(artsc-config)]) fi KDE_FIND_PATH(meinproc, MEINPROC, [$kde_default_bindirs]) kde32ornewer=1 kde33ornewer=1 if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then kde32ornewer= kde33ornewer= else if test "$kde_qtver" = "3"; then if test "$kde_qtsubver" -le 1; then kde32ornewer= fi if test "$kde_qtsubver" -le 2; then kde33ornewer= fi fi fi if test -n "$kde32ornewer"; then KDE_FIND_PATH(kconfig_compiler, KCONFIG_COMPILER, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kconfig_compiler)]) KDE_FIND_PATH(dcopidlng, DCOPIDLNG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidlng)]) fi if test -n "$kde33ornewer"; then KDE_FIND_PATH(makekdewidgets, MAKEKDEWIDGETS, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(makekdewidgets)]) AC_SUBST(MAKEKDEWIDGETS) fi KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin], [XMLLINT=""]) if test -n "$MEINPROC" && test ! "$MEINPROC" = "compiled"; then kde_sharedirs="/usr/share/kde /usr/local/share /usr/share /opt/kde3/share /opt/kde/share $prefix/share" test -n "$KDEDIR" && kde_sharedirs="$KDEDIR/share $kde_sharedirs" AC_FIND_FILE(apps/ksgmltools2/customization/kde-chunk.xsl, $kde_sharedirs, KDE_XSL_STYLESHEET) if test "$KDE_XSL_STYLESHEET" = "NO"; then KDE_XSL_STYLESHEET="" else KDE_XSL_STYLESHEET="$KDE_XSL_STYLESHEET/apps/ksgmltools2/customization/kde-chunk.xsl" fi fi DCOP_DEPENDENCIES='$(DCOPIDL)' if test -n "$kde32ornewer"; then KCFG_DEPENDENCIES='$(KCONFIG_COMPILER)' DCOP_DEPENDENCIES='$(DCOPIDL) $(DCOPIDLNG)' AC_SUBST(KCONFIG_COMPILER) AC_SUBST(KCFG_DEPENDENCIES) AC_SUBST(DCOPIDLNG) fi AC_SUBST(DCOPIDL) AC_SUBST(DCOPIDL2CPP) AC_SUBST(DCOP_DEPENDENCIES) AC_SUBST(MCOPIDL) AC_SUBST(ARTSCCONFIG) AC_SUBST(MEINPROC) AC_SUBST(KDE_XSL_STYLESHEET) AC_SUBST(XMLLINT) ])dnl AC_DEFUN([AC_CREATE_KFSSTND], [ AC_REQUIRE([AC_CHECK_RPATH]) AC_MSG_CHECKING([for KDE paths]) kde_result="" kde_cached_paths=yes AC_CACHE_VAL(kde_cv_all_paths, [ KDE_SET_DEFAULT_PATHS($1) kde_cached_paths=no ]) eval "$kde_cv_all_paths" KDE_CHECK_PATHS_FOR_COMPLETENESS if test "$kde_have_all_paths" = "no" && test "$kde_cached_paths" = "yes"; then # wrong values were cached, may be, we can set better ones kde_result= kde_htmldir= kde_appsdir= kde_icondir= kde_sounddir= kde_datadir= kde_locale= kde_cgidir= kde_confdir= kde_kcfgdir= kde_mimedir= kde_toolbardir= kde_wallpaperdir= kde_templatesdir= kde_bindir= kde_servicesdir= kde_servicetypesdir= kde_moduledir= kde_have_all_paths= kde_styledir= kde_widgetdir= xdg_appsdir = xdg_menudir= xdg_directorydir= KDE_SET_DEFAULT_PATHS($1) eval "$kde_cv_all_paths" KDE_CHECK_PATHS_FOR_COMPLETENESS kde_result="$kde_result (cache overridden)" fi if test "$kde_have_all_paths" = "no"; then AC_MSG_ERROR([configure could not run a little KDE program to test the environment. Since it had compiled and linked before, it must be a strange problem on your system. Look at config.log for details. If you are not able to fix this, look at http://www.kde.org/faq/installation.html or any www.kde.org mirror. (If you're using an egcs version on Linux, you may update binutils!) ]) else rm -f conftest* AC_MSG_RESULT($kde_result) fi bindir=$kde_bindir KDE_SUBST_PROGRAMS ]) AC_DEFUN([AC_SUBST_KFSSTND], [ AC_SUBST(kde_htmldir) AC_SUBST(kde_appsdir) AC_SUBST(kde_icondir) AC_SUBST(kde_sounddir) AC_SUBST(kde_datadir) AC_SUBST(kde_locale) AC_SUBST(kde_confdir) AC_SUBST(kde_kcfgdir) AC_SUBST(kde_mimedir) AC_SUBST(kde_wallpaperdir) AC_SUBST(kde_bindir) dnl X Desktop Group standards AC_SUBST(xdg_appsdir) AC_SUBST(xdg_menudir) AC_SUBST(xdg_directorydir) dnl for KDE 2 AC_SUBST(kde_templatesdir) AC_SUBST(kde_servicesdir) AC_SUBST(kde_servicetypesdir) AC_SUBST(kde_moduledir) AC_SUBST(kdeinitdir, '$(kde_moduledir)') AC_SUBST(kde_styledir) AC_SUBST(kde_widgetdir) if test "$kde_qtver" = 1; then kde_minidir="$kde_icondir/mini" else # for KDE 1 - this breaks KDE2 apps using minidir, but # that's the plan ;-/ kde_minidir="/dev/null" fi dnl AC_SUBST(kde_minidir) dnl AC_SUBST(kde_cgidir) dnl AC_SUBST(kde_toolbardir) ]) AC_DEFUN([KDE_MISC_TESTS], [ dnl Checks for libraries. AC_CHECK_LIB(util, main, [LIBUTIL="-lutil"]) dnl for *BSD AC_SUBST(LIBUTIL) AC_CHECK_LIB(compat, main, [LIBCOMPAT="-lcompat"]) dnl for *BSD AC_SUBST(LIBCOMPAT) kde_have_crypt= AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"; kde_have_crypt=yes], AC_CHECK_LIB(c, crypt, [kde_have_crypt=yes], [ AC_MSG_WARN([you have no crypt in either libcrypt or libc. You should install libcrypt from another source or configure with PAM support]) kde_have_crypt=no ])) AC_SUBST(LIBCRYPT) if test $kde_have_crypt = yes; then AC_DEFINE_UNQUOTED(HAVE_CRYPT, 1, [Defines if your system has the crypt function]) fi AC_CHECK_SOCKLEN_T AC_CHECK_LIB(dnet, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"]) if test $ac_cv_lib_dnet_dnet_ntoa = no; then AC_CHECK_LIB(dnet_stub, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"]) fi AC_CHECK_FUNC(inet_ntoa) if test $ac_cv_func_inet_ntoa = no; then AC_CHECK_LIB(nsl, inet_ntoa, X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl") fi AC_CHECK_FUNC(connect) if test $ac_cv_func_connect = no; then AC_CHECK_LIB(socket, connect, X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS", , $X_EXTRA_LIBS) fi AC_CHECK_FUNC(remove) if test $ac_cv_func_remove = no; then AC_CHECK_LIB(posix, remove, X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix") fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. AC_CHECK_FUNC(shmat, , AC_CHECK_LIB(ipc, shmat, X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc")) # more headers that need to be explicitly included on darwin AC_CHECK_HEADERS(sys/types.h stdint.h) # sys/bitypes.h is needed for uint32_t and friends on Tru64 AC_CHECK_HEADERS(sys/bitypes.h) # darwin requires a poll emulation library AC_CHECK_LIB(poll, poll, LIB_POLL="-lpoll") # for some image handling on Mac OS X AC_CHECK_HEADERS(Carbon/Carbon.h) # CoreAudio framework AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [ AC_DEFINE(HAVE_COREAUDIO, 1, [Define if you have the CoreAudio API]) FRAMEWORK_COREAUDIO="-Xlinker -framework -Xlinker CoreAudio" ]) AC_CHECK_RES_INIT AC_SUBST(LIB_POLL) AC_SUBST(FRAMEWORK_COREAUDIO) LIBSOCKET="$X_EXTRA_LIBS" AC_SUBST(LIBSOCKET) AC_SUBST(X_EXTRA_LIBS) AC_CHECK_LIB(ucb, killpg, [LIBUCB="-lucb"]) dnl for Solaris2.4 AC_SUBST(LIBUCB) case $host in dnl this *is* LynxOS specific *-*-lynxos* ) AC_MSG_CHECKING([LynxOS header file wrappers]) [CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"] AC_MSG_RESULT(disabled) AC_CHECK_LIB(bsd, gethostbyname, [LIBSOCKET="-lbsd"]) dnl for LynxOS ;; esac KDE_CHECK_TYPES KDE_CHECK_LIBDL KDE_CHECK_STRLCPY # darwin needs this to initialize the environment AC_CHECK_HEADERS(crt_externs.h) AC_CHECK_FUNC(_NSGetEnviron, [AC_DEFINE(HAVE_NSGETENVIRON, 1, [Define if your system needs _NSGetEnviron to set up the environment])]) AH_VERBATIM(_DARWIN_ENVIRON, [ #if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) # include # include # define environ (*_NSGetEnviron()) #endif ]) AH_VERBATIM(_AIX_STRINGS_H_BZERO, [ /* * AIX defines FD_SET in terms of bzero, but fails to include * that defines bzero. */ #if defined(_AIX) #include #endif ]) AC_CHECK_FUNCS([vsnprintf snprintf]) AH_VERBATIM(_TRU64,[ /* * On HP-UX, the declaration of vsnprintf() is needed every time ! */ #if !defined(HAVE_VSNPRINTF) || defined(hpux) #if __STDC__ #include #include #else #include #endif #ifdef __cplusplus extern "C" #endif int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); #ifdef __cplusplus extern "C" #endif int snprintf(char *str, size_t n, char const *fmt, ...); #endif ]) ]) dnl ------------------------------------------------------------------------ dnl Find the header files and libraries for X-Windows. Extended the dnl macro AC_PATH_X dnl ------------------------------------------------------------------------ dnl AC_DEFUN([K_PATH_X], [ AC_REQUIRE([KDE_MISC_TESTS])dnl AC_REQUIRE([KDE_CHECK_LIB64]) AC_ARG_ENABLE( embedded, AC_HELP_STRING([--enable-embedded],[link to Qt-embedded, don't use X]), kde_use_qt_emb=$enableval, kde_use_qt_emb=no ) AC_ARG_ENABLE( qtopia, AC_HELP_STRING([--enable-qtopia],[link to Qt-embedded, link to the Qtopia Environment]), kde_use_qt_emb_palm=$enableval, kde_use_qt_emb_palm=no ) AC_ARG_ENABLE( mac, AC_HELP_STRING([--enable-mac],[link to Qt/Mac (don't use X)]), kde_use_qt_mac=$enableval, kde_use_qt_mac=no ) # used to disable x11-specific stuff on special platforms AM_CONDITIONAL(include_x11, test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no") if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then AC_MSG_CHECKING(for X) AC_CACHE_VAL(kde_cv_have_x, [# One or both of the vars are not set, and there is no cached value. if test "{$x_includes+set}" = set || test "$x_includes" = NONE; then kde_x_includes=NO else kde_x_includes=$x_includes fi if test "{$x_libraries+set}" = set || test "$x_libraries" = NONE; then kde_x_libraries=NO else kde_x_libraries=$x_libraries fi # below we use the standard autoconf calls ac_x_libraries=$kde_x_libraries ac_x_includes=$kde_x_includes KDE_PATH_X_DIRECT dnl AC_PATH_X_XMKMF picks /usr/lib as the path for the X libraries. dnl Unfortunately, if compiling with the N32 ABI, this is not the correct dnl location. The correct location is /usr/lib32 or an undefined value dnl (the linker is smart enough to pick the correct default library). dnl Things work just fine if you use just AC_PATH_X_DIRECT. dnl Solaris has a similar problem. AC_PATH_X_XMKMF forces x_includes to dnl /usr/openwin/include, which doesn't work. /usr/include does work, so dnl x_includes should be left alone. case "$host" in mips-sgi-irix6*) ;; *-*-solaris*) ;; *) _AC_PATH_X_XMKMF if test -z "$ac_x_includes"; then ac_x_includes="." fi if test -z "$ac_x_libraries"; then ac_x_libraries="/usr/lib${kdelibsuff}" fi esac #from now on we use our own again # when the user already gave --x-includes, we ignore # what the standard autoconf macros told us. if test "$kde_x_includes" = NO; then kde_x_includes=$ac_x_includes fi # for --x-libraries too if test "$kde_x_libraries" = NO; then kde_x_libraries=$ac_x_libraries fi if test "$kde_x_includes" = NO; then AC_MSG_ERROR([Can't find X includes. Please check your installation and add the correct paths!]) fi if test "$kde_x_libraries" = NO; then AC_MSG_ERROR([Can't find X libraries. Please check your installation and add the correct paths!]) fi # Record where we found X for the cache. kde_cv_have_x="have_x=yes \ kde_x_includes=$kde_x_includes kde_x_libraries=$kde_x_libraries" ])dnl eval "$kde_cv_have_x" if test "$have_x" != yes; then AC_MSG_RESULT($have_x) no_x=yes else AC_MSG_RESULT([libraries $kde_x_libraries, headers $kde_x_includes]) fi if test -z "$kde_x_includes" || test "x$kde_x_includes" = xNONE; then X_INCLUDES="" x_includes="."; dnl better than nothing :- else x_includes=$kde_x_includes X_INCLUDES="-I$x_includes" fi if test -z "$kde_x_libraries" || test "x$kde_x_libraries" = xNONE; then X_LDFLAGS="" x_libraries="/usr/lib"; dnl better than nothing :- else x_libraries=$kde_x_libraries X_LDFLAGS="-L$x_libraries" fi all_includes="$X_INCLUDES" all_libraries="$X_LDFLAGS $LDFLAGS_AS_NEEDED $LDFLAGS_NEW_DTAGS" # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $X_LDFLAGS" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. AC_CHECK_LIB(ICE, IceConnectionNumber, [LIBSM="-lSM -lICE"], , $X_EXTRA_LIBS) LDFLAGS="$ac_save_LDFLAGS" LIB_X11='-lX11 $(LIBSOCKET)' AC_MSG_CHECKING(for libXext) AC_CACHE_VAL(kde_cv_have_libXext, [ kde_ldflags_safe="$LDFLAGS" kde_libs_safe="$LIBS" LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS" LIBS="-lXext -lX11 $LIBSOCKET" AC_TRY_LINK([ #include #ifdef STDC_HEADERS # include #endif ], [ printf("hello Xext\n"); ], kde_cv_have_libXext=yes, kde_cv_have_libXext=no ) LDFLAGS=$kde_ldflags_safe LIBS=$kde_libs_safe ]) AC_MSG_RESULT($kde_cv_have_libXext) if test "$kde_cv_have_libXext" = "no"; then AC_MSG_ERROR([We need a working libXext to proceed. Since configure can't find it itself, we stop here assuming that make wouldn't find them either.]) fi LIB_XEXT="-lXext" QTE_NORTTI="" elif test "$kde_use_qt_emb" = "yes"; then dnl We're using QT Embedded CPPFLAGS=-DQWS CXXFLAGS="$CXXFLAGS -fno-rtti" QTE_NORTTI="-fno-rtti -DQWS" X_PRE_LIBS="" LIB_X11="" LIB_XEXT="" LIB_XRENDER="" LIBSM="" X_INCLUDES="" X_LDFLAGS="" x_includes="" x_libraries="" elif test "$kde_use_qt_mac" = "yes"; then dnl We're using QT/Mac (I use QT_MAC so that qglobal.h doesn't *have* to dnl be included to get the information) --Sam CXXFLAGS="$CXXFLAGS -DQT_MAC -no-cpp-precomp" CFLAGS="$CFLAGS -DQT_MAC -no-cpp-precomp" X_PRE_LIBS="" LIB_X11="" LIB_XEXT="" LIB_XRENDER="" LIBSM="" X_INCLUDES="" X_LDFLAGS="" x_includes="" x_libraries="" fi AC_SUBST(X_PRE_LIBS) AC_SUBST(LIB_X11) AC_SUBST(LIB_XRENDER) AC_SUBST(LIBSM) AC_SUBST(X_INCLUDES) AC_SUBST(X_LDFLAGS) AC_SUBST(x_includes) AC_SUBST(x_libraries) AC_SUBST(QTE_NORTTI) AC_SUBST(LIB_XEXT) ]) AC_DEFUN([KDE_PRINT_QT_PROGRAM], [ AC_REQUIRE([KDE_USE_QT]) cat > conftest.$ac_ext < #include EOF if test "$kde_qtver" = "2"; then cat >> conftest.$ac_ext < #include #include EOF if test $kde_qtsubver -gt 0; then cat >> conftest.$ac_ext <> conftest.$ac_ext < #include #include EOF fi echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext cat >> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <&AC_FD_CC cat conftest.$ac_ext >&AC_FD_CC fi rm -f conftest* CXXFLAGS="$ac_cxxflags_safe" LDFLAGS="$ac_ldflags_safe" LIBS="$ac_libs_safe" LD_LIBRARY_PATH="$ac_LD_LIBRARY_PATH_safe" export LD_LIBRARY_PATH LIBRARY_PATH="$ac_LIBRARY_PATH" export LIBRARY_PATH AC_LANG_RESTORE ]) if test "$kde_cv_qt_direct" = "yes"; then AC_MSG_RESULT(yes) $1 else AC_MSG_RESULT(no) $2 fi ]) dnl ------------------------------------------------------------------------ dnl Try to find the Qt headers and libraries. dnl $(QT_LDFLAGS) will be -Lqtliblocation (if needed) dnl and $(QT_INCLUDES) will be -Iqthdrlocation (if needed) dnl ------------------------------------------------------------------------ dnl AC_DEFUN([AC_PATH_QT_1_3], [ AC_REQUIRE([K_PATH_X]) AC_REQUIRE([KDE_USE_QT]) AC_REQUIRE([KDE_CHECK_LIB64]) dnl ------------------------------------------------------------------------ dnl Add configure flag to enable linking to MT version of Qt library. dnl ------------------------------------------------------------------------ AC_ARG_ENABLE( mt, AC_HELP_STRING([--disable-mt],[link to non-threaded Qt (deprecated)]), kde_use_qt_mt=$enableval, [ if test $kde_qtver = 3; then kde_use_qt_mt=yes else kde_use_qt_mt=no fi ] ) USING_QT_MT="" dnl ------------------------------------------------------------------------ dnl If we not get --disable-qt-mt then adjust some vars for the host. dnl ------------------------------------------------------------------------ KDE_MT_LDFLAGS= KDE_MT_LIBS= if test "x$kde_use_qt_mt" = "xyes"; then KDE_CHECK_THREADING if test "x$kde_use_threading" = "xyes"; then CPPFLAGS="$USE_THREADS -DQT_THREAD_SUPPORT $CPPFLAGS" KDE_MT_LDFLAGS="$USE_THREADS" KDE_MT_LIBS="$LIBPTHREAD" else kde_use_qt_mt=no fi fi AC_SUBST(KDE_MT_LDFLAGS) AC_SUBST(KDE_MT_LIBS) kde_qt_was_given=yes dnl ------------------------------------------------------------------------ dnl If we haven't been told how to link to Qt, we work it out for ourselves. dnl ------------------------------------------------------------------------ if test -z "$LIBQT_GLOB"; then if test "x$kde_use_qt_emb" = "xyes"; then LIBQT_GLOB="libqte.*" else LIBQT_GLOB="libqt.*" fi fi if test -z "$LIBQT"; then dnl ------------------------------------------------------------ dnl If we got --enable-embedded then adjust the Qt library name. dnl ------------------------------------------------------------ if test "x$kde_use_qt_emb" = "xyes"; then qtlib="qte" else qtlib="qt" fi kde_int_qt="-l$qtlib" else kde_int_qt="$LIBQT" kde_lib_qt_set=yes fi if test -z "$LIBQPE"; then dnl ------------------------------------------------------------ dnl If we got --enable-palmtop then add -lqpe to the link line dnl ------------------------------------------------------------ if test "x$kde_use_qt_emb" = "xyes"; then if test "x$kde_use_qt_emb_palm" = "xyes"; then LIB_QPE="-lqpe" else LIB_QPE="" fi else LIB_QPE="" fi fi dnl ------------------------------------------------------------------------ dnl If we got --enable-qt-mt then adjust the Qt library name for the host. dnl ------------------------------------------------------------------------ if test "x$kde_use_qt_mt" = "xyes"; then if test -z "$LIBQT"; then LIBQT="-l$qtlib-mt" kde_int_qt="-l$qtlib-mt" else LIBQT="$qtlib-mt" kde_int_qt="$qtlib-mt" fi LIBQT_GLOB="lib$qtlib-mt.*" USING_QT_MT="using -mt" else LIBQT="-l$qtlib" fi if test $kde_qtver != 1; then AC_REQUIRE([AC_FIND_PNG]) AC_REQUIRE([AC_FIND_JPEG]) LIBQT="$LIBQT $LIBPNG $LIBJPEG" fi if test $kde_qtver = 3; then AC_REQUIRE([KDE_CHECK_LIBDL]) LIBQT="$LIBQT $LIBDL" fi AC_MSG_CHECKING([for Qt]) if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBQT="$LIBQT $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET" fi ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO qt_libraries="" qt_includes="" AC_ARG_WITH(qt-dir, AC_HELP_STRING([--with-qt-dir=DIR],[where the root of Qt is installed ]), [ ac_qt_includes="$withval"/include ac_qt_libraries="$withval"/lib${kdelibsuff} ac_qt_bindir="$withval"/bin ]) AC_ARG_WITH(qt-includes, AC_HELP_STRING([--with-qt-includes=DIR],[where the Qt includes are. ]), [ ac_qt_includes="$withval" ]) kde_qt_libs_given=no AC_ARG_WITH(qt-libraries, AC_HELP_STRING([--with-qt-libraries=DIR],[where the Qt library is installed.]), [ ac_qt_libraries="$withval" kde_qt_libs_given=yes ]) AC_CACHE_VAL(ac_cv_have_qt, [#try to guess Qt locations qt_incdirs="" for dir in $kde_qt_dirs; do qt_incdirs="$qt_incdirs $dir/include $dir" done qt_incdirs="$QTINC $qt_incdirs /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/X11R6/include/qt2 /usr/include/qt3 $x_includes" if test ! "$ac_qt_includes" = "NO"; then qt_incdirs="$ac_qt_includes $qt_incdirs" fi if test "$kde_qtver" != "1"; then kde_qt_header=qstyle.h else kde_qt_header=qglobal.h fi AC_FIND_FILE($kde_qt_header, $qt_incdirs, qt_incdir) ac_qt_includes="$qt_incdir" qt_libdirs="" for dir in $kde_qt_dirs; do qt_libdirs="$qt_libdirs $dir/lib${kdelibsuff} $dir" done qt_libdirs="$QTLIB $qt_libdirs /usr/X11R6/lib /usr/lib /usr/local/qt/lib $x_libraries" if test ! "$ac_qt_libraries" = "NO"; then qt_libdir=$ac_qt_libraries else qt_libdirs="$ac_qt_libraries $qt_libdirs" # if the Qt was given, the chance is too big that libqt.* doesn't exist qt_libdir=NONE for dir in $qt_libdirs; do try="ls -1 $dir/${LIBQT_GLOB}" if test -n "`$try 2> /dev/null`"; then qt_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi done fi for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do if test -e "$a"; then LIBQT="$LIBQT ${kde_int_qt}_incremental" break fi done ac_qt_libraries="$qt_libdir" AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_cxxflags_safe="$CXXFLAGS" ac_ldflags_safe="$LDFLAGS" ac_libs_safe="$LIBS" CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" LDFLAGS="$LDFLAGS -L$qt_libdir $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" LIBS="$LIBS $LIBQT $KDE_MT_LIBS" KDE_PRINT_QT_PROGRAM if AC_TRY_EVAL(ac_link) && test -s conftest; then rm -f conftest* else echo "configure: failed program was:" >&AC_FD_CC cat conftest.$ac_ext >&AC_FD_CC ac_qt_libraries="NO" fi rm -f conftest* CXXFLAGS="$ac_cxxflags_safe" LDFLAGS="$ac_ldflags_safe" LIBS="$ac_libs_safe" AC_LANG_RESTORE if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then ac_cv_have_qt="have_qt=no" ac_qt_notfound="" missing_qt_mt="" if test "$ac_qt_includes" = NO; then if test "$ac_qt_libraries" = NO; then ac_qt_notfound="(headers and libraries)"; else ac_qt_notfound="(headers)"; fi else if test "x$kde_use_qt_mt" = "xyes"; then missing_qt_mt=" Make sure that you have compiled Qt with thread support!" ac_qt_notfound="(library $qtlib-mt)"; else ac_qt_notfound="(library $qtlib)"; fi fi AC_MSG_ERROR([Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation! For more details about this problem, look at the end of config.log.$missing_qt_mt]) else have_qt="yes" fi ]) eval "$ac_cv_have_qt" if test "$have_qt" != yes; then AC_MSG_RESULT([$have_qt]); else ac_cv_have_qt="have_qt=yes \ ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries" AC_MSG_RESULT([libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT]) qt_libraries="$ac_qt_libraries" qt_includes="$ac_qt_includes" fi if test ! "$kde_qt_libs_given" = "yes" && test ! "$kde_qtver" = 3; then KDE_CHECK_QT_DIRECT(qt_libraries= ,[]) fi AC_SUBST(qt_libraries) AC_SUBST(qt_includes) if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then QT_INCLUDES="" else QT_INCLUDES="-I$qt_includes" all_includes="$QT_INCLUDES $all_includes" fi if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then QT_LDFLAGS="" else QT_LDFLAGS="-L$qt_libraries" all_libraries="$QT_LDFLAGS $all_libraries" fi test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS" AC_SUBST(QT_INCLUDES) AC_SUBST(QT_LDFLAGS) AC_PATH_QT_MOC_UIC KDE_CHECK_QT_JPEG if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)' else LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG)' fi test -z "$KDE_MT_LIBS" || LIB_QT="$LIB_QT $KDE_MT_LIBS" for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do if test -e "$a"; then LIB_QT="$LIB_QT ${kde_int_qt}_incremental" break fi done AC_SUBST(LIB_QT) AC_SUBST(LIB_QPE) AC_SUBST(kde_qtver) ]) AC_DEFUN([AC_PATH_QT], [ AC_PATH_QT_1_3 ]) AC_DEFUN([KDE_CHECK_UIC_PLUGINS], [ AC_REQUIRE([AC_PATH_QT_MOC_UIC]) if test x$ac_uic_supports_libpath = xyes; then AC_MSG_CHECKING([if UIC has KDE plugins available]) AC_CACHE_VAL(kde_cv_uic_plugins, [ cat > actest.ui << EOF NewConnectionDialog testInput EOF kde_cv_uic_plugins=no kde_line="$UIC_PATH -L $kde_widgetdir" if test x$ac_uic_supports_nounload = xyes; then kde_line="$kde_line -nounload" fi kde_line="$kde_line -impl actest.h actest.ui > actest.cpp" if AC_TRY_EVAL(kde_line); then # if you're trying to debug this check and think it's incorrect, # better check your installation. The check _is_ correct - your # installation is not. if test -f actest.cpp && grep klineedit actest.cpp > /dev/null; then kde_cv_uic_plugins=yes fi fi rm -f actest.ui actest.cpp ]) AC_MSG_RESULT([$kde_cv_uic_plugins]) if test "$kde_cv_uic_plugins" != yes; then AC_MSG_ERROR([you need to install kdelibs first.]) fi fi ]) AC_DEFUN([KDE_CHECK_FINAL], [ AC_ARG_ENABLE(final, AC_HELP_STRING([--enable-final], [build size optimized apps (experimental - needs lots of memory)]), kde_use_final=$enableval, kde_use_final=no) if test "x$kde_use_final" = "xyes"; then KDE_USE_FINAL_TRUE="" KDE_USE_FINAL_FALSE="#" else KDE_USE_FINAL_TRUE="#" KDE_USE_FINAL_FALSE="" fi AC_SUBST(KDE_USE_FINAL_TRUE) AC_SUBST(KDE_USE_FINAL_FALSE) ]) AC_DEFUN([KDE_CHECK_CLOSURE], [ AC_ARG_ENABLE(closure, AC_HELP_STRING([--enable-closure],[delay template instantiation]), kde_use_closure=$enableval, kde_use_closure=no) KDE_NO_UNDEFINED="" if test "x$kde_use_closure" = "xyes"; then KDE_USE_CLOSURE_TRUE="" KDE_USE_CLOSURE_FALSE="#" # CXXFLAGS="$CXXFLAGS $REPO" else KDE_USE_CLOSURE_TRUE="#" KDE_USE_CLOSURE_FALSE="" KDE_NO_UNDEFINED="" case $host in *-*-linux-gnu) KDE_CHECK_COMPILER_FLAG([Wl,--no-undefined], [KDE_CHECK_COMPILER_FLAG([Wl,--allow-shlib-undefined], [KDE_NO_UNDEFINED="-Wl,--no-undefined -Wl,--allow-shlib-undefined"], [KDE_NO_UNDEFINED=""])], [KDE_NO_UNDEFINED=""]) ;; esac fi AC_SUBST(KDE_USE_CLOSURE_TRUE) AC_SUBST(KDE_USE_CLOSURE_FALSE) AC_SUBST(KDE_NO_UNDEFINED) ]) dnl Check if the linker supports --enable-new-dtags and --as-needed AC_DEFUN([KDE_CHECK_NEW_LDFLAGS], [ AC_ARG_ENABLE(new_ldflags, AC_HELP_STRING([--enable-new-ldflags], [enable the new linker flags]), kde_use_new_ldflags=$enableval, kde_use_new_ldflags=no) LDFLAGS_AS_NEEDED="" LDFLAGS_NEW_DTAGS="" if test "x$kde_use_new_ldflags" = "xyes"; then LDFLAGS_NEW_DTAGS="" KDE_CHECK_COMPILER_FLAG([Wl,--enable-new-dtags], [LDFLAGS_NEW_DTAGS="-Wl,--enable-new-dtags"],) KDE_CHECK_COMPILER_FLAG([Wl,--as-needed], [LDFLAGS_AS_NEEDED="-Wl,--as-needed"],) fi AC_SUBST(LDFLAGS_AS_NEEDED) AC_SUBST(LDFLAGS_NEW_DTAGS) ]) AC_DEFUN([KDE_CHECK_NMCHECK], [ AC_ARG_ENABLE(nmcheck,AC_HELP_STRING([--enable-nmcheck],[enable automatic namespace cleanness check]), kde_use_nmcheck=$enableval, kde_use_nmcheck=no) if test "$kde_use_nmcheck" = "yes"; then KDE_USE_NMCHECK_TRUE="" KDE_USE_NMCHECK_FALSE="#" else KDE_USE_NMCHECK_TRUE="#" KDE_USE_NMCHECK_FALSE="" fi AC_SUBST(KDE_USE_NMCHECK_TRUE) AC_SUBST(KDE_USE_NMCHECK_FALSE) ]) AC_DEFUN([KDE_EXPAND_MAKEVAR], [ savex=$exec_prefix test "x$exec_prefix" = xNONE && exec_prefix=$prefix tmp=$$2 while $1=`eval echo "$tmp"`; test "x$$1" != "x$tmp"; do tmp=$$1; done exec_prefix=$savex ]) dnl ------------------------------------------------------------------------ dnl Now, the same with KDE dnl $(KDE_LDFLAGS) will be the kdeliblocation (if needed) dnl and $(kde_includes) will be the kdehdrlocation (if needed) dnl ------------------------------------------------------------------------ dnl AC_DEFUN([AC_BASE_PATH_KDE], [ AC_REQUIRE([KDE_CHECK_STL]) AC_REQUIRE([AC_PATH_QT])dnl AC_REQUIRE([KDE_CHECK_LIB64]) AC_CHECK_RPATH AC_MSG_CHECKING([for KDE]) if test "${prefix}" != NONE; then kde_includes=${includedir} KDE_EXPAND_MAKEVAR(ac_kde_includes, includedir) kde_libraries=${libdir} KDE_EXPAND_MAKEVAR(ac_kde_libraries, libdir) else ac_kde_includes= ac_kde_libraries= kde_libraries="" kde_includes="" fi AC_CACHE_VAL(ac_cv_have_kde, [#try to guess kde locations if test "$kde_qtver" = 1; then kde_check_header="ksock.h" kde_check_lib="libkdecore.la" else kde_check_header="ksharedptr.h" kde_check_lib="libkio.la" fi if test -z "$1"; then kde_incdirs="$kde_libs_prefix/include /usr/lib/kde/include /usr/local/kde/include /usr/local/include /usr/kde/include /usr/include/kde /usr/include /opt/kde3/include /opt/kde/include $x_includes $qt_includes" test -n "$KDEDIR" && kde_incdirs="$KDEDIR/include $KDEDIR/include/kde $KDEDIR $kde_incdirs" kde_incdirs="$ac_kde_includes $kde_incdirs" AC_FIND_FILE($kde_check_header, $kde_incdirs, kde_incdir) ac_kde_includes="$kde_incdir" if test -n "$ac_kde_includes" && test ! -r "$ac_kde_includes/$kde_check_header"; then AC_MSG_ERROR([ in the prefix, you've chosen, are no KDE headers installed. This will fail. So, check this please and use another prefix!]) fi kde_libdirs="$kde_libs_prefix/lib${kdelibsuff} /usr/lib/kde/lib${kdelibsuff} /usr/local/kde/lib${kdelibsuff} /usr/kde/lib${kdelibsuff} /usr/lib${kdelibsuff}/kde /usr/lib${kdelibsuff}/kde3 /usr/lib${kdelibsuff} /usr/X11R6/lib${kdelibsuff} /usr/local/lib${kdelibsuff} /opt/kde3/lib${kdelibsuff} /opt/kde/lib${kdelibsuff} /usr/X11R6/kde/lib${kdelibsuff}" test -n "$KDEDIR" && kde_libdirs="$KDEDIR/lib${kdelibsuff} $KDEDIR $kde_libdirs" kde_libdirs="$ac_kde_libraries $libdir $kde_libdirs" AC_FIND_FILE($kde_check_lib, $kde_libdirs, kde_libdir) ac_kde_libraries="$kde_libdir" kde_widgetdir=NO dnl this might be somewhere else AC_FIND_FILE("kde3/plugins/designer/kdewidgets.la", $kde_libdirs, kde_widgetdir) if test -n "$ac_kde_libraries" && test ! -r "$ac_kde_libraries/$kde_check_lib"; then AC_MSG_ERROR([ in the prefix, you've chosen, are no KDE libraries installed. This will fail. So, check this please and use another prefix!]) fi if test -n "$kde_widgetdir" && test ! -r "$kde_widgetdir/kde3/plugins/designer/kdewidgets.la"; then AC_MSG_ERROR([ I can't find the designer plugins. These are required and should have been installed by kdelibs]) fi if test -n "$kde_widgetdir"; then kde_widgetdir="$kde_widgetdir/kde3/plugins/designer" fi if test "$ac_kde_includes" = NO || test "$ac_kde_libraries" = NO || test "$kde_widgetdir" = NO; then ac_cv_have_kde="have_kde=no" else ac_cv_have_kde="have_kde=yes \ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" fi else dnl test -z $1, e.g. from kdelibs ac_cv_have_kde="have_kde=no" fi ])dnl eval "$ac_cv_have_kde" if test "$have_kde" != "yes"; then if test "${prefix}" = NONE; then ac_kde_prefix="$ac_default_prefix" else ac_kde_prefix="$prefix" fi if test "$exec_prefix" = NONE; then ac_kde_exec_prefix="$ac_kde_prefix" AC_MSG_RESULT([will be installed in $ac_kde_prefix]) else ac_kde_exec_prefix="$exec_prefix" AC_MSG_RESULT([will be installed in $ac_kde_prefix and $ac_kde_exec_prefix]) fi kde_libraries="${libdir}" kde_includes="${includedir}" else ac_cv_have_kde="have_kde=yes \ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" AC_MSG_RESULT([libraries $ac_kde_libraries, headers $ac_kde_includes]) kde_libraries="$ac_kde_libraries" kde_includes="$ac_kde_includes" fi AC_SUBST(kde_libraries) AC_SUBST(kde_includes) if test "$kde_includes" = "$x_includes" || test "$kde_includes" = "$qt_includes" || test "$kde_includes" = "/usr/include"; then KDE_INCLUDES="" else KDE_INCLUDES="-I$kde_includes" all_includes="$KDE_INCLUDES $all_includes" fi KDE_DEFAULT_CXXFLAGS="-DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION" KDE_LDFLAGS="-L$kde_libraries" if test ! "$kde_libraries" = "$x_libraries" && test ! "$kde_libraries" = "$qt_libraries" ; then all_libraries="$KDE_LDFLAGS $all_libraries" fi AC_SUBST(KDE_LDFLAGS) AC_SUBST(KDE_INCLUDES) AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) all_libraries="$all_libraries $USER_LDFLAGS" all_includes="$all_includes $USER_INCLUDES" AC_SUBST(all_includes) AC_SUBST(all_libraries) if test -z "$1"; then KDE_CHECK_UIC_PLUGINS fi ac_kde_libraries="$kde_libdir" AC_SUBST(AUTODIRS) ]) AC_DEFUN([KDE_CHECK_EXTRA_LIBS], [ AC_MSG_CHECKING(for extra includes) AC_ARG_WITH(extra-includes,AC_HELP_STRING([--with-extra-includes=DIR],[adds non standard include paths]), kde_use_extra_includes="$withval", kde_use_extra_includes=NONE ) kde_extra_includes= if test -n "$kde_use_extra_includes" && \ test "$kde_use_extra_includes" != "NONE"; then ac_save_ifs=$IFS IFS=':' for dir in $kde_use_extra_includes; do kde_extra_includes="$kde_extra_includes $dir" USER_INCLUDES="$USER_INCLUDES -I$dir" done IFS=$ac_save_ifs kde_use_extra_includes="added" else kde_use_extra_includes="no" fi AC_SUBST(USER_INCLUDES) AC_MSG_RESULT($kde_use_extra_includes) kde_extra_libs= AC_MSG_CHECKING(for extra libs) AC_ARG_WITH(extra-libs,AC_HELP_STRING([--with-extra-libs=DIR],[adds non standard library paths]), kde_use_extra_libs=$withval, kde_use_extra_libs=NONE ) if test -n "$kde_use_extra_libs" && \ test "$kde_use_extra_libs" != "NONE"; then ac_save_ifs=$IFS IFS=':' for dir in $kde_use_extra_libs; do kde_extra_libs="$kde_extra_libs $dir" KDE_EXTRA_RPATH="$KDE_EXTRA_RPATH -R $dir" USER_LDFLAGS="$USER_LDFLAGS -L$dir" done IFS=$ac_save_ifs kde_use_extra_libs="added" else kde_use_extra_libs="no" fi AC_SUBST(USER_LDFLAGS) AC_MSG_RESULT($kde_use_extra_libs) ]) AC_DEFUN([KDE_1_CHECK_PATH_HEADERS], [ AC_MSG_CHECKING([for KDE headers installed]) AC_LANG_SAVE AC_LANG_CPLUSPLUS cat > conftest.$ac_ext < #endif #include #include "confdefs.h" #include int main() { printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data()); printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data()); printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data()); printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data()); printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data()); printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data()); printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data()); printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data()); printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data()); printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data()); printf("kde_wallpaperdir=\\"%s\\"\n", KApplication::kde_wallpaperdir().data()); printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data()); printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data()); printf("kde_servicesdir=\\"/tmp/dummy\\"\n"); printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n"); printf("kde_moduledir=\\"/tmp/dummy\\"\n"); printf("kde_styledir=\\"/tmp/dummy\\"\n"); printf("kde_widgetdir=\\"/tmp/dummy\\"\n"); printf("xdg_appsdir=\\"/tmp/dummy\\"\n"); printf("xdg_menudir=\\"/tmp/dummy\\"\n"); printf("xdg_directorydir=\\"/tmp/dummy\\"\n"); printf("kde_kcfgdir=\\"/tmp/dummy\\"\n"); return 0; } EOF ac_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$all_includes $CPPFLAGS" if AC_TRY_EVAL(ac_compile); then AC_MSG_RESULT(yes) else AC_MSG_ERROR([your system is not able to compile a small KDE application! Check, if you installed the KDE header files correctly. For more details about this problem, look at the end of config.log.]) fi CPPFLAGS=$ac_save_CPPFLAGS AC_LANG_RESTORE ]) AC_DEFUN([KDE_CHECK_KDEQTADDON], [ AC_MSG_CHECKING(for kde-qt-addon) AC_CACHE_VAL(kde_cv_have_kdeqtaddon, [ kde_ldflags_safe="$LDFLAGS" kde_libs_safe="$LIBS" kde_cxxflags_safe="$CXXFLAGS" LIBS="-lkde-qt-addon $LIBQT $LIBS" CXXFLAGS="$CXXFLAGS -I$prefix/include -I$prefix/include/kde $all_includes" LDFLAGS="$LDFLAGS $all_libraries $USER_LDFLAGS" AC_TRY_LINK([ #include ], [ QDomDocument doc; ], kde_cv_have_kdeqtaddon=yes, kde_cv_have_kdeqtaddon=no ) LDFLAGS=$kde_ldflags_safe LIBS=$kde_libs_safe CXXFLAGS=$kde_cxxflags_safe ]) AC_MSG_RESULT($kde_cv_have_kdeqtaddon) if test "$kde_cv_have_kdeqtaddon" = "no"; then AC_MSG_ERROR([Can't find libkde-qt-addon. You need to install it first. It is a separate package (and CVS module) named kde-qt-addon.]) fi ]) AC_DEFUN([KDE_CREATE_LIBS_ALIASES], [ AC_REQUIRE([KDE_MISC_TESTS]) AC_REQUIRE([KDE_CHECK_LIBDL]) AC_REQUIRE([K_PATH_X]) if test $kde_qtver = 3; then AC_SUBST(LIB_KDECORE, "-lkdecore") AC_SUBST(LIB_KDEUI, "-lkdeui") AC_SUBST(LIB_KIO, "-lkio") AC_SUBST(LIB_KJS, "-lkjs") AC_SUBST(LIB_SMB, "-lsmb") AC_SUBST(LIB_KAB, "-lkab") AC_SUBST(LIB_KABC, "-lkabc") AC_SUBST(LIB_KHTML, "-lkhtml") AC_SUBST(LIB_KSPELL, "-lkspell") AC_SUBST(LIB_KPARTS, "-lkparts") AC_SUBST(LIB_KDEPRINT, "-lkdeprint") AC_SUBST(LIB_KUTILS, "-lkutils") AC_SUBST(LIB_KDEPIM, "-lkdepim") AC_SUBST(LIB_KIMPROXY, "-lkimproxy") AC_SUBST(LIB_KNEWSTUFF, "-lknewstuff") AC_SUBST(LIB_KDNSSD, "-lkdnssd") # these are for backward compatibility AC_SUBST(LIB_KSYCOCA, "-lkio") AC_SUBST(LIB_KFILE, "-lkio") elif test $kde_qtver = 2; then AC_SUBST(LIB_KDECORE, "-lkdecore") AC_SUBST(LIB_KDEUI, "-lkdeui") AC_SUBST(LIB_KIO, "-lkio") AC_SUBST(LIB_KSYCOCA, "-lksycoca") AC_SUBST(LIB_SMB, "-lsmb") AC_SUBST(LIB_KFILE, "-lkfile") AC_SUBST(LIB_KAB, "-lkab") AC_SUBST(LIB_KHTML, "-lkhtml") AC_SUBST(LIB_KSPELL, "-lkspell") AC_SUBST(LIB_KPARTS, "-lkparts") AC_SUBST(LIB_KDEPRINT, "-lkdeprint") else AC_SUBST(LIB_KDECORE, "-lkdecore -lXext $(LIB_QT)") AC_SUBST(LIB_KDEUI, "-lkdeui $(LIB_KDECORE)") AC_SUBST(LIB_KFM, "-lkfm $(LIB_KDECORE)") AC_SUBST(LIB_KFILE, "-lkfile $(LIB_KFM) $(LIB_KDEUI)") AC_SUBST(LIB_KAB, "-lkab $(LIB_KIMGIO) $(LIB_KDECORE)") fi ]) AC_DEFUN([AC_PATH_KDE], [ AC_BASE_PATH_KDE AC_ARG_ENABLE(path-check,AC_HELP_STRING([--disable-path-check],[don't try to find out, where to install]), [ if test "$enableval" = "no"; then ac_use_path_checking="default" else ac_use_path_checking="" fi ], [ if test "$kde_qtver" = 1; then ac_use_path_checking="" else ac_use_path_checking="default" fi ] ) AC_CREATE_KFSSTND($ac_use_path_checking) AC_SUBST_KFSSTND KDE_CREATE_LIBS_ALIASES ]) dnl KDE_CHECK_FUNC_EXT(, [headers], [sample-use], [C prototype], [autoheader define], [call if found]) AC_DEFUN([KDE_CHECK_FUNC_EXT], [ AC_MSG_CHECKING(for $1) AC_CACHE_VAL(kde_cv_func_$1, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS save_CXXFLAGS="$CXXFLAGS" kde_safe_LIBS="$LIBS" LIBS="$LIBS $X_EXTRA_LIBS" if test "$GXX" = "yes"; then CXXFLAGS="$CXXFLAGS -pedantic-errors" fi AC_TRY_COMPILE([ $2 ], [ $3 ], kde_cv_func_$1=yes, kde_cv_func_$1=no) CXXFLAGS="$save_CXXFLAGS" LIBS="$kde_safe_LIBS" AC_LANG_RESTORE ]) AC_MSG_RESULT($kde_cv_func_$1) AC_MSG_CHECKING([if $1 needs custom prototype]) AC_CACHE_VAL(kde_cv_proto_$1, [ if test "x$kde_cv_func_$1" = xyes; then kde_cv_proto_$1=no else case "$1" in setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat) kde_cv_proto_$1="yes - in libkdefakes" ;; *) kde_cv_proto_$1=unknown ;; esac fi if test "x$kde_cv_proto_$1" = xunknown; then AC_LANG_SAVE AC_LANG_CPLUSPLUS kde_safe_libs=$LIBS LIBS="$LIBS $X_EXTRA_LIBS" AC_TRY_LINK([ $2 extern "C" $4; ], [ $3 ], [ kde_cv_func_$1=yes kde_cv_proto_$1=yes ], [kde_cv_proto_$1="$1 unavailable"] ) LIBS=$kde_safe_libs AC_LANG_RESTORE fi ]) AC_MSG_RESULT($kde_cv_proto_$1) if test "x$kde_cv_func_$1" = xyes; then AC_DEFINE(HAVE_$5, 1, [Define if you have $1]) $6 fi if test "x$kde_cv_proto_$1" = xno; then AC_DEFINE(HAVE_$5_PROTO, 1, [Define if you have the $1 prototype]) fi AH_VERBATIM([_HAVE_$5_PROTO], [ #if !defined(HAVE_$5_PROTO) #ifdef __cplusplus extern "C" { #endif $4; #ifdef __cplusplus } #endif #endif ]) ]) AC_DEFUN([AC_CHECK_SETENV], [ KDE_CHECK_FUNC_EXT(setenv, [ #include ], [setenv("VAR", "VALUE", 1);], [int setenv (const char *, const char *, int)], [SETENV]) ]) AC_DEFUN([AC_CHECK_UNSETENV], [ KDE_CHECK_FUNC_EXT(unsetenv, [ #include ], [unsetenv("VAR");], [void unsetenv (const char *)], [UNSETENV]) ]) AC_DEFUN([AC_CHECK_GETDOMAINNAME], [ KDE_CHECK_FUNC_EXT(getdomainname, [ #include #include #include ], [ char buffer[200]; getdomainname(buffer, 200); ], [#include int getdomainname (char *, size_t)], [GETDOMAINNAME]) ]) AC_DEFUN([AC_CHECK_GETHOSTNAME], [ KDE_CHECK_FUNC_EXT(gethostname, [ #include #include ], [ char buffer[200]; gethostname(buffer, 200); ], [int gethostname (char *, unsigned int)], [GETHOSTNAME]) ]) AC_DEFUN([AC_CHECK_USLEEP], [ KDE_CHECK_FUNC_EXT(usleep, [ #include ], [ usleep(200); ], [int usleep (unsigned int)], [USLEEP]) ]) AC_DEFUN([AC_CHECK_RANDOM], [ KDE_CHECK_FUNC_EXT(random, [ #include ], [ random(); ], [long int random(void)], [RANDOM]) KDE_CHECK_FUNC_EXT(srandom, [ #include ], [ srandom(27); ], [void srandom(unsigned int)], [SRANDOM]) ]) AC_DEFUN([AC_CHECK_INITGROUPS], [ KDE_CHECK_FUNC_EXT(initgroups, [ #include #include #include ], [ char buffer[200]; initgroups(buffer, 27); ], [int initgroups(const char *, gid_t)], [INITGROUPS]) ]) AC_DEFUN([AC_CHECK_MKSTEMPS], [ KDE_CHECK_FUNC_EXT(mkstemps, [ #include #include ], [ mkstemps("/tmp/aaaXXXXXX", 6); ], [int mkstemps(char *, int)], [MKSTEMPS]) ]) AC_DEFUN([AC_CHECK_MKSTEMP], [ KDE_CHECK_FUNC_EXT(mkstemp, [ #include #include ], [ mkstemp("/tmp/aaaXXXXXX"); ], [int mkstemp(char *)], [MKSTEMP]) ]) AC_DEFUN([AC_CHECK_MKDTEMP], [ KDE_CHECK_FUNC_EXT(mkdtemp, [ #include #include ], [ mkdtemp("/tmp/aaaXXXXXX"); ], [char *mkdtemp(char *)], [MKDTEMP]) ]) AC_DEFUN([AC_CHECK_RES_INIT], [ AC_MSG_CHECKING([if res_init needs -lresolv]) kde_libs_safe="$LIBS" LIBS="$LIBS $X_EXTRA_LIBS -lresolv" AC_TRY_LINK( [ #include #include #include #include ], [ res_init(); ], [ LIBRESOLV="-lresolv" AC_MSG_RESULT(yes) AC_DEFINE(HAVE_RES_INIT, 1, [Define if you have the res_init function]) ], [ AC_MSG_RESULT(no) ] ) LIBS=$kde_libs_safe AC_SUBST(LIBRESOLV) KDE_CHECK_FUNC_EXT(res_init, [ #include #include #include #include ], [res_init()], [int res_init(void)], [RES_INIT]) ]) AC_DEFUN([AC_CHECK_STRLCPY], [ KDE_CHECK_FUNC_EXT(strlcpy, [ #include ], [ char buf[20]; strlcpy(buf, "KDE function test", sizeof(buf)); ], [unsigned long strlcpy(char*, const char*, unsigned long)], [STRLCPY]) ]) AC_DEFUN([AC_CHECK_STRLCAT], [ KDE_CHECK_FUNC_EXT(strlcat, [ #include ], [ char buf[20]; buf[0]='\0'; strlcat(buf, "KDE function test", sizeof(buf)); ], [unsigned long strlcat(char*, const char*, unsigned long)], [STRLCAT]) ]) AC_DEFUN([AC_CHECK_RES_QUERY], [ KDE_CHECK_FUNC_EXT(res_query, [ #include #include #include #include #include ], [ res_query(NULL, 0, 0, NULL, 0); ], [int res_query(const char *, int, int, unsigned char *, int)], [RES_QUERY]) ]) AC_DEFUN([AC_CHECK_DN_SKIPNAME], [ KDE_CHECK_FUNC_EXT(dn_skipname, [ #include #include #include #include ], [ dn_skipname (NULL, NULL); ], [int dn_skipname (unsigned char *, unsigned char *)], [DN_SKIPNAME]) ]) AC_DEFUN([AC_FIND_GIF], [AC_MSG_CHECKING([for giflib]) AC_CACHE_VAL(ac_cv_lib_gif, [ac_save_LIBS="$LIBS" if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBS="$all_libraries -lgif -lX11 $LIBSOCKET" else LIBS="$all_libraries -lgif" fi AC_TRY_LINK(dnl [ #ifdef __cplusplus extern "C" { #endif int GifLastError(void); #ifdef __cplusplus } #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ ], [return GifLastError();], eval "ac_cv_lib_gif=yes", eval "ac_cv_lib_gif=no") LIBS="$ac_save_LIBS" ])dnl if eval "test \"`echo $ac_cv_lib_gif`\" = yes"; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(HAVE_LIBGIF, 1, [Define if you have libgif]) else AC_MSG_ERROR(You need giflib30. Please install the kdesupport package) fi ]) AC_DEFUN([KDE_FIND_JPEG_HELPER], [ AC_MSG_CHECKING([for libjpeg$2]) AC_CACHE_VAL(ac_cv_lib_jpeg_$1, [ ac_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS -ljpeg$2 -lm" ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK( [/* Override any gcc2 internal prototype to avoid an error. */ struct jpeg_decompress_struct; typedef struct jpeg_decompress_struct * j_decompress_ptr; typedef int size_t; #ifdef __cplusplus extern "C" { #endif void jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t structsize); #ifdef __cplusplus } #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ ], [jpeg_CreateDecompress(0L, 0, 0);], eval "ac_cv_lib_jpeg_$1=-ljpeg$2", eval "ac_cv_lib_jpeg_$1=no") LIBS="$ac_save_LIBS" CFLAGS="$ac_save_CFLAGS" ]) if eval "test ! \"`echo $ac_cv_lib_jpeg_$1`\" = no"; then LIBJPEG="$ac_cv_lib_jpeg_$1" AC_MSG_RESULT($ac_cv_lib_jpeg_$1) else AC_MSG_RESULT(no) $3 fi ]) AC_DEFUN([AC_FIND_JPEG], [ dnl first look for libraries KDE_FIND_JPEG_HELPER(6b, 6b, KDE_FIND_JPEG_HELPER(normal, [], [ LIBJPEG= ] ) ) dnl then search the headers (can't use simply AC_TRY_xxx, as jpeglib.h dnl requires system dependent includes loaded before it) jpeg_incdirs="$includedir /usr/include /usr/local/include $kde_extra_includes" AC_FIND_FILE(jpeglib.h, $jpeg_incdirs, jpeg_incdir) test "x$jpeg_incdir" = xNO && jpeg_incdir= dnl if headers _and_ libraries are missing, this is no error, and we dnl continue with a warning (the user will get no jpeg support in khtml) dnl if only one is missing, it means a configuration error, but we still dnl only warn if test -n "$jpeg_incdir" && test -n "$LIBJPEG" ; then AC_DEFINE_UNQUOTED(HAVE_LIBJPEG, 1, [Define if you have libjpeg]) else if test -n "$jpeg_incdir" || test -n "$LIBJPEG" ; then AC_MSG_WARN([ There is an installation error in jpeg support. You seem to have only one of either the headers _or_ the libraries installed. You may need to either provide correct --with-extra-... options, or the development package of libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/ Disabling JPEG support. ]) else AC_MSG_WARN([libjpeg not found. disable JPEG support.]) fi jpeg_incdir= LIBJPEG= fi AC_SUBST(LIBJPEG) AH_VERBATIM(_AC_CHECK_JPEG, [/* * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system * headers and I'm too lazy to write a configure test as long as only * unixware is related */ #ifdef _UNIXWARE #define HAVE_BOOLEAN #endif ]) ]) AC_DEFUN([KDE_CHECK_QT_JPEG], [ if test -n "$LIBJPEG"; then AC_MSG_CHECKING([if Qt needs $LIBJPEG]) AC_CACHE_VAL(kde_cv_qt_jpeg, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS $LIBQT" LIBS=`echo $LIBS | sed "s/$LIBJPEG//"` ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK( [#include ], [ int argc; char** argv; QApplication app(argc, argv);], eval "kde_cv_qt_jpeg=no", eval "kde_cv_qt_jpeg=yes") LIBS="$ac_save_LIBS" CXXFLAGS="$ac_save_CXXFLAGS" AC_LANG_RESTORE fi ]) if eval "test ! \"`echo $kde_cv_qt_jpeg`\" = no"; then AC_MSG_RESULT(yes) LIBJPEG_QT='$(LIBJPEG)' else AC_MSG_RESULT(no) LIBJPEG_QT= fi ]) AC_DEFUN([AC_FIND_ZLIB], [ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) AC_MSG_CHECKING([for libz]) AC_CACHE_VAL(ac_cv_lib_z, [ kde_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS -lz $LIBSOCKET" kde_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK(dnl [ #include ], [ char buf[42]; gzFile f = (gzFile) 0; /* this would segfault.. but we only link, don't run */ (void) gzgets(f, buf, sizeof(buf)); return (zlibVersion() == ZLIB_VERSION); ], eval "ac_cv_lib_z='-lz'", eval "ac_cv_lib_z=no") LIBS="$kde_save_LIBS" CFLAGS="$kde_save_CFLAGS" ])dnl if test ! "$ac_cv_lib_z" = no; then AC_DEFINE_UNQUOTED(HAVE_LIBZ, 1, [Define if you have libz]) LIBZ="$ac_cv_lib_z" AC_MSG_RESULT($ac_cv_lib_z) else AC_MSG_ERROR(not found. Possibly configure picks up an outdated version installed by XFree86. Remove it from your system. Check your installation and look into config.log) LIBZ="" fi AC_SUBST(LIBZ) ]) AC_DEFUN([KDE_TRY_TIFFLIB], [ AC_MSG_CHECKING([for libtiff $1]) AC_CACHE_VAL(kde_cv_libtiff_$1, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS kde_save_LIBS="$LIBS" if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lX11 $LIBSOCKET -lm" else LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lm" fi kde_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK(dnl [ #include ], [return (TIFFOpen( "", "r") == 0); ], [ kde_cv_libtiff_$1="-l$1 $LIBJPEG $LIBZ" ], [ kde_cv_libtiff_$1=no ]) LIBS="$kde_save_LIBS" CXXFLAGS="$kde_save_CXXFLAGS" AC_LANG_RESTORE ]) if test "$kde_cv_libtiff_$1" = "no"; then AC_MSG_RESULT(no) LIBTIFF="" $3 else LIBTIFF="$kde_cv_libtiff_$1" AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(HAVE_LIBTIFF, 1, [Define if you have libtiff]) $2 fi ]) AC_DEFUN([AC_FIND_TIFF], [ AC_REQUIRE([K_PATH_X]) AC_REQUIRE([AC_FIND_ZLIB]) AC_REQUIRE([AC_FIND_JPEG]) AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) KDE_TRY_TIFFLIB(tiff, [], KDE_TRY_TIFFLIB(tiff34)) AC_SUBST(LIBTIFF) ]) AC_DEFUN([AC_FIND_PNG], [ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) AC_REQUIRE([AC_FIND_ZLIB]) AC_MSG_CHECKING([for libpng]) AC_CACHE_VAL(ac_cv_lib_png, [ kde_save_LIBS="$LIBS" if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm -lX11 $LIBSOCKET" else LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm" fi kde_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK(dnl [ #include ], [ png_structp png_ptr = png_create_read_struct( /* image ptr */ PNG_LIBPNG_VER_STRING, 0, 0, 0 ); return( png_ptr != 0 ); ], eval "ac_cv_lib_png='-lpng $LIBZ -lm'", eval "ac_cv_lib_png=no" ) LIBS="$kde_save_LIBS" CFLAGS="$kde_save_CFLAGS" ])dnl if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then AC_DEFINE_UNQUOTED(HAVE_LIBPNG, 1, [Define if you have libpng]) LIBPNG="$ac_cv_lib_png" AC_SUBST(LIBPNG) AC_MSG_RESULT($ac_cv_lib_png) else AC_MSG_RESULT(no) LIBPNG="" AC_SUBST(LIBPNG) fi ]) AC_DEFUN([AC_FIND_JASPER], [ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) AC_REQUIRE([AC_FIND_JPEG]) AC_MSG_CHECKING([for jasper]) AC_CACHE_VAL(ac_cv_jasper, [ kde_save_LIBS="$LIBS" LIBS="$LIBS $all_libraries $USER_LDFLAGS -ljasper $LIBJPEG -lm" kde_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK(dnl [ #include ], [ return( jas_init() ); ], eval "ac_cv_jasper='-ljasper $LIBJPEG -lm'", eval "ac_cv_jasper=no" ) LIBS="$kde_save_LIBS" CFLAGS="$kde_save_CFLAGS" ])dnl if eval "test ! \"`echo $ac_cv_jasper`\" = no"; then AC_DEFINE_UNQUOTED(HAVE_JASPER, 1, [Define if you have jasper]) LIB_JASPER="$ac_cv_jasper" AC_MSG_RESULT($ac_cv_jasper) else AC_MSG_RESULT(no) LIB_JASPER="" fi AC_SUBST(LIB_JASPER) ]) AC_DEFUN([AC_CHECK_BOOL], [ AC_DEFINE_UNQUOTED(HAVE_BOOL, 1, [You _must_ have bool]) ]) AC_DEFUN([AC_CHECK_GNU_EXTENSIONS], [ AC_MSG_CHECKING(if you need GNU extensions) AC_CACHE_VAL(ac_cv_gnu_extensions, [ cat > conftest.c << EOF #include #ifdef __GNU_LIBRARY__ yes #endif EOF if (eval "$ac_cpp conftest.c") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ac_cv_gnu_extensions=yes else ac_cv_gnu_extensions=no fi ]) AC_MSG_RESULT($ac_cv_gnu_extensions) if test "$ac_cv_gnu_extensions" = "yes"; then AC_DEFINE_UNQUOTED(_GNU_SOURCE, 1, [Define if you need to use the GNU extensions]) fi ]) AC_DEFUN([KDE_CHECK_COMPILER_FLAG], [ AC_MSG_CHECKING([whether $CXX supports -$1]) kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'` AC_CACHE_VAL(kde_cv_prog_cxx_$kde_cache, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -$1" AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cxx_$kde_cache=yes"], []) CXXFLAGS="$save_CXXFLAGS" AC_LANG_RESTORE ]) if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then AC_MSG_RESULT(yes) : $2 else AC_MSG_RESULT(no) : $3 fi ]) AC_DEFUN([KDE_CHECK_C_COMPILER_FLAG], [ AC_MSG_CHECKING([whether $CC supports -$1]) kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'` AC_CACHE_VAL(kde_cv_prog_cc_$kde_cache, [ AC_LANG_SAVE AC_LANG_C save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -$1" AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cc_$kde_cache=yes"], []) CFLAGS="$save_CFLAGS" AC_LANG_RESTORE ]) if eval "test \"`echo '$kde_cv_prog_cc_'$kde_cache`\" = yes"; then AC_MSG_RESULT(yes) : $2 else AC_MSG_RESULT(no) : $3 fi ]) dnl AC_REMOVE_FORBIDDEN removes forbidden arguments from variables dnl use: AC_REMOVE_FORBIDDEN(CC, [-forbid -bad-option whatever]) dnl it's all white-space separated AC_DEFUN([AC_REMOVE_FORBIDDEN], [ __val=$$1 __forbid=" $2 " if test -n "$__val"; then __new="" ac_save_IFS=$IFS IFS=" " for i in $__val; do case "$__forbid" in *" $i "*) AC_MSG_WARN([found forbidden $i in $1, removing it]) ;; *) # Careful to not add spaces, where there were none, because otherwise # libtool gets confused, if we change e.g. CXX if test -z "$__new" ; then __new=$i ; else __new="$__new $i" ; fi ;; esac done IFS=$ac_save_IFS $1=$__new fi ]) dnl AC_VALIDIFY_CXXFLAGS checks for forbidden flags the user may have given AC_DEFUN([AC_VALIDIFY_CXXFLAGS], [dnl if test "x$kde_use_qt_emb" != "xyes"; then AC_REMOVE_FORBIDDEN(CXX, [-fno-rtti -rpath]) AC_REMOVE_FORBIDDEN(CXXFLAGS, [-fno-rtti -rpath]) else AC_REMOVE_FORBIDDEN(CXX, [-rpath]) AC_REMOVE_FORBIDDEN(CXXFLAGS, [-rpath]) fi ]) AC_DEFUN([AC_CHECK_COMPILERS], [ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug=ARG],[enables debug symbols (yes|no|full) [default=no]]), [ case $enableval in yes) kde_use_debug_code="yes" kde_use_debug_define=no ;; full) kde_use_debug_code="full" kde_use_debug_define=no ;; *) kde_use_debug_code="no" kde_use_debug_define=yes ;; esac ], [kde_use_debug_code="no" kde_use_debug_define=no ]) dnl Just for configure --help AC_ARG_ENABLE(dummyoption, AC_HELP_STRING([--disable-debug], [disables debug output and debug symbols [default=no]]), [],[]) AC_ARG_ENABLE(strict, AC_HELP_STRING([--enable-strict], [compiles with strict compiler options (may not work!)]), [ if test $enableval = "no"; then kde_use_strict_options="no" else kde_use_strict_options="yes" fi ], [kde_use_strict_options="no"]) AC_ARG_ENABLE(warnings,AC_HELP_STRING([--disable-warnings],[disables compilation with -Wall and similar]), [ if test $enableval = "no"; then kde_use_warnings="no" else kde_use_warnings="yes" fi ], [kde_use_warnings="yes"]) dnl enable warnings for debug build if test "$kde_use_debug_code" != "no"; then kde_use_warnings=yes fi AC_ARG_ENABLE(profile,AC_HELP_STRING([--enable-profile],[creates profiling infos [default=no]]), [kde_use_profiling=$enableval], [kde_use_profiling="no"] ) dnl this prevents stupid AC_PROG_CC to add "-g" to the default CFLAGS CFLAGS=" $CFLAGS" AC_PROG_CC AC_PROG_CPP if test "$GCC" = "yes"; then if test "$kde_use_debug_code" != "no"; then if test $kde_use_debug_code = "full"; then CFLAGS="-g3 -fno-inline $CFLAGS" else CFLAGS="-g -O2 $CFLAGS" fi else CFLAGS="-O2 $CFLAGS" fi fi if test "$kde_use_debug_define" = "yes"; then CFLAGS="-DNDEBUG $CFLAGS" fi case "$host" in *-*-sysv4.2uw*) CFLAGS="-D_UNIXWARE $CFLAGS";; *-*-sysv5uw7*) CFLAGS="-D_UNIXWARE7 $CFLAGS";; esac if test -z "$LDFLAGS" && test "$kde_use_debug_code" = "no" && test "$GCC" = "yes"; then LDFLAGS="" fi CXXFLAGS=" $CXXFLAGS" AC_PROG_CXX if test "$GXX" = "yes" || test "$CXX" = "KCC"; then if test "$kde_use_debug_code" != "no"; then if test "$CXX" = "KCC"; then CXXFLAGS="+K0 -Wall -pedantic -W -Wpointer-arith -Wwrite-strings $CXXFLAGS" else if test "$kde_use_debug_code" = "full"; then CXXFLAGS="-g3 -fno-inline $CXXFLAGS" else CXXFLAGS="-g -O2 $CXXFLAGS" fi fi KDE_CHECK_COMPILER_FLAG(fno-builtin,[CXXFLAGS="-fno-builtin $CXXFLAGS"]) dnl convenience compiler flags KDE_CHECK_COMPILER_FLAG(Woverloaded-virtual, [WOVERLOADED_VIRTUAL="-Woverloaded-virtual"], [WOVERLOADED_VRITUAL=""]) AC_SUBST(WOVERLOADED_VIRTUAL) else if test "$CXX" = "KCC"; then CXXFLAGS="+K3 $CXXFLAGS" else CXXFLAGS="-O2 $CXXFLAGS" fi fi fi if test "$kde_use_debug_define" = "yes"; then CXXFLAGS="-DNDEBUG -DNO_DEBUG $CXXFLAGS" fi if test "$kde_use_profiling" = "yes"; then KDE_CHECK_COMPILER_FLAG(pg, [ CFLAGS="-pg $CFLAGS" CXXFLAGS="-pg $CXXFLAGS" ]) fi if test "$kde_use_warnings" = "yes"; then if test "$GCC" = "yes"; then CXXFLAGS="-Wall -W -Wpointer-arith -Wwrite-strings $CXXFLAGS" case $host in *-*-linux-gnu) CFLAGS="-ansi -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE $CFLAGS" CXXFLAGS="-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts $CXXFLAGS" KDE_CHECK_COMPILER_FLAG(Wmissing-format-attribute, [CXXFLAGS="$CXXFLAGS -Wformat-security -Wmissing-format-attribute"]) KDE_CHECK_C_COMPILER_FLAG(Wmissing-format-attribute, [CFLAGS="$CFLAGS -Wformat-security -Wmissing-format-attribute"]) ;; esac KDE_CHECK_COMPILER_FLAG(Wundef,[CXXFLAGS="-Wundef $CXXFLAGS"]) KDE_CHECK_COMPILER_FLAG(Wno-long-long,[CXXFLAGS="-Wno-long-long $CXXFLAGS"]) KDE_CHECK_COMPILER_FLAG(Wnon-virtual-dtor,[CXXFLAGS="-Wnon-virtual-dtor $CXXFLAGS"]) fi fi if test "$GXX" = "yes" && test "$kde_use_strict_options" = "yes"; then CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS" fi AC_ARG_ENABLE(pch, AC_HELP_STRING([--enable-pch], [enables precompiled header support (currently only KCC or gcc >=3.4+unsermake) [default=no]]), [ kde_use_pch=$enableval ],[ kde_use_pch=no ]) HAVE_GCC_VISIBILITY=0 AC_SUBST([HAVE_GCC_VISIBILITY]) if test "$GXX" = "yes"; then KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"]) KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"]) KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"]) KDE_CHECK_COMPILER_FLAG(fexceptions, [USE_EXCEPTIONS="-fexceptions"], USE_EXCEPTIONS= ) ENABLE_PERMISSIVE_FLAG="-fpermissive" if test "$kde_use_pch" = "yes"; then AC_MSG_CHECKING(whether gcc supports precompiling c header files) echo >conftest.h if $CC -x c-header conftest.h >/dev/null 2>/dev/null; then kde_gcc_supports_pch=yes AC_MSG_RESULT(yes) else kde_gcc_supports_pch=no AC_MSG_RESULT(no) fi if test "$kde_gcc_supports_pch" = "yes"; then AC_MSG_CHECKING(whether gcc supports precompiling c++ header files) if $CXX -x c++-header conftest.h >/dev/null 2>/dev/null; then kde_gcc_supports_pch=yes AC_MSG_RESULT(yes) else kde_gcc_supports_pch=no AC_MSG_RESULT(no) fi fi rm -f conftest.h conftest.h.gch fi AM_CONDITIONAL(unsermake_enable_pch, test "$kde_use_pch" = "yes" && test "$kde_gcc_supports_pch" = "yes") fi if test "$CXX" = "KCC"; then dnl unfortunately we currently cannot disable exception support in KCC dnl because doing so is binary incompatible and Qt by default links with exceptions :-( dnl KDE_CHECK_COMPILER_FLAG(-no_exceptions,[CXXFLAGS="$CXXFLAGS --no_exceptions"]) dnl KDE_CHECK_COMPILER_FLAG(-exceptions, [USE_EXCEPTIONS="--exceptions"], USE_EXCEPTIONS= ) if test "$kde_use_pch" = "yes"; then dnl TODO: support --pch-dir! KDE_CHECK_COMPILER_FLAG(-pch,[CXXFLAGS="$CXXFLAGS --pch"]) dnl the below works (but the dir must exist), but it's dnl useless for a whole package. dnl The are precompiled headers for each source file, so when compiling dnl from scratch, it doesn't make a difference, and they take up dnl around ~5Mb _per_ sourcefile. dnl KDE_CHECK_COMPILER_FLAG(-pch_dir /tmp, dnl [CXXFLAGS="$CXXFLAGS --pch_dir `pwd`/pcheaders"]) fi dnl this flag controls inlining. by default KCC inlines in optimisation mode dnl all implementations that are defined inside the class {} declaration. dnl because of templates-compatibility with broken gcc compilers, this dnl can cause excessive inlining. This flag limits it to a sane level KDE_CHECK_COMPILER_FLAG(-inline_keyword_space_time=6,[CXXFLAGS="$CXXFLAGS --inline_keyword_space_time=6"]) KDE_CHECK_COMPILER_FLAG(-inline_auto_space_time=2,[CXXFLAGS="$CXXFLAGS --inline_auto_space_time=2"]) KDE_CHECK_COMPILER_FLAG(-inline_implicit_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_implicit_space_time=2.0"]) KDE_CHECK_COMPILER_FLAG(-inline_generated_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_generated_space_time=2.0"]) dnl Some source files are shared between multiple executables dnl (or libraries) and some of those need template instantiations. dnl In that case KCC needs to compile those sources with dnl --one_instantiation_per_object. To make it easy for us we compile dnl _all_ objects with that flag (--one_per is a shorthand). KDE_CHECK_COMPILER_FLAG(-one_per, [CXXFLAGS="$CXXFLAGS --one_per"]) fi AC_SUBST(USE_EXCEPTIONS) dnl obsolete macro - provided to keep things going USE_RTTI= AC_SUBST(USE_RTTI) case "$host" in *-*-irix*) test "$GXX" = yes && CXXFLAGS="-D_LANGUAGE_C_PLUS_PLUS -D__LANGUAGE_C_PLUS_PLUS $CXXFLAGS" ;; *-*-sysv4.2uw*) CXXFLAGS="-D_UNIXWARE $CXXFLAGS";; *-*-sysv5uw7*) CXXFLAGS="-D_UNIXWARE7 $CXXFLAGS";; *-*-solaris*) if test "$GXX" = yes; then libstdcpp=`$CXX -print-file-name=libstdc++.so` if test ! -f $libstdcpp; then AC_MSG_ERROR([You've compiled gcc without --enable-shared. This doesn't work with KDE. Please recompile gcc with --enable-shared to receive a libstdc++.so]) fi fi ;; esac AC_VALIDIFY_CXXFLAGS AC_PROG_CXXCPP if test "$GCC" = yes; then NOOPT_CFLAGS=-O0 fi KDE_CHECK_COMPILER_FLAG(O0,[NOOPT_CXXFLAGS=-O0]) AC_ARG_ENABLE(coverage, AC_HELP_STRING([--enable-coverage],[use gcc coverage testing]), [ if test "$am_cv_CC_dependencies_compiler_type" = "gcc3"; then ac_coverage_compiler="-fprofile-arcs -ftest-coverage" ac_coverage_linker="-lgcc" elif test "$am_cv_CC_dependencies_compiler_type" = "gcc"; then ac_coverage_compiler="-fprofile-arcs -ftest-coverage" ac_coverage_linker="" else AC_MSG_ERROR([coverage with your compiler is not supported]) fi CFLAGS="$CFLAGS $ac_coverage_compiler" CXXFLAGS="$CXXFLAGS $ac_coverage_compiler" LDFLAGS="$LDFLAGS $ac_coverage_linker" ]) AC_SUBST(NOOPT_CXXFLAGS) AC_SUBST(NOOPT_CFLAGS) AC_SUBST(ENABLE_PERMISSIVE_FLAG) KDE_CHECK_NEW_LDFLAGS KDE_CHECK_FINAL KDE_CHECK_CLOSURE KDE_CHECK_NMCHECK ifdef([AM_DEPENDENCIES], AC_REQUIRE([KDE_ADD_DEPENDENCIES]), []) ]) AC_DEFUN([KDE_CHECK_AND_ADD_HIDDEN_VISIBILITY], [ if test "$GXX" = "yes"; then KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"]) KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"]) KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"]) KDE_CHECK_COMPILER_FLAG(fvisibility=hidden, [ CXXFLAGS="$CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden" HAVE_GCC_VISIBILITY=1 AC_DEFINE_UNQUOTED(__KDE_HAVE_GCC_VISIBILITY, "$HAVE_GCC_VISIBILITY", [define to 1 if -fvisibility is supported]) ]) fi ]) AC_DEFUN([KDE_ENABLE_HIDDEN_VISIBILITY], [ AC_REQUIRE([KDE_CHECK_AND_ADD_HIDDEN_VISIBILITY]) ]) AC_DEFUN([KDE_ADD_DEPENDENCIES], [ [A]M_DEPENDENCIES(CC) [A]M_DEPENDENCIES(CXX) ]) dnl just a wrapper to clean up configure.in AC_DEFUN([KDE_PROG_LIBTOOL], [ AC_REQUIRE([AC_CHECK_COMPILERS]) AC_REQUIRE([AC_ENABLE_SHARED]) AC_REQUIRE([AC_ENABLE_STATIC]) AC_REQUIRE([AC_LIBTOOL_DLOPEN]) AC_REQUIRE([KDE_CHECK_LIB64]) AC_OBJEXT AC_EXEEXT AM_PROG_LIBTOOL AC_LIBTOOL_CXX LIBTOOL_SHELL="/bin/sh ./libtool" # LIBTOOL="$LIBTOOL --silent" KDE_PLUGIN="-avoid-version -module -no-undefined \$(KDE_NO_UNDEFINED) \$(KDE_RPATH) \$(KDE_MT_LDFLAGS)" AC_SUBST(KDE_PLUGIN) # we patch configure quite some so we better keep that consistent for incremental runs AC_SUBST(AUTOCONF,'$(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure') ]) AC_DEFUN([KDE_CHECK_LIB64], [ kdelibsuff="$kde_libs_suffix" if test -z "$kdelibsuff"; then kdelibsuff=no fi AC_ARG_ENABLE(libsuffix, AC_HELP_STRING([--enable-libsuffix], [/lib directory suffix (64,32,none[=default])]), kdelibsuff=$enableval) # TODO: add an auto case that compiles a little C app to check # where the glibc is if test "$kdelibsuff" = "no"; then kdelibsuff= fi if test -z "$kdelibsuff"; then AC_MSG_RESULT([not using lib directory suffix]) AC_DEFINE(KDELIBSUFF, [""], Suffix for lib directories) else if test "$libdir" = '${exec_prefix}/lib'; then libdir="$libdir${kdelibsuff}" AC_SUBST([libdir], ["$libdir"]) dnl ugly hack for lib64 platforms fi AC_DEFINE_UNQUOTED(KDELIBSUFF, ["${kdelibsuff}"], Suffix for lib directories) AC_MSG_RESULT([using lib directory suffix $kdelibsuff]) fi ]) AC_DEFUN([KDE_CHECK_TYPES], [ AC_CHECK_SIZEOF(int, 4)dnl AC_CHECK_SIZEOF(short)dnl AC_CHECK_SIZEOF(long, 4)dnl AC_CHECK_SIZEOF(char *, 4)dnl ])dnl dnl Not used - kept for compat only? AC_DEFUN([KDE_DO_IT_ALL], [ AC_CANONICAL_SYSTEM AC_ARG_PROGRAM AM_INIT_AUTOMAKE($1, $2) AM_DISABLE_LIBRARIES AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde}) AC_CHECK_COMPILERS KDE_PROG_LIBTOOL AM_KDE_WITH_NLS AC_PATH_KDE ]) AC_DEFUN([AC_CHECK_RPATH], [ AC_MSG_CHECKING(for rpath) AC_ARG_ENABLE(rpath, AC_HELP_STRING([--disable-rpath],[do not use the rpath feature of ld]), USE_RPATH=$enableval, USE_RPATH=yes) if test -z "$KDE_RPATH" && test "$USE_RPATH" = "yes"; then KDE_RPATH="-R \$(libdir)" if test "$kde_libraries" != "$libdir"; then KDE_RPATH="$KDE_RPATH -R \$(kde_libraries)" fi if test -n "$qt_libraries"; then KDE_RPATH="$KDE_RPATH -R \$(qt_libraries)" fi dnl $x_libraries is set to /usr/lib in case if test -n "$X_LDFLAGS"; then X_RPATH="-R \$(x_libraries)" KDE_RPATH="$KDE_RPATH $X_RPATH" fi if test -n "$KDE_EXTRA_RPATH"; then KDE_RPATH="$KDE_RPATH \$(KDE_EXTRA_RPATH)" fi fi AC_SUBST(KDE_EXTRA_RPATH) AC_SUBST(KDE_RPATH) AC_SUBST(X_RPATH) AC_MSG_RESULT($USE_RPATH) ]) dnl Check for the type of the third argument of getsockname AC_DEFUN([AC_CHECK_SOCKLEN_T], [ AC_MSG_CHECKING(for socklen_t) AC_CACHE_VAL(kde_cv_socklen_t, [ AC_LANG_PUSH(C++) kde_cv_socklen_t=no AC_TRY_COMPILE([ #include #include ], [ socklen_t len; getpeername(0,0,&len); ], [ kde_cv_socklen_t=yes kde_cv_socklen_t_equiv=socklen_t ]) AC_LANG_POP(C++) ]) AC_MSG_RESULT($kde_cv_socklen_t) if test $kde_cv_socklen_t = no; then AC_MSG_CHECKING([for socklen_t equivalent for socket functions]) AC_CACHE_VAL(kde_cv_socklen_t_equiv, [ kde_cv_socklen_t_equiv=int AC_LANG_PUSH(C++) for t in int size_t unsigned long "unsigned long"; do AC_TRY_COMPILE([ #include #include ], [ $t len; getpeername(0,0,&len); ], [ kde_cv_socklen_t_equiv="$t" break ]) done AC_LANG_POP(C++) ]) AC_MSG_RESULT($kde_cv_socklen_t_equiv) fi AC_DEFINE_UNQUOTED(kde_socklen_t, $kde_cv_socklen_t_equiv, [type to use in place of socklen_t if not defined]) AC_DEFINE_UNQUOTED(ksize_t, $kde_cv_socklen_t_equiv, [type to use in place of socklen_t if not defined (deprecated, use kde_socklen_t)]) ]) dnl This is a merge of some macros out of the gettext aclocal.m4 dnl since we don't need anything, I took the things we need dnl the copyright for them is: dnl > dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. dnl This Makefile.in is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. dnl > dnl for this file it is relicensed under LGPL AC_DEFUN([AM_KDE_WITH_NLS], [ dnl If we use NLS figure out what method AM_PATH_PROG_WITH_TEST_KDE(MSGFMT, msgfmt, [test -n "`$ac_dir/$ac_word --version 2>&1 | grep 'GNU gettext'`"], msgfmt) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) if test -z "`$GMSGFMT --version 2>&1 | grep 'GNU gettext'`"; then AC_MSG_RESULT([found msgfmt program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi MSGFMT=$GMSGFMT AC_SUBST(GMSGFMT) AC_SUBST(MSGFMT) AM_PATH_PROG_WITH_TEST_KDE(XGETTEXT, xgettext, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header /dev/null 2> /dev/null; then : ; else AC_MSG_RESULT( [found xgettext programs is not GNU xgettext; ignore it]) XGETTEXT=":" fi fi AC_SUBST(XGETTEXT) ]) # Search path for a program which passes the given test. # Ulrich Drepper , 1996. # serial 1 # Stephan Kulow: I appended a _KDE against name conflicts dnl AM_PATH_PROG_WITH_TEST_KDE(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST_KDE], [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in ifelse([$5], , $PATH, [$5]); do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test -n "[$]$1"; then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) # Check whether LC_MESSAGES is available in . # Ulrich Drepper , 1995. # serial 1 AC_DEFUN([AM_LC_MESSAGES], [if test $ac_cv_header_locale_h = yes; then AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) if test $am_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your locale.h file contains LC_MESSAGES]) fi fi]) dnl From Jim Meyering. dnl FIXME: migrate into libit. AC_DEFUN([AM_FUNC_OBSTACK], [AC_CACHE_CHECK([for obstacks], am_cv_func_obstack, [AC_TRY_LINK([#include "obstack.h"], [struct obstack *mem;obstack_free(mem,(char *) 0)], am_cv_func_obstack=yes, am_cv_func_obstack=no)]) if test $am_cv_func_obstack = yes; then AC_DEFINE(HAVE_OBSTACK) else LIBOBJS="$LIBOBJS obstack.o" fi ]) dnl From Jim Meyering. Use this if you use the GNU error.[ch]. dnl FIXME: Migrate into libit AC_DEFUN([AM_FUNC_ERROR_AT_LINE], [AC_CACHE_CHECK([for error_at_line], am_cv_lib_error_at_line, [AC_TRY_LINK([],[error_at_line(0, 0, "", 0, "");], am_cv_lib_error_at_line=yes, am_cv_lib_error_at_line=no)]) if test $am_cv_lib_error_at_line = no; then LIBOBJS="$LIBOBJS error.o" fi AC_SUBST(LIBOBJS)dnl ]) # Macro to add for using GNU gettext. # Ulrich Drepper , 1995. # serial 1 # Stephan Kulow: I put a KDE in it to avoid name conflicts AC_DEFUN([AM_KDE_GNU_GETTEXT], [AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_TYPE_OFF_T])dnl AC_REQUIRE([AC_TYPE_SIZE_T])dnl AC_REQUIRE([AC_FUNC_ALLOCA])dnl AC_REQUIRE([AC_FUNC_MMAP])dnl AC_REQUIRE([AM_KDE_WITH_NLS])dnl AC_CHECK_HEADERS([limits.h locale.h nl_types.h string.h values.h alloca.h]) AC_CHECK_FUNCS([getcwd munmap putenv setlocale strchr strcasecmp \ __argz_count __argz_stringify __argz_next]) AC_MSG_CHECKING(for stpcpy) AC_CACHE_VAL(kde_cv_func_stpcpy, [ kde_safe_cxxflags=$CXXFLAGS CXXFLAGS="-Werror" AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([ #include ], [ char buffer[200]; stpcpy(buffer, buffer); ], kde_cv_func_stpcpy=yes, kde_cv_func_stpcpy=no) AC_LANG_RESTORE CXXFLAGS=$kde_safe_cxxflags ]) AC_MSG_RESULT($kde_cv_func_stpcpy) if eval "test \"`echo $kde_cv_func_stpcpy`\" = yes"; then AC_DEFINE(HAVE_STPCPY, 1, [Define if you have stpcpy]) fi AM_LC_MESSAGES if test "x$CATOBJEXT" != "x"; then if test "x$ALL_LINGUAS" = "x"; then LINGUAS= else AC_MSG_CHECKING(for catalogs to be installed) NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; esac done LINGUAS=$NEW_LINGUAS AC_MSG_RESULT($LINGUAS) fi dnl Construct list of names of catalog files to be constructed. if test -n "$LINGUAS"; then for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done fi fi ]) AC_DEFUN([AC_HAVE_XPM], [AC_REQUIRE_CPP()dnl AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) test -z "$XPM_LDFLAGS" && XPM_LDFLAGS= test -z "$XPM_INCLUDE" && XPM_INCLUDE= AC_ARG_WITH(xpm,AC_HELP_STRING([--without-xpm],[disable color pixmap XPM tests]), xpm_test=$withval, xpm_test="yes") if test "x$xpm_test" = xno; then ac_cv_have_xpm=no else AC_MSG_CHECKING(for XPM) AC_CACHE_VAL(ac_cv_have_xpm, [ ac_save_ldflags="$LDFLAGS" ac_save_cflags="$CFLAGS" if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm -lX11 -lXext $LIBZ $LIBSOCKET" else LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm $LIBZ $LIBSOCKET" fi CFLAGS="$CFLAGS $X_INCLUDES $USER_INCLUDES" test -n "$XPM_INCLUDE" && CFLAGS="-I$XPM_INCLUDE $CFLAGS" AC_TRY_LINK([#include ],[], ac_cv_have_xpm="yes",ac_cv_have_xpm="no") LDFLAGS="$ac_save_ldflags" CFLAGS="$ac_save_cflags" ])dnl if test "$ac_cv_have_xpm" = no; then AC_MSG_RESULT(no) XPM_LDFLAGS="" XPMINC="" $2 else AC_DEFINE(HAVE_XPM, 1, [Define if you have XPM support]) if test "$XPM_LDFLAGS" = ""; then XPMLIB='-lXpm $(LIB_X11)' else XPMLIB="-L$XPM_LDFLAGS -lXpm "'$(LIB_X11)' fi if test "$XPM_INCLUDE" = ""; then XPMINC="" else XPMINC="-I$XPM_INCLUDE" fi AC_MSG_RESULT(yes) $1 fi fi AC_SUBST(XPMINC) AC_SUBST(XPMLIB) ]) AC_DEFUN([AC_HAVE_DPMS], [AC_REQUIRE_CPP()dnl AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) test -z "$DPMS_LDFLAGS" && DPMS_LDFLAGS= test -z "$DPMS_INCLUDE" && DPMS_INCLUDE= DPMS_LIB= AC_ARG_WITH(dpms,AC_HELP_STRING([--without-dpms],[disable DPMS power saving]), dpms_test=$withval, dpms_test="yes") if test "x$dpms_test" = xno; then ac_cv_have_dpms=no else AC_MSG_CHECKING(for DPMS) dnl Note: ac_cv_have_dpms can be no, yes, or -lXdpms. dnl 'yes' means DPMS_LIB="", '-lXdpms' means DPMS_LIB="-lXdpms". AC_CACHE_VAL(ac_cv_have_dpms, [ if test "x$kde_use_qt_emb" = "xyes" || test "x$kde_use_qt_mac" = "xyes"; then AC_MSG_RESULT(no) ac_cv_have_dpms="no" else ac_save_ldflags="$LDFLAGS" ac_save_cflags="$CFLAGS" ac_save_libs="$LIBS" LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries -lX11 -lXext $LIBSOCKET" CFLAGS="$CFLAGS $X_INCLUDES" test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" AC_TRY_LINK([ #include #include #include #include int foo_test_dpms() { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[], ac_cv_have_dpms="yes", [ LDFLAGS="$ac_save_ldflags" CFLAGS="$ac_save_cflags" LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries -lX11 -lXext $LIBSOCKET" LIBS="$LIBS -lXdpms" CFLAGS="$CFLAGS $X_INCLUDES" test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" AC_TRY_LINK([ #include #include #include #include int foo_test_dpms() { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[], [ ac_cv_have_dpms="-lXdpms" ],ac_cv_have_dpms="no") ]) LDFLAGS="$ac_save_ldflags" CFLAGS="$ac_save_cflags" LIBS="$ac_save_libs" fi ])dnl if test "$ac_cv_have_dpms" = no; then AC_MSG_RESULT(no) DPMS_LDFLAGS="" DPMSINC="" $2 else AC_DEFINE(HAVE_DPMS, 1, [Define if you have DPMS support]) if test "$ac_cv_have_dpms" = "-lXdpms"; then DPMS_LIB="-lXdpms" fi if test "$DPMS_LDFLAGS" = ""; then DPMSLIB="$DPMS_LIB "'$(LIB_X11)' else DPMSLIB="$DPMS_LDFLAGS $DPMS_LIB "'$(LIB_X11)' fi if test "$DPMS_INCLUDE" = ""; then DPMSINC="" else DPMSINC="-I$DPMS_INCLUDE" fi AC_MSG_RESULT(yes) $1 fi fi ac_save_cflags="$CFLAGS" CFLAGS="$CFLAGS $X_INCLUDES" test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" AH_TEMPLATE(HAVE_DPMSCAPABLE_PROTO, [Define if you have the DPMSCapable prototype in ]) AC_CHECK_DECL(DPMSCapable, AC_DEFINE(HAVE_DPMSCAPABLE_PROTO),, [#include ]) AH_TEMPLATE(HAVE_DPMSINFO_PROTO, [Define if you have the DPMSInfo prototype in ]) AC_CHECK_DECL(DPMSInfo, AC_DEFINE(HAVE_DPMSINFO_PROTO),, [#include ]) CFLAGS="$ac_save_cflags" AC_SUBST(DPMSINC) AC_SUBST(DPMSLIB) ]) AC_DEFUN([AC_HAVE_GL], [AC_REQUIRE_CPP()dnl AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) test -z "$GL_LDFLAGS" && GL_LDFLAGS= test -z "$GL_INCLUDE" && GL_INCLUDE= AC_ARG_WITH(gl,AC_HELP_STRING([--without-gl],[disable 3D GL modes]), gl_test=$withval, gl_test="yes") if test "x$kde_use_qt_emb" = "xyes"; then # GL and Qt Embedded is a no-go for now. ac_cv_have_gl=no elif test "x$gl_test" = xno; then ac_cv_have_gl=no else AC_MSG_CHECKING(for GL) AC_CACHE_VAL(ac_cv_have_gl, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_save_ldflags="$LDFLAGS" ac_save_cxxflags="$CXXFLAGS" LDFLAGS="$LDFLAGS $GL_LDFLAGS $X_LDFLAGS $all_libraries -lGL -lGLU" test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LDFLAGS="$LDFLAGS -lX11" LDFLAGS="$LDFLAGS $LIB_XEXT -lm $LIBSOCKET" CXXFLAGS="$CFLAGS $X_INCLUDES" test -n "$GL_INCLUDE" && CFLAGS="-I$GL_INCLUDE $CFLAGS" AC_TRY_LINK([#include #include ], [], ac_cv_have_gl="yes", ac_cv_have_gl="no") AC_LANG_RESTORE LDFLAGS="$ac_save_ldflags" CXXFLAGS="$ac_save_cxxflags" ])dnl if test "$ac_cv_have_gl" = "no"; then AC_MSG_RESULT(no) GL_LDFLAGS="" GLINC="" $2 else AC_DEFINE(HAVE_GL, 1, [Defines if you have GL (Mesa, OpenGL, ...)]) if test "$GL_LDFLAGS" = ""; then GLLIB='-lGLU -lGL $(LIB_X11)' else GLLIB="$GL_LDFLAGS -lGLU -lGL "'$(LIB_X11)' fi if test "$GL_INCLUDE" = ""; then GLINC="" else GLINC="-I$GL_INCLUDE" fi AC_MSG_RESULT($ac_cv_have_gl) $1 fi fi AC_SUBST(GLINC) AC_SUBST(GLLIB) ]) dnl shadow password and PAM magic - maintained by ossi@kde.org AC_DEFUN([KDE_PAM], [ AC_REQUIRE([KDE_CHECK_LIBDL]) want_pam= AC_ARG_WITH(pam, AC_HELP_STRING([--with-pam[=ARG]],[enable support for PAM: ARG=[yes|no|service name]]), [ if test "x$withval" = "xyes"; then want_pam=yes pam_service=kde elif test "x$withval" = "xno"; then want_pam=no else want_pam=yes pam_service=$withval fi ], [ pam_service=kde ]) use_pam= PAMLIBS= if test "x$want_pam" != xno; then AC_CHECK_LIB(pam, pam_start, [ AC_CHECK_HEADER(security/pam_appl.h, [ pam_header=security/pam_appl.h ], [ AC_CHECK_HEADER(pam/pam_appl.h, [ pam_header=pam/pam_appl.h ], [ AC_MSG_WARN([PAM detected, but no headers found! Make sure you have the necessary development packages installed.]) ] ) ] ) ], , $LIBDL) if test -z "$pam_header"; then if test "x$want_pam" = xyes; then AC_MSG_ERROR([--with-pam was specified, but cannot compile with PAM!]) fi else AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM (Pluggable Authentication Modules)]) PAMLIBS="$PAM_MISC_LIB -lpam $LIBDL" use_pam=yes dnl darwin claims to be something special if test "$pam_header" = "pam/pam_appl.h"; then AC_DEFINE(HAVE_PAM_PAM_APPL_H, 1, [Define if your PAM headers are in pam/ instead of security/]) fi dnl test whether struct pam_message is const (Linux) or not (Sun) AC_MSG_CHECKING(for const pam_message) AC_EGREP_HEADER([struct pam_message], $pam_header, [ AC_EGREP_HEADER([const struct pam_message], $pam_header, [AC_MSG_RESULT([const: Linux-type PAM])], [AC_MSG_RESULT([nonconst: Sun-type PAM]) AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM support takes non-const arguments (Solaris)])] )], [AC_MSG_RESULT([not found - assume const, Linux-type PAM])]) fi fi AC_SUBST(PAMLIBS) ]) dnl DEF_PAM_SERVICE(arg name, full name, define name) AC_DEFUN([DEF_PAM_SERVICE], [ AC_ARG_WITH($1-pam, AC_HELP_STRING([--with-$1-pam=[val]],[override PAM service from --with-pam for $2]), [ if test "x$use_pam" = xyes; then $3_PAM_SERVICE=$withval else AC_MSG_ERROR([Cannot use use --with-$1-pam, as no PAM was detected. You may want to enforce it by using --with-pam.]) fi ], [ if test "x$use_pam" = xyes; then $3_PAM_SERVICE="$pam_service" fi ]) if test -n "$$3_PAM_SERVICE"; then AC_MSG_RESULT([The PAM service used by $2 will be $$3_PAM_SERVICE]) AC_DEFINE_UNQUOTED($3_PAM_SERVICE, "$$3_PAM_SERVICE", [The PAM service to be used by $2]) fi AC_SUBST($3_PAM_SERVICE) ]) AC_DEFUN([KDE_SHADOWPASSWD], [ AC_REQUIRE([KDE_PAM]) AC_CHECK_LIB(shadow, getspent, [ LIBSHADOW="-lshadow" ac_use_shadow=yes ], [ dnl for UnixWare AC_CHECK_LIB(gen, getspent, [ LIBGEN="-lgen" ac_use_shadow=yes ], [ AC_CHECK_FUNC(getspent, [ ac_use_shadow=yes ], [ ac_use_shadow=no ]) ]) ]) AC_SUBST(LIBSHADOW) AC_SUBST(LIBGEN) AC_MSG_CHECKING([for shadow passwords]) AC_ARG_WITH(shadow, AC_HELP_STRING([--with-shadow],[If you want shadow password support]), [ if test "x$withval" != "xno"; then use_shadow=yes else use_shadow=no fi ], [ use_shadow="$ac_use_shadow" ]) if test "x$use_shadow" = xyes; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SHADOW, 1, [Define if you use shadow passwords]) else AC_MSG_RESULT(no) LIBSHADOW= LIBGEN= fi dnl finally make the relevant binaries setuid root, if we have shadow passwds. dnl this still applies, if we could use it indirectly through pam. if test "x$use_shadow" = xyes || ( test "x$use_pam" = xyes && test "x$ac_use_shadow" = xyes ); then case $host in *-*-freebsd* | *-*-netbsd* | *-*-openbsd*) SETUIDFLAGS="-m 4755 -o root";; *) SETUIDFLAGS="-m 4755";; esac fi AC_SUBST(SETUIDFLAGS) ]) AC_DEFUN([KDE_PASSWDLIBS], [ AC_REQUIRE([KDE_MISC_TESTS]) dnl for LIBCRYPT AC_REQUIRE([KDE_PAM]) AC_REQUIRE([KDE_SHADOWPASSWD]) if test "x$use_pam" = "xyes"; then PASSWDLIBS="$PAMLIBS" else PASSWDLIBS="$LIBCRYPT $LIBSHADOW $LIBGEN" fi dnl FreeBSD uses a shadow-like setup, where /etc/passwd holds the users, but dnl /etc/master.passwd holds the actual passwords. /etc/master.passwd requires dnl root to read, so kcheckpass needs to be root (even when using pam, since pam dnl may need to read /etc/master.passwd). case $host in *-*-freebsd*) SETUIDFLAGS="-m 4755 -o root" ;; *) ;; esac AC_SUBST(PASSWDLIBS) ]) AC_DEFUN([KDE_CHECK_LIBDL], [ AC_CHECK_LIB(dl, dlopen, [ LIBDL="-ldl" ac_cv_have_dlfcn=yes ]) AC_CHECK_LIB(dld, shl_unload, [ LIBDL="-ldld" ac_cv_have_shload=yes ]) AC_SUBST(LIBDL) ]) AC_DEFUN([KDE_CHECK_DLOPEN], [ KDE_CHECK_LIBDL AC_CHECK_HEADERS(dlfcn.h dl.h) if test "$ac_cv_header_dlfcn_h" = "no"; then ac_cv_have_dlfcn=no fi if test "$ac_cv_header_dl_h" = "no"; then ac_cv_have_shload=no fi dnl XXX why change enable_dlopen? its already set by autoconf's AC_ARG_ENABLE dnl (MM) AC_ARG_ENABLE(dlopen, AC_HELP_STRING([--disable-dlopen],[link statically [default=no]]), enable_dlopen=$enableval, enable_dlopen=yes) # override the user's opinion, if we know it better ;) if test "$ac_cv_have_dlfcn" = "no" && test "$ac_cv_have_shload" = "no"; then enable_dlopen=no fi if test "$ac_cv_have_dlfcn" = "yes"; then AC_DEFINE_UNQUOTED(HAVE_DLFCN, 1, [Define if you have dlfcn]) fi if test "$ac_cv_have_shload" = "yes"; then AC_DEFINE_UNQUOTED(HAVE_SHLOAD, 1, [Define if you have shload]) fi if test "$enable_dlopen" = no ; then test -n "$1" && eval $1 else test -n "$2" && eval $2 fi ]) AC_DEFUN([KDE_CHECK_DYNAMIC_LOADING], [ KDE_CHECK_DLOPEN(libtool_enable_shared=yes, libtool_enable_static=no) KDE_PROG_LIBTOOL AC_MSG_CHECKING([dynamic loading]) eval "`egrep '^build_libtool_libs=' libtool`" if test "$build_libtool_libs" = "yes" && test "$enable_dlopen" = "yes"; then dynamic_loading=yes AC_DEFINE_UNQUOTED(HAVE_DYNAMIC_LOADING) else dynamic_loading=no fi AC_MSG_RESULT($dynamic_loading) if test "$dynamic_loading" = "yes"; then $1 else $2 fi ]) AC_DEFUN([KDE_ADD_INCLUDES], [ if test -z "$1"; then test_include="Pix.h" else test_include="$1" fi AC_MSG_CHECKING([for libg++ ($test_include)]) AC_CACHE_VAL(kde_cv_libgpp_includes, [ kde_cv_libgpp_includes=no for ac_dir in \ \ /usr/include/g++ \ /usr/include \ /usr/unsupported/include \ /opt/include \ $extra_include \ ; \ do if test -r "$ac_dir/$test_include"; then kde_cv_libgpp_includes=$ac_dir break fi done ]) AC_MSG_RESULT($kde_cv_libgpp_includes) if test "$kde_cv_libgpp_includes" != "no"; then all_includes="-I$kde_cv_libgpp_includes $all_includes $USER_INCLUDES" fi ]) ]) AC_DEFUN([KDE_CHECK_LIBPTHREAD], [ dnl This code is here specifically to handle the dnl various flavors of threading library on FreeBSD dnl 4-, 5-, and 6-, and the (weird) rules around it. dnl There may be an environment PTHREAD_LIBS that dnl specifies what to use; otherwise, search for it. dnl -pthread is special cased and unsets LIBPTHREAD dnl below if found. LIBPTHREAD="" if test -n "$PTHREAD_LIBS"; then if test "x$PTHREAD_LIBS" = "x-pthread" ; then LIBPTHREAD="PTHREAD" else PTHREAD_LIBS_save="$PTHREAD_LIBS" PTHREAD_LIBS=`echo "$PTHREAD_LIBS_save" | sed -e 's,^-l,,g'` AC_MSG_CHECKING([for pthread_create in $PTHREAD_LIBS]) KDE_CHECK_LIB($PTHREAD_LIBS, pthread_create, [ LIBPTHREAD="$PTHREAD_LIBS_save"]) PTHREAD_LIBS="$PTHREAD_LIBS_save" fi fi dnl Is this test really needed, in the face of the Tru64 test below? if test -z "$LIBPTHREAD"; then AC_CHECK_LIB(pthread, pthread_create, [LIBPTHREAD="-lpthread"]) fi dnl This is a special Tru64 check, see BR 76171 issue #18. if test -z "$LIBPTHREAD" ; then AC_MSG_CHECKING([for pthread_create in -lpthread]) kde_safe_libs=$LIBS LIBS="$LIBS -lpthread" AC_TRY_LINK([#include ],[(void)pthread_create(0,0,0,0);],[ AC_MSG_RESULT(yes) LIBPTHREAD="-lpthread"],[ AC_MSG_RESULT(no)]) LIBS=$kde_safe_libs fi dnl Un-special-case for FreeBSD. if test "x$LIBPTHREAD" = "xPTHREAD" ; then LIBPTHREAD="" fi AC_SUBST(LIBPTHREAD) ]) AC_DEFUN([KDE_CHECK_PTHREAD_OPTION], [ USE_THREADS="" if test -z "$LIBPTHREAD"; then KDE_CHECK_COMPILER_FLAG(pthread, [USE_THREADS="-D_THREAD_SAFE -pthread"]) fi AH_VERBATIM(__svr_define, [ #if defined(__SVR4) && !defined(__svr4__) #define __svr4__ 1 #endif ]) case $host_os in solaris*) KDE_CHECK_COMPILER_FLAG(mt, [USE_THREADS="-mt"]) CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4" ;; freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE $PTHREAD_CFLAGS" ;; aix*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" LIBPTHREAD="$LIBPTHREAD -lc_r" ;; linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" if test "$CXX" = "KCC"; then CXXFLAGS="$CXXFLAGS --thread_safe" NOOPT_CXXFLAGS="$NOOPT_CXXFLAGS --thread_safe" fi ;; *) ;; esac AC_SUBST(USE_THREADS) AC_SUBST(LIBPTHREAD) ]) AC_DEFUN([KDE_CHECK_THREADING], [ AC_REQUIRE([KDE_CHECK_LIBPTHREAD]) AC_REQUIRE([KDE_CHECK_PTHREAD_OPTION]) dnl default is yes if libpthread is found and no if no libpthread is available if test -z "$LIBPTHREAD"; then if test -z "$USE_THREADS"; then kde_check_threading_default=no else kde_check_threading_default=yes fi else kde_check_threading_default=yes fi AC_ARG_ENABLE(threading,AC_HELP_STRING([--disable-threading],[disables threading even if libpthread found]), kde_use_threading=$enableval, kde_use_threading=$kde_check_threading_default) if test "x$kde_use_threading" = "xyes"; then AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have a working libpthread (will enable threaded code)]) fi ]) AC_DEFUN([KDE_TRY_LINK_PYTHON], [ if test "$kde_python_link_found" = no; then if test "$1" = normal; then AC_MSG_CHECKING(if a Python application links) else AC_MSG_CHECKING(if Python depends on $2) fi AC_CACHE_VAL(kde_cv_try_link_python_$1, [ kde_save_cflags="$CFLAGS" CFLAGS="$CFLAGS $PYTHONINC" kde_save_libs="$LIBS" LIBS="$LIBS $LIBPYTHON $2 $LIBDL $LIBSOCKET" kde_save_ldflags="$LDFLAGS" LDFLAGS="$LDFLAGS $PYTHONLIB" AC_TRY_LINK( [ #include ],[ PySys_SetArgv(1, 0); ], [kde_cv_try_link_python_$1=yes], [kde_cv_try_link_python_$1=no] ) CFLAGS="$kde_save_cflags" LIBS="$kde_save_libs" LDFLAGS="$kde_save_ldflags" ]) if test "$kde_cv_try_link_python_$1" = "yes"; then AC_MSG_RESULT(yes) kde_python_link_found=yes if test ! "$1" = normal; then LIBPYTHON="$LIBPYTHON $2" fi $3 else AC_MSG_RESULT(no) $4 fi fi ]) AC_DEFUN([KDE_CHECK_PYTHON_DIR], [ AC_MSG_CHECKING([for Python directory]) AC_CACHE_VAL(kde_cv_pythondir, [ if test -z "$PYTHONDIR"; then kde_cv_pythondir=/usr/local else kde_cv_pythondir="$PYTHONDIR" fi ]) AC_ARG_WITH(pythondir, AC_HELP_STRING([--with-pythondir=pythondir],[use python installed in pythondir]), [ ac_python_dir=$withval ], ac_python_dir=$kde_cv_pythondir ) AC_MSG_RESULT($ac_python_dir) ]) AC_DEFUN([KDE_CHECK_PYTHON_INTERN], [ AC_REQUIRE([KDE_CHECK_LIBDL]) AC_REQUIRE([KDE_CHECK_LIBPTHREAD]) AC_REQUIRE([KDE_CHECK_PYTHON_DIR]) if test -z "$1"; then version="1.5" else version="$1" fi AC_MSG_CHECKING([for Python$version]) python_incdirs="$ac_python_dir/include /usr/include /usr/local/include/ $kde_extra_includes" AC_FIND_FILE(Python.h, $python_incdirs, python_incdir) if test ! -r $python_incdir/Python.h; then AC_FIND_FILE(python$version/Python.h, $python_incdirs, python_incdir) python_incdir=$python_incdir/python$version if test ! -r $python_incdir/Python.h; then python_incdir=no fi fi PYTHONINC=-I$python_incdir python_libdirs="$ac_python_dir/lib$kdelibsuff /usr/lib$kdelibsuff /usr/local /usr/lib$kdelibsuff $kde_extra_libs" AC_FIND_FILE(libpython$version.so, $python_libdirs, python_libdir) if test ! -r $python_libdir/libpython$version.so; then AC_FIND_FILE(libpython$version.a, $python_libdirs, python_libdir) if test ! -r $python_libdir/libpython$version.a; then AC_FIND_FILE(python$version/config/libpython$version.a, $python_libdirs, python_libdir) python_libdir=$python_libdir/python$version/config if test ! -r $python_libdir/libpython$version.a; then python_libdir=no fi fi fi PYTHONLIB=-L$python_libdir kde_orig_LIBPYTHON=$LIBPYTHON if test -z "$LIBPYTHON"; then LIBPYTHON=-lpython$version fi AC_FIND_FILE(python$version/copy.py, $python_libdirs, python_moddir) python_moddir=$python_moddir/python$version if test ! -r $python_moddir/copy.py; then python_moddir=no fi PYTHONMODDIR=$python_moddir AC_MSG_RESULT(header $python_incdir library $python_libdir modules $python_moddir) if test x$python_incdir = xno || test x$python_libdir = xno || test x$python_moddir = xno; then LIBPYTHON=$kde_orig_LIBPYTHON test "x$PYTHONLIB" = "x-Lno" && PYTHONLIB="" test "x$PYTHONINC" = "x-Ino" && PYTHONINC="" $2 else dnl Note: this test is very weak kde_python_link_found=no KDE_TRY_LINK_PYTHON(normal) KDE_TRY_LINK_PYTHON(m, -lm) KDE_TRY_LINK_PYTHON(pthread, $LIBPTHREAD) KDE_TRY_LINK_PYTHON(tcl, -ltcl) KDE_TRY_LINK_PYTHON(db2, -ldb2) KDE_TRY_LINK_PYTHON(m_and_thread, [$LIBPTHREAD -lm]) KDE_TRY_LINK_PYTHON(m_and_thread_and_util, [$LIBPTHREAD -lm -lutil]) KDE_TRY_LINK_PYTHON(m_and_thread_and_db3, [$LIBPTHREAD -lm -ldb-3 -lutil]) KDE_TRY_LINK_PYTHON(pthread_and_db3, [$LIBPTHREAD -ldb-3]) KDE_TRY_LINK_PYTHON(m_and_thread_and_db, [$LIBPTHREAD -lm -ldb -ltermcap -lutil]) KDE_TRY_LINK_PYTHON(pthread_and_dl, [$LIBPTHREAD $LIBDL -lutil -lreadline -lncurses -lm]) KDE_TRY_LINK_PYTHON(pthread_and_panel_curses, [$LIBPTHREAD $LIBDL -lm -lpanel -lcurses]) KDE_TRY_LINK_PYTHON(m_and_thread_and_db_special, [$LIBPTHREAD -lm -ldb -lutil], [], [AC_MSG_WARN([it seems, Python depends on another library. Please set LIBPYTHON to '-lpython$version -lotherlib' before calling configure to fix this and contact the authors to let them know about this problem]) ]) LIBPYTHON="$LIBPYTHON $LIBDL $LIBSOCKET" AC_SUBST(PYTHONINC) AC_SUBST(PYTHONLIB) AC_SUBST(LIBPYTHON) AC_SUBST(PYTHONMODDIR) AC_DEFINE(HAVE_PYTHON, 1, [Define if you have the development files for python]) fi ]) AC_DEFUN([KDE_CHECK_PYTHON], [ KDE_CHECK_PYTHON_INTERN("2.4", [KDE_CHECK_PYTHON_INTERN("2.3", [KDE_CHECK_PYTHON_INTERN("2.2", [KDE_CHECK_PYTHON_INTERN("2.1", [KDE_CHECK_PYTHON_INTERN("2.0", [KDE_CHECK_PYTHON_INTERN($1, $2) ]) ]) ]) ]) ]) ]) AC_DEFUN([KDE_CHECK_STL], [ AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="`echo $CXXFLAGS | sed s/-fno-exceptions//`" AC_MSG_CHECKING([if C++ programs can be compiled]) AC_CACHE_VAL(kde_cv_stl_works, [ AC_TRY_COMPILE([ #include using namespace std; ],[ string astring="Hallo Welt."; astring.erase(0, 6); // now astring is "Welt" return 0; ], kde_cv_stl_works=yes, kde_cv_stl_works=no) ]) AC_MSG_RESULT($kde_cv_stl_works) if test "$kde_cv_stl_works" = "yes"; then # back compatible AC_DEFINE_UNQUOTED(HAVE_SGI_STL, 1, [Define if you have a STL implementation by SGI]) else AC_MSG_ERROR([Your Installation isn't able to compile simple C++ programs. Check config.log for details - if you're using a Linux distribution you might miss a package named similar to libstdc++-dev.]) fi CXXFLAGS="$ac_save_CXXFLAGS" AC_LANG_RESTORE ]) AC_DEFUN([AC_FIND_QIMGIO], [AC_REQUIRE([AC_FIND_JPEG]) AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) AC_MSG_CHECKING([for qimgio]) AC_CACHE_VAL(ac_cv_lib_qimgio, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_save_LIBS="$LIBS" ac_save_CXXFLAGS="$CXXFLAGS" LIBS="$all_libraries -lqimgio -lpng -lz $LIBJPEG $LIBQT" CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" AC_TRY_RUN(dnl [ #include #include int main() { QString t = "hallo"; t.fill('t'); qInitImageIO(); } ], ac_cv_lib_qimgio=yes, ac_cv_lib_qimgio=no, ac_cv_lib_qimgio=no) LIBS="$ac_save_LIBS" CXXFLAGS="$ac_save_CXXFLAGS" AC_LANG_RESTORE ])dnl if eval "test \"`echo $ac_cv_lib_qimgio`\" = yes"; then LIBQIMGIO="-lqimgio -lpng -lz $LIBJPEG" AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(HAVE_QIMGIO, 1, [Define if you have the Qt extension qimgio available]) AC_SUBST(LIBQIMGIO) else AC_MSG_RESULT(not found) fi ]) AC_DEFUN([AM_DISABLE_LIBRARIES], [ AC_PROVIDE([AM_ENABLE_STATIC]) AC_PROVIDE([AM_ENABLE_SHARED]) enable_static=no enable_shared=yes ]) AC_DEFUN([AC_CHECK_UTMP_FILE], [ AC_MSG_CHECKING([for utmp file]) AC_CACHE_VAL(kde_cv_utmp_file, [ kde_cv_utmp_file=no for ac_file in \ \ /var/run/utmp \ /var/adm/utmp \ /etc/utmp \ ; \ do if test -r "$ac_file"; then kde_cv_utmp_file=$ac_file break fi done ]) if test "$kde_cv_utmp_file" != "no"; then AC_DEFINE_UNQUOTED(UTMP, "$kde_cv_utmp_file", [Define the file for utmp entries]) $1 AC_MSG_RESULT($kde_cv_utmp_file) else $2 AC_MSG_RESULT([non found]) fi ]) AC_DEFUN([KDE_CREATE_SUBDIRSLIST], [ DO_NOT_COMPILE="$DO_NOT_COMPILE CVS debian bsd-port admin" TOPSUBDIRS="" if test ! -s $srcdir/subdirs; then dnl Note: Makefile.common creates subdirs, so this is just a fallback files=`cd $srcdir && ls -1` dirs=`for i in $files; do if test -d $i; then echo $i; fi; done` for i in $dirs; do echo $i >> $srcdir/subdirs done fi ac_topsubdirs= if test -s $srcdir/inst-apps; then ac_topsubdirs="`cat $srcdir/inst-apps`" elif test -s $srcdir/subdirs; then ac_topsubdirs="`cat $srcdir/subdirs`" fi for i in $ac_topsubdirs; do AC_MSG_CHECKING([if $i should be compiled]) if test -d $srcdir/$i; then install_it="yes" for j in $DO_NOT_COMPILE; do if test $i = $j; then install_it="no" fi done else install_it="no" fi AC_MSG_RESULT($install_it) vari=`echo $i | sed -e 's,[[-+.@]],_,g'` if test $install_it = "yes"; then TOPSUBDIRS="$TOPSUBDIRS $i" eval "$vari""_SUBDIR_included=yes" else eval "$vari""_SUBDIR_included=no" fi done AC_SUBST(TOPSUBDIRS) ]) AC_DEFUN([KDE_CHECK_NAMESPACES], [ AC_MSG_CHECKING(whether C++ compiler supports namespaces) AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([ ], [ namespace Foo { extern int i; namespace Bar { extern int i; } } int Foo::i = 0; int Foo::Bar::i = 1; ],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_NAMESPACES) ], [ AC_MSG_RESULT(no) ]) AC_LANG_RESTORE ]) dnl ------------------------------------------------------------------------ dnl Check for S_ISSOCK macro. Doesn't exist on Unix SCO. faure@kde.org dnl ------------------------------------------------------------------------ dnl AC_DEFUN([AC_CHECK_S_ISSOCK], [ AC_MSG_CHECKING(for S_ISSOCK) AC_CACHE_VAL(ac_cv_have_s_issock, [ AC_TRY_LINK( [ #include ], [ struct stat buff; int b = S_ISSOCK( buff.st_mode ); ], ac_cv_have_s_issock=yes, ac_cv_have_s_issock=no) ]) AC_MSG_RESULT($ac_cv_have_s_issock) if test "$ac_cv_have_s_issock" = "yes"; then AC_DEFINE_UNQUOTED(HAVE_S_ISSOCK, 1, [Define if sys/stat.h declares S_ISSOCK.]) fi AH_VERBATIM(_ISSOCK, [ #ifndef HAVE_S_ISSOCK #define HAVE_S_ISSOCK #define S_ISSOCK(mode) (1==0) #endif ]) ]) dnl ------------------------------------------------------------------------ dnl Check for MAXPATHLEN macro, defines KDEMAXPATHLEN. faure@kde.org dnl ------------------------------------------------------------------------ dnl AC_DEFUN([AC_CHECK_KDEMAXPATHLEN], [ AC_MSG_CHECKING(for MAXPATHLEN) AC_CACHE_VAL(ac_cv_maxpathlen, [ cat > conftest.$ac_ext < #endif #include #include #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif KDE_HELLO MAXPATHLEN EOF ac_try="$ac_cpp conftest.$ac_ext 2>/dev/null | grep '^KDE_HELLO' >conftest.out" if AC_TRY_EVAL(ac_try) && test -s conftest.out; then ac_cv_maxpathlen=`sed 's#KDE_HELLO ##' conftest.out` else ac_cv_maxpathlen=1024 fi rm conftest.* ]) AC_MSG_RESULT($ac_cv_maxpathlen) AC_DEFINE_UNQUOTED(KDEMAXPATHLEN,$ac_cv_maxpathlen, [Define a safe value for MAXPATHLEN] ) ]) AC_DEFUN([KDE_CHECK_HEADER], [ AC_LANG_SAVE kde_safe_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $all_includes" AC_LANG_CPLUSPLUS AC_CHECK_HEADER([$1], [$2], [$3], [$4]) CPPFLAGS=$kde_safe_cppflags AC_LANG_RESTORE ]) AC_DEFUN([KDE_CHECK_HEADERS], [ AH_CHECK_HEADERS([$1]) AC_LANG_SAVE kde_safe_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $all_includes" AC_LANG_CPLUSPLUS AC_CHECK_HEADERS([$1], [$2], [$3], [$4]) CPPFLAGS=$kde_safe_cppflags AC_LANG_RESTORE ]) AC_DEFUN([KDE_FAST_CONFIGURE], [ dnl makes configure fast (needs perl) AC_ARG_ENABLE(fast-perl, AC_HELP_STRING([--disable-fast-perl],[disable fast Makefile generation (needs perl)]), with_fast_perl=$enableval, with_fast_perl=yes) ]) AC_DEFUN([KDE_CONF_FILES], [ val= if test -f $srcdir/configure.files ; then val=`sed -e 's%^%\$(top_srcdir)/%' $srcdir/configure.files` fi CONF_FILES= if test -n "$val" ; then for i in $val ; do CONF_FILES="$CONF_FILES $i" done fi AC_SUBST(CONF_FILES) ])dnl dnl This sets the prefix, for arts and kdelibs dnl Do NOT use in any other module. dnl It only looks at --prefix, KDEDIR and falls back to /usr/local/kde AC_DEFUN([KDE_SET_PREFIX_CORE], [ unset CDPATH dnl make $KDEDIR the default for the installation AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde}) if test "x$prefix" = "xNONE"; then prefix=$ac_default_prefix ac_configure_args="$ac_configure_args --prefix=$prefix" fi # And delete superfluous '/' to make compares easier prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` kde_libs_htmldir=$prefix/share/doc/HTML/ exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` kde_libs_prefix='$(prefix)' kde_libs_htmldir='$(kde_htmldir)' AC_SUBST(kde_libs_prefix) AC_SUBST(kde_libs_htmldir) KDE_FAST_CONFIGURE KDE_CONF_FILES ]) AC_DEFUN([KDE_SET_PREFIX], [ unset CDPATH dnl We can't give real code to that macro, only a value. dnl It only matters for --help, since we set the prefix in this function anyway. AC_PREFIX_DEFAULT(${KDEDIR:-the kde prefix}) KDE_SET_DEFAULT_BINDIRS if test "x$prefix" = "xNONE"; then dnl no prefix given: look for kde-config in the PATH and deduce the prefix from it KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend) else dnl prefix given: look for kde-config, preferrably in prefix, otherwise in PATH kde_save_PATH="$PATH" PATH="$exec_prefix/bin:$prefix/bin:$PATH" KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend) PATH="$kde_save_PATH" fi kde_libs_prefix=`$KDECONFIG --prefix` if test -z "$kde_libs_prefix" || test ! -x "$kde_libs_prefix"; then AC_MSG_ERROR([$KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs. This means it has been moved since you installed it. This won't work. Please recompile kdelibs for the new prefix. ]) fi kde_libs_htmldir=`$KDECONFIG --install html --expandvars` kde_libs_suffix=`$KDECONFIG --libsuffix` AC_MSG_CHECKING([where to install]) if test "x$prefix" = "xNONE"; then prefix=$kde_libs_prefix AC_MSG_RESULT([$prefix (as returned by kde-config)]) else dnl --prefix was given. Compare prefixes and warn (in configure.in.bot.end) if different given_prefix=$prefix AC_MSG_RESULT([$prefix (as requested)]) fi # And delete superfluous '/' to make compares easier prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` given_prefix=`echo "$given_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` AC_SUBST(KDECONFIG) AC_SUBST(kde_libs_prefix) AC_SUBST(kde_libs_htmldir) KDE_FAST_CONFIGURE KDE_CONF_FILES ]) pushdef([AC_PROG_INSTALL], [ dnl our own version, testing for a -p flag popdef([AC_PROG_INSTALL]) dnl as AC_PROG_INSTALL works as it works we first have dnl to save if the user didn't specify INSTALL, as the dnl autoconf one overwrites INSTALL and we have no chance to find dnl out afterwards test -n "$INSTALL" && kde_save_INSTALL_given=$INSTALL test -n "$INSTALL_PROGRAM" && kde_save_INSTALL_PROGRAM_given=$INSTALL_PROGRAM test -n "$INSTALL_SCRIPT" && kde_save_INSTALL_SCRIPT_given=$INSTALL_SCRIPT AC_PROG_INSTALL if test -z "$kde_save_INSTALL_given" ; then # OK, user hasn't given any INSTALL, autoconf found one for us # now we test, if it supports the -p flag AC_MSG_CHECKING(for -p flag to install) rm -f confinst.$$.* > /dev/null 2>&1 echo "Testtest" > confinst.$$.orig ac_res=no if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then if test -f confinst.$$.new ; then # OK, -p seems to do no harm to install INSTALL="${INSTALL} -p" ac_res=yes fi fi rm -f confinst.$$.* AC_MSG_RESULT($ac_res) fi dnl the following tries to resolve some signs and wonders coming up dnl with different autoconf/automake versions dnl e.g.: dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS) dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the dnl install-@DIR@PROGRAMS targets to explicitly use that flag dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as dnl INSTALL_SCRIPT, which breaks with automake <= 1.4 dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure dnl *sometimes KDE does not use the install-@DIR@PROGRAM targets from dnl automake (due to broken Makefile.am or whatever) to install programs, dnl and so does not see the -s flag in automake > 1.4 dnl to clean up that mess we: dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG dnl which cleans KDE's program with automake > 1.4; dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems dnl with automake<=1.4 dnl note that dues to this sometimes two '-s' flags are used (if KDE dnl properly uses install-@DIR@PROGRAMS, but I don't care dnl dnl And to all this comes, that I even can't write in comments variable dnl names used by automake, because it is so stupid to think I wanted to dnl _use_ them, therefor I have written A_M_... instead of AM_ dnl hmm, I wanted to say something ... ahh yes: Arghhh. if test -z "$kde_save_INSTALL_PROGRAM_given" ; then INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)' fi if test -z "$kde_save_INSTALL_SCRIPT_given" ; then INSTALL_SCRIPT='${INSTALL}' fi ])dnl AC_DEFUN([KDE_LANG_CPLUSPLUS], [AC_LANG_CPLUSPLUS ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&AC_FD_CC' pushdef([AC_LANG_CPLUSPLUS], [popdef([AC_LANG_CPLUSPLUS]) KDE_LANG_CPLUSPLUS]) ]) pushdef([AC_LANG_CPLUSPLUS], [popdef([AC_LANG_CPLUSPLUS]) KDE_LANG_CPLUSPLUS ]) AC_DEFUN([KDE_CHECK_LONG_LONG], [ AC_MSG_CHECKING(for long long) AC_CACHE_VAL(kde_cv_c_long_long, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_LINK([], [ long long foo = 0; foo = foo+1; ], kde_cv_c_long_long=yes, kde_cv_c_long_long=no) AC_LANG_RESTORE ]) AC_MSG_RESULT($kde_cv_c_long_long) if test "$kde_cv_c_long_long" = yes; then AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have long long as datatype]) fi ]) AC_DEFUN([KDE_CHECK_LIB], [ kde_save_LDFLAGS="$LDFLAGS" dnl AC_CHECK_LIB modifies LIBS, so save it here kde_save_LIBS="$LIBS" LDFLAGS="$LDFLAGS $all_libraries" case $host_os in aix*) LDFLAGS="-brtl $LDFLAGS" test "$GCC" = yes && LDFLAGS="-Wl,$LDFLAGS" ;; esac AC_CHECK_LIB($1, $2, $3, $4, $5) LDFLAGS="$kde_save_LDFLAGS" LIBS="$kde_save_LIBS" ]) AC_DEFUN([KDE_JAVA_PREFIX], [ dir=`dirname "$1"` base=`basename "$1"` list=`ls -1 $dir 2> /dev/null` for entry in $list; do if test -d $dir/$entry/bin; then case $entry in $base) javadirs="$javadirs $dir/$entry/bin" ;; esac elif test -d $dir/$entry/jre/bin; then case $entry in $base) javadirs="$javadirs $dir/$entry/jre/bin" ;; esac fi done ]) dnl KDE_CHEC_JAVA_DIR(onlyjre) AC_DEFUN([KDE_CHECK_JAVA_DIR], [ AC_ARG_WITH(java, AC_HELP_STRING([--with-java=javadir],[use java installed in javadir, --without-java disables]), [ ac_java_dir=$withval ], ac_java_dir="" ) AC_MSG_CHECKING([for Java]) dnl at this point ac_java_dir is either a dir, 'no' to disable, or '' to say look in $PATH if test "x$ac_java_dir" = "xno"; then kde_java_bindir=no kde_java_includedir=no kde_java_libjvmdir=no kde_java_libgcjdir=no kde_java_libhpidir=no else if test "x$ac_java_dir" = "x"; then dnl No option set -> collect list of candidate paths if test -n "$JAVA_HOME"; then KDE_JAVA_PREFIX($JAVA_HOME) fi KDE_JAVA_PREFIX(/usr/j2se) KDE_JAVA_PREFIX(/usr/lib/j2se) KDE_JAVA_PREFIX(/usr/j*dk*) KDE_JAVA_PREFIX(/usr/lib/j*dk*) KDE_JAVA_PREFIX(/opt/j*sdk*) KDE_JAVA_PREFIX(/usr/lib/java*) KDE_JAVA_PREFIX(/usr/java*) KDE_JAVA_PREFIX(/usr/java/j*dk*) KDE_JAVA_PREFIX(/usr/java/j*re*) KDE_JAVA_PREFIX(/usr/lib/SunJava2*) KDE_JAVA_PREFIX(/usr/lib/SunJava*) KDE_JAVA_PREFIX(/usr/lib/IBMJava2*) KDE_JAVA_PREFIX(/usr/lib/IBMJava*) KDE_JAVA_PREFIX(/opt/java*) kde_cv_path="NONE" kde_save_IFS=$IFS IFS=':' for dir in $PATH; do if test -d "$dir"; then javadirs="$javadirs $dir" fi done IFS=$kde_save_IFS jredirs= dnl Now javadirs contains a list of paths that exist, all ending with bin/ for dir in $javadirs; do dnl Check for the java executable if test -x "$dir/java"; then dnl And also check for a libjvm.so somewhere under there dnl Since we have to go to the parent dir, /usr/bin is excluded, /usr is too big. if test "$dir" != "/usr/bin"; then libjvmdir=`find $dir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1` if test ! -f $libjvmdir/libjvm.so; then continue; fi jredirs="$jredirs $dir" fi fi done dnl Now jredirs contains a reduced list, of paths where both java and ../**/libjvm.so was found JAVAC= JAVA= kde_java_bindir=no for dir in $jredirs; do JAVA="$dir/java" kde_java_bindir=$dir if test -x "$dir/javac"; then JAVAC="$dir/javac" break fi done if test -n "$JAVAC"; then dnl this substitution might not work - well, we test for jni.h below kde_java_includedir=`echo $JAVAC | sed -e 's,bin/javac$,include/,'` else kde_java_includedir=no fi else dnl config option set kde_java_bindir=$ac_java_dir/bin if test -x $ac_java_dir/bin/java && test ! -x $ac_java_dir/bin/javac; then kde_java_includedir=no else kde_java_includedir=$ac_java_dir/include fi fi fi dnl At this point kde_java_bindir and kde_java_includedir are either set or "no" if test "x$kde_java_bindir" != "xno"; then dnl Look for libjvm.so kde_java_libjvmdir=`find $kde_java_bindir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1` dnl Look for libgcj.so kde_java_libgcjdir=`find $kde_java_bindir/.. -name libgcj.so | sed 's,libgcj.so,,'|head -n 1` dnl Look for libhpi.so and avoid green threads kde_java_libhpidir=`find $kde_java_bindir/.. -name libhpi.so | grep -v green | sed 's,libhpi.so,,' | head -n 1` dnl Now check everything's fine under there dnl the include dir is our flag for having the JDK if test -d "$kde_java_includedir"; then if test ! -x "$kde_java_bindir/javac"; then AC_MSG_ERROR([javac not found under $kde_java_bindir - it seems you passed a wrong --with-java.]) fi if test ! -x "$kde_java_bindir/javah"; then AC_MSG_ERROR([javah not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) fi if test ! -x "$kde_java_bindir/jar"; then AC_MSG_ERROR([jar not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) fi if test ! -r "$kde_java_includedir/jni.h"; then AC_MSG_ERROR([jni.h not found under $kde_java_includedir. Use --with-java or --without-java.]) fi jni_includes="-I$kde_java_includedir" dnl Strange thing, jni.h requires jni_md.h which is under genunix here.. dnl and under linux here.. dnl not needed for gcj if test "x$kde_java_libgcjdir" = "x"; then test -d "$kde_java_includedir/linux" && jni_includes="$jni_includes -I$kde_java_includedir/linux" test -d "$kde_java_includedir/solaris" && jni_includes="$jni_includes -I$kde_java_includedir/solaris" test -d "$kde_java_includedir/genunix" && jni_includes="$jni_includes -I$kde_java_includedir/genunix" fi else JAVAC= jni_includes= fi if test "x$kde_java_libgcjdir" = "x"; then if test ! -r "$kde_java_libjvmdir/libjvm.so"; then AC_MSG_ERROR([libjvm.so not found under $kde_java_libjvmdir. Use --without-java.]) fi else if test ! -r "$kde_java_libgcjdir/libgcj.so"; then AC_MSG_ERROR([libgcj.so not found under $kde_java_libgcjdir. Use --without-java.]) fi fi if test ! -x "$kde_java_bindir/java"; then AC_MSG_ERROR([java not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) fi dnl not needed for gcj compile if test "x$kde_java_libgcjdir" = "x"; then if test ! -r "$kde_java_libhpidir/libhpi.so"; then AC_MSG_ERROR([libhpi.so not found under $kde_java_libhpidir. Use --without-java.]) fi fi if test -n "$jni_includes"; then dnl Check for JNI version AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_cxxflags_safe="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $all_includes $jni_includes" AC_TRY_COMPILE([ #include ], [ #ifndef JNI_VERSION_1_2 Syntax Error #endif ],[ kde_jni_works=yes ], [ kde_jni_works=no ]) if test $kde_jni_works = no; then AC_MSG_ERROR([Incorrect version of $kde_java_includedir/jni.h. You need to have Java Development Kit (JDK) version 1.2. Use --with-java to specify another location. Use --without-java to configure without java support. Or download a newer JDK and try again. See e.g. http://java.sun.com/products/jdk/1.2 ]) fi CXXFLAGS="$ac_cxxflags_safe" AC_LANG_RESTORE dnl All tests ok, inform and subst the variables JAVAC=$kde_java_bindir/javac JAVAH=$kde_java_bindir/javah JAR=$kde_java_bindir/jar AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) if test "x$kde_java_libgcjdir" = "x"; then JVMLIBS="-L$kde_java_libjvmdir -ljvm -L$kde_java_libhpidir -lhpi" else JVMLIBS="-L$kde_java_libgcjdir -lgcj" fi AC_MSG_RESULT([java JDK in $kde_java_bindir]) else AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) AC_MSG_RESULT([java JRE in $kde_java_bindir]) fi elif test -d "/Library/Java/Home"; then kde_java_bindir="/Library/Java/Home/bin" jni_includes="-I/Library/Java/Home/include" JAVAC=$kde_java_bindir/javac JAVAH=$kde_java_bindir/javah JAR=$kde_java_bindir/jar JVMLIBS="-Xlinker -framework -Xlinker JavaVM" AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) AC_MSG_RESULT([Apple Java Framework]) else AC_MSG_RESULT([none found]) fi AC_SUBST(JAVAC) AC_SUBST(JAVAH) AC_SUBST(JAR) AC_SUBST(JVMLIBS) AC_SUBST(jni_includes) # for backward compat kde_cv_java_includedir=$kde_java_includedir kde_cv_java_bindir=$kde_java_bindir ]) dnl this is a redefinition of autoconf 2.5x's AC_FOREACH. dnl When the argument list becomes big, as in KDE for AC_OUTPUT in dnl big packages, m4_foreach is dog-slow. So use our own version of dnl it. (matz@kde.org) m4_define([mm_foreach], [m4_pushdef([$1])_mm_foreach($@)m4_popdef([$1])]) m4_define([mm_car], [[$1]]) m4_define([mm_car2], [[$@]]) m4_define([_mm_foreach], [m4_if(m4_quote($2), [], [], [m4_define([$1], mm_car($2))$3[]_mm_foreach([$1], mm_car2(m4_shift($2)), [$3])])]) m4_define([AC_FOREACH], [mm_foreach([$1], m4_split(m4_normalize([$2])), [$3])]) AC_DEFUN([KDE_NEED_FLEX], [ kde_libs_safe=$LIBS LIBS="$LIBS $USER_LDFLAGS" AM_PROG_LEX LIBS=$kde_libs_safe if test -z "$LEXLIB"; then AC_MSG_ERROR([You need to have flex installed.]) fi AC_SUBST(LEXLIB) ]) AC_DEFUN([AC_PATH_QTOPIA], [ dnl TODO: use AC_CACHE_VAL if test -z "$1"; then qtopia_minver_maj=1 qtopia_minver_min=5 qtopia_minver_pat=0 else qtopia_minver_maj=`echo "$1" | sed -e "s/^\(.*\)\..*\..*$/\1/"` qtopia_minver_min=`echo "$1" | sed -e "s/^.*\.\(.*\)\..*$/\1/"` qtopia_minver_pat=`echo "$1" | sed -e "s/^.*\..*\.\(.*\)$/\1/"` fi qtopia_minver="$qtopia_minver_maj$qtopia_minver_min$qtopia_minver_pat" qtopia_minverstr="$qtopia_minver_maj.$qtopia_minver_min.$qtopia_minver_pat" AC_REQUIRE([AC_PATH_QT]) AC_MSG_CHECKING([for Qtopia]) LIB_QTOPIA="-lqpe" AC_SUBST(LIB_QTOPIA) kde_qtopia_dirs="$QPEDIR /opt/Qtopia" ac_qtopia_incdir=NO AC_ARG_WITH(qtopia-dir, AC_HELP_STRING([--with-qtopia-dir=DIR],[where the root of Qtopia is installed]), [ ac_qtopia_incdir="$withval"/include] ) qtopia_incdirs="" for dir in $kde_qtopia_dirs; do qtopia_incdirs="$qtopia_incdirs $dir/include" done if test ! "$ac_qtopia_incdir" = "NO"; then qtopia_incdirs="$ac_qtopia_incdir $qtopia_incdirs" fi qtopia_incdir="" AC_FIND_FILE(qpe/qpeapplication.h, $qtopia_incdirs, qtopia_incdir) ac_qtopia_incdir="$qtopia_incdir" if test -z "$qtopia_incdir"; then AC_MSG_ERROR([Cannot find Qtopia headers. Please check your installation.]) fi qtopia_ver_maj=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION "\(.*\)\..*\..*".*,\1,p'`; qtopia_ver_min=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\.\(.*\)\..*".*,\1,p'`; qtopia_ver_pat=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\..*\.\(.*\)".*,\1,p'`; qtopia_ver="$qtopia_ver_maj$qtopia_ver_min$qtopia_ver_pat" qtopia_verstr="$qtopia_ver_maj.$qtopia_ver_min.$qtopia_ver_pat" if test "$qtopia_ver" -lt "$qtopia_minver"; then AC_MSG_ERROR([found Qtopia version $qtopia_verstr but version $qtopia_minverstr is required.]) fi AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_cxxflags_safe="$CXXFLAGS" ac_ldflags_safe="$LDFLAGS" ac_libs_safe="$LIBS" CXXFLAGS="$CXXFLAGS -I$qtopia_incdir $all_includes" LDFLAGS="$LDFLAGS $QT_LDFLAGS $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" LIBS="$LIBS $LIB_QTOPIA $LIBQT" cat > conftest.$ac_ext < #include int main( int argc, char **argv ) { QPEApplication app( argc, argv ); return 0; } EOF if AC_TRY_EVAL(ac_link) && test -s conftest; then rm -f conftest* else rm -f conftest* AC_MSG_ERROR([Cannot link small Qtopia Application. For more details look at the end of config.log]) fi CXXFLAGS="$ac_cxxflags_safe" LDFLAGS="$ac_ldflags_safe" LIBS="$ac_libs_safe" AC_LANG_RESTORE QTOPIA_INCLUDES="-I$qtopia_incdir" AC_SUBST(QTOPIA_INCLUDES) AC_MSG_RESULT([found version $qtopia_verstr with headers at $qtopia_incdir]) ]) AC_DEFUN([KDE_INIT_DOXYGEN], [ AC_MSG_CHECKING([for Qt docs]) kde_qtdir= if test "${with_qt_dir+set}" = set; then kde_qtdir="$with_qt_dir" fi AC_FIND_FILE(qsql.html, [ $kde_qtdir/doc/html $QTDIR/doc/html /usr/share/doc/packages/qt3/html /usr/lib/qt/doc /usr/lib/qt3/doc /usr/lib/qt3/doc/html /usr/doc/qt3/html /usr/doc/qt3 /usr/share/doc/qt3-doc /usr/share/qt3/doc/html /usr/X11R6/share/doc/qt/html ], QTDOCDIR) AC_MSG_RESULT($QTDOCDIR) AC_SUBST(QTDOCDIR) KDE_FIND_PATH(dot, DOT, [], []) if test -n "$DOT"; then KDE_HAVE_DOT="YES" else KDE_HAVE_DOT="NO" fi AC_SUBST(KDE_HAVE_DOT) KDE_FIND_PATH(doxygen, DOXYGEN, [], []) AC_SUBST(DOXYGEN) DOXYGEN_PROJECT_NAME="$1" DOXYGEN_PROJECT_NUMBER="$2" AC_SUBST(DOXYGEN_PROJECT_NAME) AC_SUBST(DOXYGEN_PROJECT_NUMBER) KDE_HAS_DOXYGEN=no if test -n "$DOXYGEN" && test -x "$DOXYGEN" && test -f $QTDOCDIR/qsql.html; then KDE_HAS_DOXYGEN=yes fi AC_SUBST(KDE_HAS_DOXYGEN) ]) AC_DEFUN([AC_FIND_BZIP2], [ AC_MSG_CHECKING([for bzDecompress in libbz2]) AC_CACHE_VAL(ac_cv_lib_bzip2, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS kde_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS -lbz2 $LIBSOCKET" kde_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" AC_TRY_LINK(dnl [ #define BZ_NO_STDIO #include ], [ bz_stream s; (void) bzDecompress(&s); ], eval "ac_cv_lib_bzip2='-lbz2'", eval "ac_cv_lib_bzip2=no") LIBS="$kde_save_LIBS" CXXFLAGS="$kde_save_CXXFLAGS" AC_LANG_RESTORE ])dnl AC_MSG_RESULT($ac_cv_lib_bzip2) if test ! "$ac_cv_lib_bzip2" = no; then BZIP2DIR=bzip2 LIBBZ2="$ac_cv_lib_bzip2" AC_SUBST(LIBBZ2) else cxx_shared_flag= ld_shared_flag= KDE_CHECK_COMPILER_FLAG(shared, [ ld_shared_flag="-shared" ]) KDE_CHECK_COMPILER_FLAG(fPIC, [ cxx_shared_flag="-fPIC" ]) AC_MSG_CHECKING([for BZ2_bzDecompress in (shared) libbz2]) AC_CACHE_VAL(ac_cv_lib_bzip2_prefix, [ AC_LANG_SAVE AC_LANG_CPLUSPLUS kde_save_LIBS="$LIBS" LIBS="$all_libraries $USER_LDFLAGS $ld_shared_flag -lbz2 $LIBSOCKET" kde_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CFLAGS $cxx_shared_flag $all_includes $USER_INCLUDES" AC_TRY_LINK(dnl [ #define BZ_NO_STDIO #include ], [ bz_stream s; (void) BZ2_bzDecompress(&s); ], eval "ac_cv_lib_bzip2_prefix='-lbz2'", eval "ac_cv_lib_bzip2_prefix=no") LIBS="$kde_save_LIBS" CXXFLAGS="$kde_save_CXXFLAGS" AC_LANG_RESTORE ])dnl AC_MSG_RESULT($ac_cv_lib_bzip2_prefix) if test ! "$ac_cv_lib_bzip2_prefix" = no; then BZIP2DIR=bzip2 LIBBZ2="$ac_cv_lib_bzip2_prefix" AC_SUBST(LIBBZ2) AC_DEFINE(NEED_BZ2_PREFIX, 1, [Define if the libbz2 functions need the BZ2_ prefix]) dnl else, we just ignore this fi fi AM_CONDITIONAL(include_BZIP2, test -n "$BZIP2DIR") ]) dnl ------------------------------------------------------------------------ dnl Try to find the SSL headers and libraries. dnl $(SSL_LDFLAGS) will be -Lsslliblocation (if needed) dnl and $(SSL_INCLUDES) will be -Isslhdrlocation (if needed) dnl ------------------------------------------------------------------------ dnl AC_DEFUN([KDE_CHECK_SSL], [ LIBSSL="-lssl -lcrypto" AC_REQUIRE([KDE_CHECK_LIB64]) ac_ssl_includes=NO ac_ssl_libraries=NO ssl_libraries="" ssl_includes="" AC_ARG_WITH(ssl-dir, AC_HELP_STRING([--with-ssl-dir=DIR],[where the root of OpenSSL is installed]), [ ac_ssl_includes="$withval"/include ac_ssl_libraries="$withval"/lib$kdelibsuff ]) want_ssl=yes AC_ARG_WITH(ssl, AC_HELP_STRING([--without-ssl],[disable SSL checks]), [want_ssl=$withval]) if test $want_ssl = yes; then AC_MSG_CHECKING(for OpenSSL) AC_CACHE_VAL(ac_cv_have_ssl, [#try to guess OpenSSL locations ssl_incdirs="/usr/include /usr/local/include /usr/ssl/include /usr/local/ssl/include $prefix/include $kde_extra_includes" ssl_incdirs="$ac_ssl_includes $ssl_incdirs" AC_FIND_FILE(openssl/ssl.h, $ssl_incdirs, ssl_incdir) ac_ssl_includes="$ssl_incdir" ssl_libdirs="/usr/lib$kdelibsuff /usr/local/lib$kdelibsuff /usr/ssl/lib$kdelibsuff /usr/local/ssl/lib$kdelibsuff $libdir $prefix/lib$kdelibsuff $exec_prefix/lib$kdelibsuff $kde_extra_libs" if test ! "$ac_ssl_libraries" = "NO"; then ssl_libdirs="$ac_ssl_libraries $ssl_libdirs" fi test=NONE ssl_libdir=NONE for dir in $ssl_libdirs; do try="ls -1 $dir/libssl*" if test=`eval $try 2> /dev/null`; then ssl_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi done ac_ssl_libraries="$ssl_libdir" ac_ldflags_safe="$LDFLAGS" ac_libs_safe="$LIBS" LDFLAGS="$LDFLAGS -L$ssl_libdir $all_libraries" LIBS="$LIBS $LIBSSL -lRSAglue -lrsaref" AC_TRY_LINK(,void RSAPrivateEncrypt(void);RSAPrivateEncrypt();, ac_ssl_rsaref="yes" , ac_ssl_rsaref="no" ) LDFLAGS="$ac_ldflags_safe" LIBS="$ac_libs_safe" if test "$ac_ssl_includes" = NO || test "$ac_ssl_libraries" = NO; then have_ssl=no else have_ssl=yes; fi ]) eval "$ac_cv_have_ssl" AC_MSG_RESULT([libraries $ac_ssl_libraries, headers $ac_ssl_includes]) AC_MSG_CHECKING([whether OpenSSL uses rsaref]) AC_MSG_RESULT($ac_ssl_rsaref) AC_MSG_CHECKING([for easter eggs]) AC_MSG_RESULT([none found]) else have_ssl=no fi if test "$have_ssl" = yes; then AC_MSG_CHECKING(for OpenSSL version) dnl Check for SSL version AC_CACHE_VAL(ac_cv_ssl_version, [ cat >conftest.$ac_ext < #include int main() { #ifndef OPENSSL_VERSION_NUMBER printf("ssl_version=\\"error\\"\n"); #else if (OPENSSL_VERSION_NUMBER < 0x00906000) printf("ssl_version=\\"old\\"\n"); else printf("ssl_version=\\"ok\\"\n"); #endif return (0); } EOF ac_save_CPPFLAGS=$CPPFLAGS if test "$ac_ssl_includes" != "/usr/include"; then CPPFLAGS="$CPPFLAGS -I$ac_ssl_includes" fi if AC_TRY_EVAL(ac_link); then if eval `./conftest 2>&5`; then if test $ssl_version = error; then AC_MSG_ERROR([$ssl_incdir/openssl/opensslv.h doesn't define OPENSSL_VERSION_NUMBER !]) else if test $ssl_version = old; then AC_MSG_WARN([OpenSSL version too old. Upgrade to 0.9.6 at least, see http://www.openssl.org. SSL support disabled.]) have_ssl=no fi fi ac_cv_ssl_version="ssl_version=$ssl_version" else AC_MSG_ERROR([Your system couldn't run a small SSL test program. Check config.log, and if you can't figure it out, send a mail to David Faure , attaching your config.log]) fi else AC_MSG_ERROR([Your system couldn't link a small SSL test program. Check config.log, and if you can't figure it out, send a mail to David Faure , attaching your config.log]) fi CPPFLAGS=$ac_save_CPPFLAGS ]) eval "$ac_cv_ssl_version" AC_MSG_RESULT($ssl_version) fi if test "$have_ssl" != yes; then LIBSSL=""; else AC_DEFINE(HAVE_SSL, 1, [If we are going to use OpenSSL]) ac_cv_have_ssl="have_ssl=yes \ ac_ssl_includes=$ac_ssl_includes ac_ssl_libraries=$ac_ssl_libraries ac_ssl_rsaref=$ac_ssl_rsaref" ssl_libraries="$ac_ssl_libraries" ssl_includes="$ac_ssl_includes" if test "$ac_ssl_rsaref" = yes; then LIBSSL="-lssl -lcrypto -lRSAglue -lrsaref" fi if test $ssl_version = "old"; then AC_DEFINE(HAVE_OLD_SSL_API, 1, [Define if you have OpenSSL < 0.9.6]) fi fi SSL_INCLUDES= if test "$ssl_includes" = "/usr/include"; then if test -f /usr/kerberos/include/krb5.h; then SSL_INCLUDES="-I/usr/kerberos/include" fi elif test "$ssl_includes" != "/usr/local/include" && test -n "$ssl_includes"; then SSL_INCLUDES="-I$ssl_includes" fi if test "$ssl_libraries" = "/usr/lib" || test "$ssl_libraries" = "/usr/local/lib" || test -z "$ssl_libraries" || test "$ssl_libraries" = "NONE"; then SSL_LDFLAGS="" else SSL_LDFLAGS="-L$ssl_libraries -R$ssl_libraries" fi AC_SUBST(SSL_INCLUDES) AC_SUBST(SSL_LDFLAGS) AC_SUBST(LIBSSL) ]) AC_DEFUN([KDE_CHECK_STRLCPY], [ AC_REQUIRE([AC_CHECK_STRLCAT]) AC_REQUIRE([AC_CHECK_STRLCPY]) AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(unsigned long) AC_MSG_CHECKING([sizeof size_t == sizeof unsigned long]) AC_TRY_COMPILE(,[ #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_LONG choke me #endif ],AC_MSG_RESULT([yes]),[ AC_MSG_RESULT(no) AC_MSG_ERROR([ Apparently on your system our assumption sizeof size_t == sizeof unsigned long does not apply. Please mail kde-devel@kde.org with a description of your system! ]) ]) ]) AC_DEFUN([KDE_CHECK_BINUTILS], [ AC_MSG_CHECKING([if ld supports unversioned version maps]) kde_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" echo "{ local: extern \"C++\" { foo }; };" > conftest.map AC_TRY_LINK([int foo;], [ #ifdef __INTEL_COMPILER icc apparently does not support libtools version-info and version-script at the same time. Dunno where the bug is, but until somebody figured out, better disable the optional version scripts. #endif foo = 42; ], kde_supports_versionmaps=yes, kde_supports_versionmaps=no) LDFLAGS="$kde_save_LDFLAGS" rm -f conftest.map AM_CONDITIONAL(include_VERSION_SCRIPT, [test "$kde_supports_versionmaps" = "yes" && test "$kde_use_debug_code" = "no"]) AC_MSG_RESULT($kde_supports_versionmaps) ]) AC_DEFUN([AM_PROG_OBJC],[ AC_CHECK_PROGS(OBJC, gcc, gcc) test -z "$OBJC" && AC_MSG_ERROR([no acceptable objective-c gcc found in \$PATH]) if test "x${OBJCFLAGS-unset}" = xunset; then OBJCFLAGS="-g -O2" fi AC_SUBST(OBJCFLAGS) _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES(OBJC)]) ]) AC_DEFUN([KDE_CHECK_PERL], [ KDE_FIND_PATH(perl, PERL, [$bindir $exec_prefix/bin $prefix/bin], [ AC_MSG_ERROR([No Perl found in your $PATH. We need perl to generate some code.]) ]) AC_SUBST(PERL) ]) AC_DEFUN([KDE_CHECK_LARGEFILE], [ AC_SYS_LARGEFILE if test "$ac_cv_sys_file_offset_bits" != no; then CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" fi if test "x$ac_cv_sys_large_files" != "xno"; then CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=1" fi ]) dnl A small extension to PKG_CHECK_MODULES (defined in pkg.m4.in) dnl which allows to search for libs that get installed into the KDE prefix. dnl dnl Syntax: KDE_PKG_CHECK_MODULES(KSTUFF, libkexif >= 0.2 glib = 1.3.4, action-if, action-not) dnl defines KSTUFF_LIBS, KSTUFF_CFLAGS, see pkg-config man page dnl also defines KSTUFF_PKG_ERRORS on error AC_DEFUN([KDE_PKG_CHECK_MODULES], [ PKG_CONFIG_PATH="$prefix/lib/pkgconfig:$PKG_CONFIG_PATH" if test "$prefix" != "$kde_libs_prefix"; then PKG_CONFIG_PATH="$kde_libs_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" fi export PKG_CONFIG_PATH PKG_CHECK_MODULES($1,$2,$3,$4) ]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- ## Copyright 1996, 1997, 1998, 1999, 2000, 2001 ## Free Software Foundation, Inc. ## Originally by Gordon Matzigkeit , 1996 ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ## ## As a special exception to the GNU General Public License, if you ## distribute this file as part of a program that contains a ## configuration script generated by Autoconf, you may include it under ## the same distribution terms that you use for the rest of that program. # serial 47 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) # ----------------------------------------------------------- # If this macro is not defined by Autoconf, define it here. m4_ifdef([AC_PROVIDE_IFELSE], [], [m4_define([AC_PROVIDE_IFELSE], [m4_ifdef([AC_PROVIDE_$1], [$2], [$3])])]) # AC_PROG_LIBTOOL # --------------- AC_DEFUN([AC_PROG_LIBTOOL], [AC_REQUIRE([_AC_PROG_LIBTOOL])dnl dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. AC_PROVIDE_IFELSE([AC_PROG_CXX], [AC_LIBTOOL_CXX], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX ])]) dnl And a similar setup for Fortran 77 support AC_PROVIDE_IFELSE([AC_PROG_F77], [AC_LIBTOOL_F77], [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 ])]) dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [AC_LIBTOOL_GCJ], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [AC_LIBTOOL_GCJ], [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], [AC_LIBTOOL_GCJ], [ifdef([AC_PROG_GCJ], [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ifdef([A][M_PROG_GCJ], [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ifdef([LT_AC_PROG_GCJ], [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) ])])# AC_PROG_LIBTOOL # _AC_PROG_LIBTOOL # ---------------- AC_DEFUN([_AC_PROG_LIBTOOL], [AC_REQUIRE([AC_LIBTOOL_SETUP])dnl AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool --silent' AC_SUBST(LIBTOOL)dnl # Prevent multiple expansion define([AC_PROG_LIBTOOL], []) ])# _AC_PROG_LIBTOOL # AC_LIBTOOL_SETUP # ---------------- AC_DEFUN([AC_LIBTOOL_SETUP], [AC_PREREQ(2.50)dnl AC_REQUIRE([AC_ENABLE_SHARED])dnl AC_REQUIRE([AC_ENABLE_STATIC])dnl AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_LD])dnl AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl AC_REQUIRE([AC_PROG_NM])dnl AC_REQUIRE([AC_PROG_LN_S])dnl AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! AC_REQUIRE([AC_OBJEXT])dnl AC_REQUIRE([AC_EXEEXT])dnl dnl AC_LIBTOOL_SYS_MAX_CMD_LEN AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE AC_LIBTOOL_OBJDIR AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl _LT_AC_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e s/^X//' [sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] # Same as above, but do not quote variable references. [double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Constants: rm="rm -f" # Global variables: default_ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except M$VC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" ofile="$default_ofile" with_gnu_ld="$lt_cv_prog_gnu_ld" AC_CHECK_TOOL(AR, ar, false) AC_CHECK_TOOL(RANLIB, ranlib, :) AC_CHECK_TOOL(STRIP, strip, :) old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" test -z "$MAGIC_CMD" && MAGIC_CMD=file test -z "$NM" && NM=nm test -z "$SED" && SED=sed test -z "$OBJDUMP" && OBJDUMP=objdump test -z "$RANLIB" && RANLIB=: test -z "$STRIP" && STRIP=: test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" ;; *) old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then AC_PATH_MAGIC fi ;; esac AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], enable_win32_dll=yes, enable_win32_dll=no) AC_ARG_ENABLE([libtool-lock], [AC_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes AC_ARG_WITH([pic], [AC_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=default # Use C for the default configuration in the libtool script tagname= AC_LIBTOOL_LANG_C_CONFIG _LT_AC_TAGCONFIG ])# AC_LIBTOOL_SETUP # _LT_AC_SYS_COMPILER # ------------------- AC_DEFUN([_LT_AC_SYS_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_AC_SYS_COMPILER # _LT_AC_SYS_LIBPATH_AIX # ---------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], [AC_LINK_IFELSE(AC_LANG_PROGRAM,[ aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_AC_SYS_LIBPATH_AIX # _LT_AC_SHELL_INIT(ARG) # ---------------------- AC_DEFUN([_LT_AC_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_AC_SHELL_INIT # _LT_AC_PROG_ECHO_BACKSLASH # -------------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], [_LT_AC_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac echo=${ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then # Yippee, $echo works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null && echo_test_string="`eval $cmd`" && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break fi done fi if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$echo" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. echo='print -r' elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. echo='printf %s\n' if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL echo="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. echo=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. ECHO=$echo if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(ECHO) ])])# _LT_AC_PROG_ECHO_BACKSLASH # _LT_AC_LOCK # ----------- AC_DEFUN([_LT_AC_LOCK], [AC_ARG_ENABLE([libtool-lock], [AC_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case "`/usr/bin/file conftest.o`" in *32-bit*) LINUX_64_MODE="32" case $host in x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) LINUX_64_MODE="64" case $host in x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], [*-*-cygwin* | *-*-mingw* | *-*-pw32*) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; ]) esac need_locks="$enable_libtool_lock" ])# _LT_AC_LOCK # AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [AC_REQUIRE([LT_AC_PROG_SED]) AC_CACHE_CHECK([$1], [$2], [$2=no ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test ! -s conftest.err; then $2=yes fi fi $rm conftest* ]) if test x"[$]$2" = xyes; then ifelse([$5], , :, [$5]) else ifelse([$6], , :, [$6]) fi ])# AC_LIBTOOL_COMPILER_OPTION # AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ------------------------------------------------------------ # Check whether the given compiler option works AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD else $2=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then ifelse([$4], , :, [$4]) else ifelse([$5], , :, [$5]) fi ])# AC_LIBTOOL_LINKER_OPTION # AC_LIBTOOL_SYS_MAX_CMD_LEN # -------------------------- AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [# find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 testring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; *) # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$testring" 2>/dev/null` \ = "XX$testring") >/dev/null 2>&1 && new_result=`expr "X$testring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` testring=$testring$testring done testring= # Add a significant safety factor because C++ compilers can tack on massive # amounts of additional arguments before passing them to the linker. # It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi ])# AC_LIBTOOL_SYS_MAX_CMD_LEN # _LT_AC_CHECK_DLFCN # -------------------- AC_DEFUN([_LT_AC_CHECK_DLFCN], [AC_CHECK_HEADERS(dlfcn.h)dnl ])# _LT_AC_CHECK_DLFCN # _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ------------------------------------------------------------------ AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif #ifdef __cplusplus extern "C" void exit (int); #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } exit (status); }] EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_unknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_AC_TRY_DLOPEN_SELF # AC_LIBTOOL_DLOPEN_SELF # ------------------- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_AC_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then LDFLAGS="$LDFLAGS $link_static_flag" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_AC_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi ])# AC_LIBTOOL_DLOPEN_SELF # AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) # --------------------------------- # Check to see if options -c and -o are simultaneously supported by compiler AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], [AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext # According to Tom Tromey, Ian Lance Taylor reported there are C compilers # that will create temporary files in the current directory regardless of # the output directory. Thus, making CWD read-only will cause this test # to fail, enabling locking or at least warning the user not to do parallel # builds. chmod -w . lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test ! -s out/conftest.err; then _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . $rm conftest* out/* rmdir out cd .. rmdir conftest $rm conftest* ]) ])# AC_LIBTOOL_PROG_CC_C_O # AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) # ----------------------------------------- # Check to see if we can do hard links to lock some files if needed AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_REQUIRE([_LT_AC_LOCK])dnl hard_links="nottested" if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi ])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS # AC_LIBTOOL_OBJDIR # ----------------- AC_DEFUN([AC_LIBTOOL_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir ])# AC_LIBTOOL_OBJDIR # AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) # ---------------------------------------------- # Check hardcoding attributes. AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_AC_TAGVAR(hardcode_action, $1)= if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then # We can hardcode non-existant directories. if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_AC_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_AC_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_AC_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi ])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH # AC_LIBTOOL_SYS_LIB_STRIP # ------------------------ AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], [striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi ])# AC_LIBTOOL_SYS_LIB_STRIP # AC_LIBTOOL_SYS_DYNAMIC_LINKER # ----------------------------- # PORTME Fill in your ld.so characteristics AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_MSG_CHECKING([dynamic linker characteristics]) library_names_spec= libname_spec='lib$name' soname_spec= shrext=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi4*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext='$(test .$module = .yes && echo .so || echo .dylib)' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd*-gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; freebsd*) objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; *) # from 3.2 on shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case "$host_cpu" in ia64*) shrext='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' libsuff= if test "x$LINUX_64_MODE" = x64; then # Some platforms are per default 64-bit, so there's no /lib64 if test -d /lib64; then libsuff=64 fi fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; sco3.2v5*) version_type=osf soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no ])# AC_LIBTOOL_SYS_DYNAMIC_LINKER # _LT_AC_TAGCONFIG # ---------------- AC_DEFUN([_LT_AC_TAGCONFIG], [AC_ARG_WITH([tags], [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], [include additional configurations @<:@automatic@:>@])], [tagnames="$withval"]) if test -f "$ltmain" && test -n "$tagnames"; then if test ! -f "${ofile}"; then AC_MSG_WARN([output file `$ofile' does not exist]) fi if test -z "$LTCC"; then eval "`$SHELL ${ofile} --config | grep '^LTCC='`" if test -z "$LTCC"; then AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) else AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) fi fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for tagname in $tagnames; do IFS="$lt_save_ifs" # Check whether tagname contains only valid characters case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in "") ;; *) AC_MSG_ERROR([invalid tag name: $tagname]) ;; esac if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null then AC_MSG_ERROR([tag name \"$tagname\" already exists]) fi # Update the list of available tags. if test -n "$tagname"; then echo appending configuration tag \"$tagname\" to $ofile case $tagname in CXX) if test -n "$CXX" && test "X$CXX" != "Xno"; then AC_LIBTOOL_LANG_CXX_CONFIG else tagname="" fi ;; F77) if test -n "$F77" && test "X$F77" != "Xno"; then AC_LIBTOOL_LANG_F77_CONFIG else tagname="" fi ;; GCJ) if test -n "$GCJ" && test "X$GCJ" != "Xno"; then AC_LIBTOOL_LANG_GCJ_CONFIG else tagname="" fi ;; RC) AC_LIBTOOL_LANG_RC_CONFIG ;; *) AC_MSG_ERROR([Unsupported tag name: $tagname]) ;; esac # Append the new tag name to the list of available tags. if test -n "$tagname" ; then available_tags="$available_tags $tagname" fi fi done IFS="$lt_save_ifs" # Now substitute the updated list of available tags. if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then mv "${ofile}T" "$ofile" chmod +x "$ofile" else rm -f "${ofile}T" AC_MSG_ERROR([unable to update list of available tagged configurations.]) fi fi ])# _LT_AC_TAGCONFIG # AC_LIBTOOL_DLOPEN # ----------------- # enable checks for dlopen support AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) ])# AC_LIBTOOL_DLOPEN # AC_LIBTOOL_WIN32_DLL # -------------------- # declare package support for building win32 dll's AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) ])# AC_LIBTOOL_WIN32_DLL # AC_ENABLE_SHARED([DEFAULT]) # --------------------------- # implement the --enable-shared flag # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. AC_DEFUN([AC_ENABLE_SHARED], [define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl AC_ARG_ENABLE([shared], [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]AC_ENABLE_SHARED_DEFAULT) ])# AC_ENABLE_SHARED # AC_DISABLE_SHARED # ----------------- #- set the default shared flag to --disable-shared AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_SHARED(no) ])# AC_DISABLE_SHARED # AC_ENABLE_STATIC([DEFAULT]) # --------------------------- # implement the --enable-static flag # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. AC_DEFUN([AC_ENABLE_STATIC], [define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl AC_ARG_ENABLE([static], [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]AC_ENABLE_STATIC_DEFAULT) ])# AC_ENABLE_STATIC # AC_DISABLE_STATIC # ----------------- # set the default static flag to --disable-static AC_DEFUN([AC_DISABLE_STATIC], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_STATIC(no) ])# AC_DISABLE_STATIC # AC_ENABLE_FAST_INSTALL([DEFAULT]) # --------------------------------- # implement the --enable-fast-install flag # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. AC_DEFUN([AC_ENABLE_FAST_INSTALL], [define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl AC_ARG_ENABLE([fast-install], [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) ])# AC_ENABLE_FAST_INSTALL # AC_DISABLE_FAST_INSTALL # ----------------------- # set the default to --disable-fast-install AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_FAST_INSTALL(no) ])# AC_DISABLE_FAST_INSTALL # AC_LIBTOOL_PICMODE([MODE]) # -------------------------- # implement the --with-pic flag # MODE is either `yes' or `no'. If omitted, it defaults to `both'. AC_DEFUN([AC_LIBTOOL_PICMODE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl pic_mode=ifelse($#,1,$1,default) ])# AC_LIBTOOL_PICMODE # AC_PROG_EGREP # ------------- # This is predefined starting with Autoconf 2.54, so this conditional # definition can be removed once we require Autoconf 2.54 or later. m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], [AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi]) EGREP=$ac_cv_prog_egrep AC_SUBST([EGREP]) ])]) # AC_PATH_TOOL_PREFIX # ------------------- # find a file program which can recognise shared library AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="ifelse([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi ])# AC_PATH_TOOL_PREFIX # AC_PATH_MAGIC # ------------- # find a file program which can recognise a shared library AC_DEFUN([AC_PATH_MAGIC], [AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# AC_PATH_MAGIC # AC_PROG_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([AC_PROG_LD], [AC_ARG_WITH([gnu-ld], [AC_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no]) AC_REQUIRE([LT_AC_PROG_SED])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case "$host_cpu" in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; irix5* | irix6* | nonstopux*) case $host_os in irix5* | nonstopux*) # this will be overridden with pass_all, but let us keep it just in case lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" ;; *) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac # this will be overridden with pass_all, but let us keep it just in case lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" ;; esac lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux*) case $host_cpu in alpha* | hppa* | i*86 | ia64* | m68* | mips* | powerpc* | sparc* | s390* | sh* | x86_64* ) lt_cv_deplibs_check_method=pass_all ;; # the debian people say, arm and glibc 2.3.1 works for them with pass_all arm* ) lt_cv_deplibs_check_method=pass_all ;; *) # glibc up to 2.1.1 does not perform some relocations on ARM lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; esac lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; nto-qnx*) lt_cv_deplibs_check_method=unknown ;; openbsd*) lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' else lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' fi ;; osf3* | osf4* | osf5*) # this will be overridden with pass_all, but let us keep it just in case lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' lt_cv_file_magic_test_file=/shlib/libc.so lt_cv_deplibs_check_method=pass_all ;; sco3.2v5*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all lt_cv_file_magic_test_file=/lib/libc.so ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; esac ;; sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown ])# AC_DEPLIBS_CHECK_METHOD # AC_PROG_NM # ---------- # find the pathname to a BSD-compatible name lister AC_DEFUN([AC_PROG_NM], [AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/${ac_tool_prefix}nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac esac fi done IFS="$lt_save_ifs" test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi]) NM="$lt_cv_path_NM" ])# AC_PROG_NM # AC_CHECK_LIBM # ------------- # check for math library AC_DEFUN([AC_CHECK_LIBM], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac ])# AC_CHECK_LIBM # AC_LIBLTDL_CONVENIENCE([DIRECTORY]) # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL # and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If # DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will # be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with # '${top_srcdir}/' (note the single quotes!). If your package is not # flat and you're not using automake, define top_builddir and # top_srcdir appropriately in the Makefiles. AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; esac LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" ])# AC_LIBLTDL_CONVENIENCE # AC_LIBLTDL_INSTALLABLE([DIRECTORY]) # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl installable library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-install to the configure arguments. Note that LIBLTDL # and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If # DIRECTORY is not provided and an installed libltdl is not found, it is # assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' # and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single # quotes!). If your package is not flat and you're not using automake, # define top_builddir and top_srcdir appropriately in the Makefiles. # In the future, this macro may have to be called after AC_PROG_LIBTOOL. AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_CHECK_LIB(ltdl, lt_dlinit, [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], [if test x"$enable_ltdl_install" = xno; then AC_MSG_WARN([libltdl not installed, but installation disabled]) else enable_ltdl_install=yes fi ]) if test x"$enable_ltdl_install" = x"yes"; then ac_configure_args="$ac_configure_args --enable-ltdl-install" LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) else ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL="-lltdl" LTDLINCL= fi # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" ])# AC_LIBLTDL_INSTALLABLE # AC_LIBTOOL_CXX # -------------- # enable support for C++ libraries AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_LT_AC_LANG_CXX]) ])# AC_LIBTOOL_CXX # _LT_AC_LANG_CXX # --------------- AC_DEFUN([_LT_AC_LANG_CXX], [AC_REQUIRE([AC_PROG_CXX]) AC_REQUIRE([AC_PROG_CXXCPP]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) ])# _LT_AC_LANG_CXX # AC_LIBTOOL_F77 # -------------- # enable support for Fortran 77 libraries AC_DEFUN([AC_LIBTOOL_F77], [AC_REQUIRE([_LT_AC_LANG_F77]) ])# AC_LIBTOOL_F77 # _LT_AC_LANG_F77 # --------------- AC_DEFUN([_LT_AC_LANG_F77], [AC_REQUIRE([AC_PROG_F77]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) ])# _LT_AC_LANG_F77 # AC_LIBTOOL_GCJ # -------------- # enable support for GCJ libraries AC_DEFUN([AC_LIBTOOL_GCJ], [AC_REQUIRE([_LT_AC_LANG_GCJ]) ])# AC_LIBTOOL_GCJ # _LT_AC_LANG_GCJ # --------------- AC_DEFUN([_LT_AC_LANG_GCJ], [AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) ])# _LT_AC_LANG_GCJ # AC_LIBTOOL_RC # -------------- # enable support for Windows resource files AC_DEFUN([AC_LIBTOOL_RC], [AC_REQUIRE([LT_AC_PROG_RC]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) ])# AC_LIBTOOL_RC # AC_LIBTOOL_LANG_C_CONFIG # ------------------------ # Ensure that the configuration vars for the C compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) AC_DEFUN([_LT_AC_LANG_C_CONFIG], [lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}\n' _LT_AC_SYS_COMPILER # # Check for any special shared library compilation flags. # _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= if test "$GCC" = no; then case $host_os in sco3.2v5*) _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' ;; esac fi if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$]_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[[ ]]" >/dev/null; then : else AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no fi fi # # Check to make sure the static flag actually works. # AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), [], [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) AC_LIBTOOL_PROG_CC_C_O($1) AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) AC_LIBTOOL_SYS_LIB_STRIP AC_LIBTOOL_DLOPEN_SELF($1) # Report which librarie types wil actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case "$host_os" in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; darwin* | rhapsody*) if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no case "$host_os" in rhapsody* | darwin1.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' ;; 10.*) allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' ;; esac fi ;; esac output_verbose_link_cmd='echo' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) AC_LIBTOOL_CONFIG($1) AC_LANG_POP CC="$lt_save_CC" ])# AC_LIBTOOL_LANG_C_CONFIG # AC_LIBTOOL_LANG_CXX_CONFIG # -------------------------- # Ensure that the configuration vars for the C compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], [AC_LANG_PUSH(C++) AC_REQUIRE([AC_PROG_CXX]) AC_REQUIRE([AC_PROG_CXXCPP]) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(allow_undefined_flag, $1)= _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(archive_expsym_cmds, $1)= _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= _LT_AC_TAGVAR(hardcode_minus_L, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=no _LT_AC_TAGVAR(module_cmds, $1)= _LT_AC_TAGVAR(module_expsym_cmds, $1)= _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown _LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_AC_TAGVAR(no_undefined_flag, $1)= _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Dependencies to place before and after the object being linked: _LT_AC_TAGVAR(predep_objects, $1)= _LT_AC_TAGVAR(postdep_objects, $1)= _LT_AC_TAGVAR(predeps, $1)= _LT_AC_TAGVAR(postdeps, $1)= _LT_AC_TAGVAR(compiler_lib_search_path, $1)= # Source file extension for C++ test sources. ac_ext=cc # Object file extension for compiled C++ test sources. objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_AC_TAGVAR(compiler, $1)=$CC cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` # We don't want -fno-exception wen compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration AC_PROG_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ grep 'no-whole-archive' > /dev/null; then _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_AC_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # KDE requires run time linking. Make it the default. aix_use_runtimelinking=yes exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_AC_TAGVAR(archive_cmds, $1)='' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=yes else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='-qmkshrobj ${wl}-G' else shared_flag='-qmkshrobj' fi fi fi # Let the compiler handle the export list. _LT_AC_TAGVAR(always_export_symbols, $1)=no if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_AC_TAGVAR(archive_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '" $shared_flag" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # -bexpall does not export symbols beginning with underscore (_) _LT_AC_TAGVAR(always_export_symbols, $1)=yes # Exported symbols can be pulled into shared objects from archives _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds it's shared libraries. _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(allow_undefined_flag, $1)=no _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) if test "$GXX" = yes; then _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no case "$host_os" in rhapsody* | darwin1.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' ;; 10.*) allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' ;; esac fi ;; esac lt_int_apple_cc_single_mod=no output_verbose_link_cmd='echo' if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then lt_int_apple_cc_single_mod=yes fi if test "X$lt_int_apple_cc_single_mod" = Xyes ; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring' fi _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's if test "X$lt_int_apple_cc_single_mod" = Xyes ; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' fi _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; dgux*) case $cc_basename in ec++) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; ghcx) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[12]*) # C++ shared libraries reported to be fairly broken before switch to ELF _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_AC_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aCC) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then case "$host_cpu" in hppa*64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; ia64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; *) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case "$host_cpu" in hppa*64*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; ia64*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; *) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aCC) case "$host_cpu" in hppa*64*|ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case "$host_cpu" in ia64*|hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects' ;; esac fi else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; irix5* | irix6*) case $cc_basename in CC) # SGI C++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' fi fi _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; linux*) case $cc_basename in KCC) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib; mv \$templib $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc) # Intel C++ with_gnu_ld=yes _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; cxx) # Compaq C++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; osf3*) case $cc_basename in KCC) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib; mv \$templib $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; RCC) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; cxx) _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; osf4* | osf5*) case $cc_basename in KCC) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects --soname $soname -o \$templib; mv \$templib $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; RCC) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; cxx) _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ $rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; sco*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no case $cc_basename in CC) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; sunos4*) case $cc_basename in CC) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; lcc) # Lucid # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC) # Sun C++ 4.2, 5.x and Centerline C++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~$rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The C++ compiler is used as linker so we must use $wl # flag to pass the commands to the underlying system # linker. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx) # Green Hills C++ Compiler _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | grep -v '^2\.7' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-h $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects ${wl}-h $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $compiler_flags $predep_objects $libobjs $deplibs $postdep_objects~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' fi ;; esac ;; sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; tandem*) case $cc_basename in NCC) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_AC_TAGVAR(GCC, $1)="$GXX" _LT_AC_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... AC_LIBTOOL_POSTDEP_PREDEP($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) AC_LIBTOOL_PROG_CC_C_O($1) AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) AC_LIBTOOL_SYS_LIB_STRIP AC_LIBTOOL_DLOPEN_SELF($1) AC_LIBTOOL_CONFIG($1) AC_LANG_POP CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ldcxx=$with_gnu_ld with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ])# AC_LIBTOOL_LANG_CXX_CONFIG # AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) # ------------------------ # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" ifelse([$1], [], [#! $SHELL # `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: # Originally by Gordon Matzigkeit , 1996 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="$SED -e s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi # The names of the tagged configurations supported by this script. available_tags= # ### BEGIN LIBTOOL CONFIG], [# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # A language-specific compiler. CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) # Is the compiler the GNU C compiler? with_gcc=$_LT_AC_TAGVAR(GCC, $1) # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_[]_LT_AC_TAGVAR(LD, $1) # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext='$shrext' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) # Must we lock files when doing compilation ? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) # Commands used to build and install a shared archive. archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) # Flag that forces no undefined symbols. no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" # Set to yes if exported symbols are required. always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) # The commands to list exported symbols. export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) # Symbols that must always be exported. include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) ifelse([$1],[], [# ### END LIBTOOL CONFIG], [# ### END LIBTOOL TAG CONFIG: $tagname]) __EOF__ ifelse([$1],[], [ case $host_os in aix3*) cat <<\EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi EOF ;; esac # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || \ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ]) else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. test -f Makefile && make "$ltmain" fi ])# AC_LIBTOOL_CONFIG # AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------------------- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi ])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE # --------------------------------- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_NM]) AC_REQUIRE([AC_OBJEXT]) # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Transform the above into a raw symbol and a C symbol. symxfrm='\1 \2\3 \3' # Transform an extracted symbol line into a proper C declaration lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32*) symcode='[[ABCDGISTW]]' ;; hpux*) # Its linker distinguishes data from code symbols if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris* | sysv5*) symcode='[[BDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGISTW]]' ;; esac # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do # Write the raw and C identifiers. lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if grep ' nm_test_var$' "$nlist" >/dev/null; then if grep ' nm_test_func$' "$nlist" >/dev/null; then cat < conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' cat <> conftest.$ac_ext #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[[]] = { EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext cat <<\EOF >> conftest.$ac_ext {0, (lt_ptr_t) 0} }; #ifdef __cplusplus } #endif EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -f conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi ]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE # AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) # --------------------------------------- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], [_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) ifelse([$1],[CXX],[ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case "$host_cpu" in hppa*64*|ia64*) ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix4* | aix5*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68) # Green Hills C++ Compiler # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx) # Green Hills C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" case "$host_cpu" in hppa*64*|ia64*) # +Z the default ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux*) case $cc_basename in KCC) # KAI C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; icpc) # Intel C++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; cxx) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; osf3* | osf4* | osf5*) case $cc_basename in KCC) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC) # Rational C++ 2.4.1 _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx) # Digital/Compaq C++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; sco*) case $cc_basename in CC) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; *) ;; esac ;; solaris*) case $cc_basename in CC) # Sun C++ 4.2, 5.x and Centerline C++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx) # Green Hills C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC) # Sun C++ 4.x _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc) # Lucid _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; tandem*) case $cc_basename in NCC) # NonStop-UX NCC 3.20 _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; unixware*) ;; vxworks*) ;; *) _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case "$host_cpu" in hppa*64*|ia64*) # +Z the default ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case "$host_cpu" in hppa*64*|ia64*) # +Z the default ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; newsos6) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; linux*) case $CC in icc* | ecc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; ccc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; sco3.2v5*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' ;; solaris*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sunos4*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; uts4*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi case "$host_os" in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" ;; esac ]) # AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) # ------------------------------------ # See if the linker supports building shared libraries. AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ifelse([$1],[CXX],[ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix4* | aix5*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' else _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw*) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' ;; *) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ],[ runpath_var= _LT_AC_TAGVAR(allow_undefined_flag, $1)= _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_AC_TAGVAR(archive_cmds, $1)= _LT_AC_TAGVAR(archive_expsym_cmds, $1)= _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_minus_L, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown _LT_AC_TAGVAR(hardcode_automatic, $1)=no _LT_AC_TAGVAR(module_cmds, $1)= _LT_AC_TAGVAR(module_expsym_cmds, $1)= _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_AC_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; openbsd*) with_gnu_ld=no ;; esac _LT_AC_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(allow_undefined_flag, $1)=no _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $compiler_flags $libobjs $deplibs -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris* | sysv5*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; sunos4*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then runpath_var=LD_RUN_PATH _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= fi fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=yes _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$link_static_flag"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' else _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' fi # KDE requires run time linking. Make it the default. aix_use_runtimelinking=yes exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_AC_TAGVAR(archive_cmds, $1)='' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=yes else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='-qmkshrobj ${wl}-G' else shared_flag='-qmkshrobj' fi fi fi # Let the compiler handle the export list. _LT_AC_TAGVAR(always_export_symbols, $1)=no if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_AC_TAGVAR(archive_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '" $shared_flag" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # -bexpall does not export symbols beginning with underscore (_) _LT_AC_TAGVAR(always_export_symbols, $1)=yes # Exported symbols can be pulled into shared objects from archives _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds it's shared libraries. _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $compiler_flags $libobjs $deplibs ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # see comment about different semantics on the GNU ld section _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; bsdi4*) _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_AC_TAGVAR(allow_undefined_flag, $1)=no # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext=".dll" # FIXME: Setting linknames here is a bad hack. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $compiler_flags $libobjs `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) if test "$GXX" = yes ; then _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no case "$host_os" in rhapsody* | darwin1.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' ;; 10.*) allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' ;; esac fi ;; esac lt_int_apple_cc_single_mod=no output_verbose_link_cmd='echo' if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then lt_int_apple_cc_single_mod=yes fi if test "X$lt_int_apple_cc_single_mod" = Xyes ; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring' fi _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's if test "X$lt_int_apple_cc_single_mod" = Xyes ; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $compiler_flags $libobjs $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $compiler_flags $deplibs -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' fi _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $compiler_flags $libobjs $deplibs~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; dgux*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $compiler_flags $libobjs $deplibs' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $compiler_flags $libobjs $deplibs~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10* | hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case "$host_cpu" in hppa*64*|ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $compiler_flags $libobjs $deplibs' ;; esac else case "$host_cpu" in hppa*64*|ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; esac fi if test "$with_gnu_ld" = no; then case "$host_cpu" in hppa*64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; ia64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ;; *) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $compiler_flags $libobjs $deplibs ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; openbsd*) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $compiler_flags $libobjs $deplibs' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $compiler_flags $libobjs $deplibs' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi ;; os2*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $compiler_flags $libobjs $deplibs$output_objdir/$libname.def' _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $libobjs $deplibs ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $compiler_flags $libobjs $deplibs ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; sco3.2v5*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ;; solaris*) _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs~$rm $lib.exp' else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $compiler_flags $libobjs $deplibs' else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_AC_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_AC_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4.2uw2*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no hardcode_runpath_var=yes runpath_var=LD_RUN_PATH ;; sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $compiler_flags $libobjs $deplibs' fi runpath_var='LD_RUN_PATH' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv5*) _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' # $CC -shared without GNU ld will not create a library from C++ # object files and a static libstdc++, better avoid it by now _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' ;; uts4*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac fi ]) AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi # # Do we need to explicitly link libc? # case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_AC_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) _LT_AC_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) then _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac ])# AC_LIBTOOL_PROG_LD_SHLIBS # _LT_AC_FILE_LTDLL_C # ------------------- # Be careful that the start marker always follows a newline. AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ # /* ltdll.c starts here */ # #define WIN32_LEAN_AND_MEAN # #include # #undef WIN32_LEAN_AND_MEAN # #include # # #ifndef __CYGWIN__ # # ifdef __CYGWIN32__ # # define __CYGWIN__ __CYGWIN32__ # # endif # #endif # # #ifdef __cplusplus # extern "C" { # #endif # BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); # #ifdef __cplusplus # } # #endif # # #ifdef __CYGWIN__ # #include # DECLARE_CYGWIN_DLL( DllMain ); # #endif # HINSTANCE __hDllInstance_base; # # BOOL APIENTRY # DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) # { # __hDllInstance_base = hInst; # return TRUE; # } # /* ltdll.c ends here */ ])# _LT_AC_FILE_LTDLL_C # _LT_AC_TAGVAR(VARNAME, [TAGNAME]) # --------------------------------- AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) # old names AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) # This is just to silence aclocal about the macro not being used ifelse([AC_DISABLE_FAST_INSTALL]) AC_DEFUN([LT_AC_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj, no) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS) ]) AC_DEFUN([LT_AC_PROG_RC], [AC_CHECK_TOOL(RC, windres, no) ]) ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ # LT_AC_PROG_SED # -------------- # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. AC_DEFUN([LT_AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && break cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_MSG_RESULT([$SED]) ]) dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page dnl also defines GSTUFF_PKG_ERRORS on error AC_DEFUN([PKG_CHECK_MODULES], [ succeeded=no if test -z "$PKG_CONFIG"; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) fi if test "$PKG_CONFIG" = "no" ; then echo "*** The pkg-config script could not be found. Make sure it is" echo "*** in your path, or set the PKG_CONFIG environment variable" echo "*** to the full path to pkg-config." echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." else PKG_CONFIG_MIN_VERSION=0.9.0 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then AC_MSG_CHECKING(for $2) if $PKG_CONFIG --exists "$2" ; then AC_MSG_RESULT(yes) succeeded=yes AC_MSG_CHECKING($1_CFLAGS) $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` AC_MSG_RESULT($$1_CFLAGS) AC_MSG_CHECKING($1_LIBS) $1_LIBS=`$PKG_CONFIG --libs "$2"` AC_MSG_RESULT($$1_LIBS) else $1_CFLAGS="" $1_LIBS="" ## If we have a custom action on failure, don't print errors, but ## do set a variable so people can do so. $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` ifelse([$4], ,echo $$1_PKG_ERRORS,) fi AC_SUBST($1_CFLAGS) AC_SUBST($1_LIBS) else echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." echo "*** See http://www.freedesktop.org/software/pkgconfig" fi fi if test $succeeded = yes; then ifelse([$3], , :, [$3]) else ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) fi ]) dnl lrelease fix see https://bugzilla.novell.com/show_bug.cgi?id=327023 # Check for lrelease compress flag AC_DEFUN([ms_CHECK_LRELEASE], [ AC_MSG_CHECKING([LRELEASE OPTIONS]) if lrelease -compress /dev/null -qm /dev/null 1>/dev/null 2>&1 then AC_MSG_RESULT([compress]) LRELEASEOPTION="-compress" else AC_MSG_RESULT([nocompress]) LRELEASEOPTION="" fi AC_SUBST([LRELEASEOPTION]) ]) twinkle-1.4.2/AUTHORS0000644000175000001440000000202711135152724011162 00000000000000Author of Twinkle: Michel de Boer designed and implemented Twinkle. Contributions: * Werner Dittmann (ZRTP/SRTP) * Bogdan Harjoc (AKAv1-MD5, Service-Route) * Roman Imankulov (command line editing) * Ondrej Moris (codec preprocessing) * Rickard Petzall (ALSA) Twinkle contains the following 3rd party software packages: - GSM codec from Jutta Degener and Carsten Bormann see directory src/audio/gsm for more info - G.711/G.726 codec from Sun Microsystems see src/audio/README_G711 for more info - iLBC implementation from RFC 3951 (www.ilbcfreeware.org) - Parts of the STUN project from sourceforge http://sourceforge.net/projects/stun - Parts of libsrv at http://libsrv.sourceforge.net/ Dynamic linked libraries: - RTP, ZRTP and SRTP functionality is provided by the GNU ccRTP stack: http://www.gnu.org/software/ccrtp Translators: Czech Marek Straka Dutch Michel de Boer German Joerg Reisenweber French Olivier Aufrere Russian Michail Chodorenko Swedish Daniel Nylander Michel de Boer www.twinklephone.com twinkle-1.4.2/INSTALL0000644000175000001440000002243211151323411011134 00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Here is a another example: /bin/bash ./configure CONFIG_SHELL=/bin/bash Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent configuration-related scripts to be executed by `/bin/bash'. `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. twinkle-1.4.2/twinkle.spec.in0000644000175000001440000000330411150245462013046 00000000000000Summary: A SIP Soft Phone Name: twinkle Version: @VERSION@ Release: %{suserel}1 License: GPL Group: Productivity/Telephony/SIP/Clients Source: %{name}-%{version}.tar.gz Prefix: %{_prefix} BuildArch: i586 #BuildArch: x86_64 BuildRoot: %{_tmppath}/making_of_%{name}_%{version} Packager: URL: http://www.twinklephone.com Requires: alsa Requires: commoncpp2 >= 1.6.0 Requires: ccrtp >= 1.6.0 Requires: libzrtpcpp >= 1.3.0 Requires: kdelibs3 >= 3.2.0 Requires: libsndfile Requires: libspeex >= 1.1.99 Requires: libxml2 Requires: file Requires: readline BuildRequires: alsa-devel BuildRequires: qt3-devel BuildRequires: update-desktop-files BuildRequires: commoncpp2-devel BuildRequires: libccrtp-devel BuildRequires: libzrtpcpp-devel BuildRequires: kdelibs3-devel BuildRequires: libsndfile-devel BuildRequires: speex-devel BuildRequires: boost-devel BuildRequires: libxml2-devel BuildRequires: file-devel BuildRequires: readline-devel %description Twinkle is a SIP based softphone for making telephone calls and instant messaging over IP networks. %prep %setup -q %build autoreconf -fi %configure --without-ilbc #%configure --without-ilbc --enable-libsuffix=64 #sed -i -e "s|(INCPATH *= \)|\1-I/opt/kde3/include |" src/gui/Makefile make %install rm -rf %{buildroot} %makeinstall install -d 755 %{buildroot}%{_datadir}/pixmaps install -m 644 src/gui/images/twinkle48.png %{buildroot}%{_datadir}/pixmaps/twinkle.png %suse_update_desktop_file -c twinkle Twinkle "A SIP softphone" twinkle twinkle Network Telephony %clean rm -rf %{buildroot} %files %defattr(-, root, root) %doc AUTHORS COPYING README ChangeLog %{_bindir}/%{name} %{_datadir}/%{name} %{_datadir}/pixmaps/twinkle.png %{_datadir}/applications/twinkle.desktop twinkle-1.4.2/ChangeLog0000644000175000001440000007616511151327562011704 0000000000000025 february 2009 - 1.4.2 ======================== - Integration with Diamondcard Worldwide Communication Service (worldwide calls to regular and cell phones and SMS). - Show number of calls and total call duration in call history. - Show message size while typing an instant message. - Show "referred by" party for an incoming transferred call in systray popup. - Option to allow call transfer while consultation call is still in progress. - Improved lock file checking. No more stale lock files. Bug fixes: ---------- - Opening an IM attachment did not work anymore. Build fixes: ------------ - Link with ncurses library 31 january 2009 - 1.4.1 ======================= Bug fixes: ---------- - No sound when Twinkle is compiled without speex support. Build fixes: ------------ - Compiling without KDE sometimes failed (cannot find -lqt-mt). - Configure script did not correctly check for the readline-devel package. 25 january 2009 - 1.4 ===================== - Service route discovery during registration. - Codec preprocessing: automatic gain control, voice activation detection, noise reduction, acoustic echo cancellation (experimental). - Support tel-URI as destination address for a call or instant message. - User profile option to expand a telephone number to a tel-URI instead of a sip-URI. - Add descending q-value to contacts in 3XX responses for the redirection services. - AKAv1-MD5 authentication. - Command line editing, history, auto-completion. - Ignore wrong formatted domain-parameter in digest challenge. - Match tel-URI in incoming call to address book. - Determine RTP IP address for SDP answer from RTP IP address in SDP offer. - Show context menu's when pressing the right mouse button instead of after clicking. - Swedish translation - Resampled ringback tone from 8287 Hz to 8000 Hz Bug fixes --------- - Text line edit in the message form looses focus after sending an IM. - Twinkle does not escape reserved symbols when dialing. - Deregister all function causes a crash. - Twinkle crashes at startup in CLI mode. - Twinkle may freeze when an ALSA error is detected when starting the ringback tone and the outgoing call gets answered very fast. - User profile editor did not allow spaces in a user name. New RFC's --------- RFC 3608 - Session Initiation Protocol (SIP) Extension Header Field for Service Route Discovery During Registration 24 august 2008 - 1.3.2 ====================== - Fix in non-KDE version for gcc 4.3 23 august 2008 - 1.3.1 ====================== - Disable file attachment button in message window when destination address is not filled in - Updated russian translation Build fixes ----------- - Fixes for gcc 4.3 (missing includes) - non-KDE version failed to build 18 august 2008 - 1.3 ==================== - Send file attachment with instant message. - Show timestamp with instant messages. - Instant message composition indication (RFC 3994). - Persistent TCP connections with keep alive. - Do not try to send SIP messages larger than 64K via UDP. - Integration with libzrtcpp-1.3.0 - Xsession support to restore Twinkle after system shutdown/startup. - Call snd_pcm_state to determine jitter buffer exhaustion (some ALSA implementations gave problems with the old method). - SDP parser allows SDP body without terminating CRLF. - Russian translation. Bug fixes --------- - SIP parser did not allow white space between header name and colon. - With "send in-dialog requests to proxy" enabled and transport mode set to "auto", in-dialog requests are wrongly sent via TCP. - Crash when a too large message is received. - Comparison of authentication parameters (e.g. algorithm) were case-sensitive. These comparisons must be case-insensitive. - SDP parser could not parse other media transports than RTP/AVP. - Twinkle sent 415 response instead of 200 OK on in-dialog INFO without body. - Twinkle responds with 513 Message too large on an incoming call. - ICMP error on STUN request causes Twinkle to crash. - Add received-parameter to Via header of an incoming request if it contains an empty rport parameter (RFC 3581) - Twinkle did not add Contact header and copy Record-Route header to 180 response. New RFC's --------- RFC 3994 - Indication of Message Composition for Instant Messaging 8 march 2008 - 1.2 ================== - SIP over TCP - Automatic selection of IP address. * On a multi-homed machine you do not have to select an IP address/NIC anymore. - Support for sending a q-value in a registration contact. - Send DTMF on an early media stream. - Choose auth over auth-int qop when server supports both for authentication. This avoids problems with SIP ALGs. - Support tel-URI in From and To headers in incoming SIP messages. - Print a log rotation message at end of log when a log file is full. - Remove 20 character limit on profile names. - Reject an incoming MESSAGE with 603 if max. sessions == 0 - Delivery notification when a 202 response is received on a MESSAGE. Bug fixes --------- - When you deactivate a profile that has MWI active, but MWI subscription failed, and subsequently activate this profile again, then Twinkle does not subscribe to MWI. - The max redirection value was always set to 1. - Leading space in the body of a SIP message causes a parse failure - Twinkle crashes with SIGABRT when it receives an INVITE with a CSeq header that contains an invalid method. - Latest release of lrelease corrupted translation files. - Twinkle crashes on 'twinkle --cmd line' - If an MWI NOTIFY does not contain a voice msg summary, twinkle shows a random number for the amount of messages waiting. - Depending on the locale Twinkle encoded a q-value with a comma instead of a dot as decimal point. Build changes ------------- - Modifications for gcc 4.3. - Remove fast sequence of open/close calls for ALSA to avoid problems with bluez. 21 july 2007 - 1.1 ================== - French translation - Presence - Instant messaging - New CLI commands: presence, message Bug fixes --------- - If a session was on-hold and Twinkle received a re-INVITE without SDP, it would offer SDP on-hold in the 200 OK, instead of a brand new SDP offer. - Twinkle refused to change to another profile with the same user name as the current active profile. - ICMP processing did not work most times (uninitialized data). - Replace strerror by strerror_r (caused rare SIGSEGV crashes) - Fix deadlock in timekeeper (caused rare freezes) New RFC's --------- RFC 3428 - Session Initiation Protocol (SIP) Extension for Instant Messaging RFC 3856 - A Presence Event Package for the Session Initiation Protocol (SIP) RFC 3863 - Presence Information Data Format (PIDF) RFC 3903 - Session Initiation Protocol (SIP) Extension for Event State Publication 19 may 2007 - 1.0.1 =================== - Czech translation - Check on user profiles having the same contact name at startup. - When comparing an incoming INVITE request-URI with the contact-name, ignore the host part to avoid NAT problems. - A call to voice mail will not be attached to the "redial" button. - Added voice mail entry to services and systray menu. - New command line options: --show, --hide - TWINKLE_LINE environment variable in scripts. This variable contains the line number (starting at 1) associated with a trigger. - Preload KAddressbook at startup. - Allow multiple occurrences of the display_msg parameter in the incoming call script to create multi-line messages. - Handle SIP forking and early media interaction Bug fixes --------- - Fix conference call - If lock file still exists when you start Twinkle, Twinkle asks if it should start anyway. When you click 'yes', Twinkle does not start. - Audio validation opened soundcard in stereo instead of mono - When quitting Twinkle while the call history window is open, a segfault occurs - When an incoming call is rejected when only unsupported codecs are offered, it does not show as a missed call in the call history. - Segfault when the remote party establishes an early media session without sending a to-tag in the 1XX response (some Cisco devices). - in_call_failed trigger was not called when the call failed before ringing. - Escape double quote with backslash in display name. - On some system Twinkle occasionally crashed at startup with the following error: Xlib: unexpected async reply Build Changes ------------- - Remove AC_CHECK_HEADERS([]) from configure.in - Configure checks for lrelease. Other ----- - Very small part of the comments has been formatted now for automatic documentation generation with doxygen. 22 jan 2007 - 1.0 ================= - Local address book - Message waiting indication (MWI) * Sollicted MWI as specified by RFC 3842 * Unsollicited MWI as implemented by Asterisk - Voice mail speed dial - Call transfer with consultation * This is a combination of a consultation call on the other line followed by a blind transfer. - Attended call transfer * This is a combination of a consultation call on the other line followed by a replacement from B to C of the call on the first line. This is only possible if the C-party supports "replaces". If "replaces" is not supported, then twinkle automatically falls back to "transfer with consultation". - User identity hiding - Multi language support This version contains Dutch and German translations - Send BYE when a CANCEL/2XX INVITE glare occurs. - When call release was not immediate due to network problems or protocol errors, the line would be locked for some time. Now Twinkle releases a call in the background immediately freeing the line for new calls. - Escape reserved symbols in a URI by their hex-notation (%hex). - Changed key binding for Bye from F7 to ESC - When a lock file exists at startup, Twinkle asks if you want to override it - New command line options: --force, --sip-port, --rtp-port - Ring tone and speaker device list now also shows playback only devices - Microphone device list now also shows capture only devices - Validate audio device settings on startup, before making a call, before answering a call. - SIP_FROM_USER, SIP_FROM_HOST, SIP_TO_USER, SIP_TO_HOST variables for call scripts. - display_msg parameter added to incoming call script - User profile options to indicate which codec preference to follow - Twinkle now asks permission for an incoming REFER asynchronously. This prevents blocking of the transaction layer. - Highlight missed calls in call history - Support for G.726 ATM AAL2 codeword packing - replaces SIP extension (RFC 3891) - norefesub SIP extension (RFC 4488) - SIP parser supports IPv6 addresses in SIP URI's and Via headers (Note: Twinkle does not support transport over IPv6) - Support mid-call change of SSRC - Handling of SIGCHLD, SIGTERM and SIGINT on platforms implementing LinuxThreads instead of NPTL threading (e.g. sparc) Bug fixes --------- - Invalid speex payload when setting ptime=30 for G.711 - When editing the active user profile via File -> Change User -> Edit QObject::connect: No such slot MphoneForm::displayUser(t_user*) - 32 s after call setup the DTMF button gets disabled. - 4XX response on INVITE does not get properly handled. From/To/Subject labels are not cleared. No call history record is made. - The dial combobox accepted a newline through copy/past. This corrupted the system settings. - When a far-end responds with no supported codecs, Twinkle automatically releases the call. If the far-end sends an invalid response on this release and the user pressed the BYE button, Twinkle crashed. - When using STUN the private port was put in the Via header instead of the public port. - Twinkle crashes once in a while, while it is just sitting idle. Build changes ------------- - If libbind exists then link with libbind, otherwise link with libresolv This solves GLIBC_PRIVATE errors on Fedora - Link with libboost_regex or libboost_regex-gcc New RFC's --------- RFC 3323 - A Privacy Mechanism for the Session Initiation Protocol (SIP) RFC 3325 - Private Extensions to the Session Initiation Protocol (SIP) for Asserted Identity within Trusted Networks RFC 3842 - A Message Summary and Message Waiting Indication Event Package for the Session Initiation Protocol (SIP) RFC 3891 - The Session Initiation Protocol (SIP) "Replaces" Header RFC 4488 - Suppression of Session Initiation Protocol (SIP) REFER Method Implicit Subscription 01 oct 2006 - Release 0.9 ========================= - Supports Phil Zimmermann's ZRTP and SRTP for secure voice communication. ZRTP/SRTP is provided by the latest version (1.5.0) of the GNU ccRTP library. The implementation is interoperable with Zfone beta2 - SIP INFO method (RFC 2976) - DTMF via SIP INFO - G.726 codec (16, 24, 32 and 48 kbps modes) - Option to hide display - CLI command "answerbye" to answer an incoming or hangup an established call - Switch lines from system tray menu - Answer or reject a call from the KDE systray popup on incoming call - Icons to indicate line status - Default NIC option in system settings - Accept SDP offer without m= lines (RFC 3264 section 5, RFC 3725 flow IV) Bug fixes --------- - t_audio::open did not return a value - segmentation fault when quitting Twinkle in transient call state - Twinkle did not accept message/sipfrag body with a single CRLF at the end - user profile could not be changed on service redirect dialog - Twinkle did not react to 401/407 authentication challenges for PRACK, REFER, SUBSCRIBE and NOTIFY Build changes ------------- - For ZRTP support you need to install libzrtpcpp first. This library comes as an extension library with ccRTP. 09 jul 2006 - Release 0.8.1 =========================== - Removed iLBC source code from Twinkle. To use iLBC you can link Twinkle with the ilbc library (ilbc package). When you have the ilbc library installed on your system, then Twinkle's configure script will automatically setup the Makefiles to link with the library. Bug fixes --------- - Name and photo lookups in KAddressbook on incoming calls may freeze Twinkle. Build improvements ------------------ - Added missing includes to userprofile.ui and addressfinder.h - Configure has new --without-speex option 01 jul 2006 - Release 0.8 ========================= - iLBC - Make supplementary service settings persistent - Lookup name in address book for incoming call - Display photo from address book of caller on incoming call - Number conversion rules - Always popup systray notification (KDE only) on incoming call - Add organization and subject to incoming call popup - New call script trigger points: incoming call answered, incoming call failed, outgoing call, outgoing call answered, outgoing call failed, local release, remote release. - Added 'end' parameter for the incoming call script - Option to provision ALSA and OSS devices that are not in the standard list of devices. - Option to auto show main window on incoming call - Resized the user profile window such that it fits on an 800x600 display - Popup the user profile selection window, when the SIP UDP port is occupied during startup of Twinkle, so the user can change to another port. - Skip unsupported codecs in user profile during startup Bug fixes --------- - Sometimes the NAT discovery window never closed - When RTP timestamps wrap around some RTP packets may be discarded - When the dial history contains an entry of insane length, the main window becomes insanely large on next startup - On rare occasions, Twinkle could respond to an incoming call for a deactivated user profile. - Credentials cache did not get erased when a failure response other than 401/407 was received on a REGISTER with credentials. - G.711 enocders amplified soft noise from the microphone. Newly supported RFC's --------------------- RFC 3951 - Internet Low Bit Rate Codec (iLBC) RFC 3952 - Real-time Transport Protocol (RTP) Payload Format for internet Low Bit Rate Codec (iLBC) Speech Build notes ----------- - New dependency on libboost-regex (boost package) 07 may 2006 - Release 0.7.1 =========================== - Check that --call and --cmd arguments are not empty - When DTMF transport is "inband", then do not signal RFC2833 support in SDP Bug fixes --------- - CLI and non-KDE version hang when stopping ring tone - The GUI allowed payload type 96-255 for DTMF and Speex, while maximum value is only 127 - When a dynamic codec change takes place at the same time as a re-INVITE Twinkle sometimes freezes. - Sending RFC 2833 DTMF events fails when codec is speex-wb or speex-uwb 29 apr 2006 - Release 0.7 ========================= - Speex support (narrow, wide and ultra wide band) - Support for dynamic payload numbers for audio codecs in SDP - Inband DTMF (option for DTMF transport in user profile) - UTF-8 support to properly display non-ASCII characters - --cmd command line option to remotely execute CLI commands - --immediate command line option to perform --call and --cmd without user confirmation. - --set-profile command line option to set the active profile. - Support "?subject=" as part of address for --call - The status icon are always displayed: gray -> inactive, full color -> active - Clicking the registration status icon fetches current registration status - Clicking the service icons enables/disables the service - Fancier popup from KDE system tray on incoming call. - Popup from system tray shows as long as the phone is ringing. - Reload button on address form - Remove special phone number symbols from dialed strings. This option can be enabled/disabled via the user profile. - Remove duplicate entries from the dial history drop down box - Specify in the user profile what symbols are special symbols to remove. - Changed default for "use domain to create unique contact header value" to "no" - New SIP protocol option: allow SDP change in INVITE responses - Do not ask username and password when authentication for an automatic re-regsitration fails. The user may not be at his desk, and the authentication dialog stalls Twinkle. - Ask authentication password when user profile contains authentication name, but no password. - Improved handling of socket errors when interface goes down temporarily. Bug fixes --------- - If the far end holds a call and then resumes a call while Twinkle has been put locally on-hold, then Twinkle will start recording sound from the mic and send it to the far-end while indicating that the call is still on-hold. - Crash on no-op SDP in re-INVITE - Twinkle exits when it receives SIGSTOP followed by SIGCONT - call release cause in history is incorrect for incoming calls. Build improvements ------------------ - Break dependency on X11/xpm.h 26 feb 2006 - Release 0.6.2 =========================== - Graceful termination on reception of SIGINT and SIGTERM Bug fixes --------- - If the URI in a received To-header is not enclosed by '<' and '>', then the tag parameter is erronesouly parsed as a URI parameter instead of a header parameter. This causes failing call setup, tear down, when communicating with a far-end that does not enclose the URI in angle brackets in the To-header. - Function to flush OSS buffers flushed a random amount of samples that could cause sound clipping (at start of call and after call hold) when using OSS. - In some cases Twinkle added "user=phone" to a URI when the URI already had a user parameter. 11 feb 2006 - Release 0.6.1 =========================== - action=autoanswer added to call script actions - Performance improvement of --call parameter - Synchronized dial history drop downs on main window and call dialog - Dial history drop down lists are stored persistently - Redial information is stored persistently Bug fixes --------- - When using STUN Twinkle freezes when making a call and the STUN server does not respond within 200 ms (since version 0.2) - Some malformed SIP messages triggered a memory leak in the parser code generated by bison (since version 0.1) - The lexical scanner jammed on rubbish input (since version 0.1) 05 feb 2006 - Release 0.6 ========================= - Custom ring tones (package libsndfile is needed) - Twinkle can call a user defineable script for each incoming call. With this script the user can: * reject, redirect or accept a call * define a specific ring tone (distinctive ringing) - Missed call indication - Call directly from the main window - DTMF keys can by typed directly from the keyboard at the main window. Letters are converted to the corresponding digits. - Letters can be typed in the DTMF window. They are converted to digits. - Call duration in call history - Call duration timer while call is established - Added --call parameter to command line to instruct Twinkle to make a call - Increased expiry timer for outgoing RTP packets to 160 ms With this setting slow sound cards should give better sound quality for the mic. - System setting to disable call waiting. - System setting to modify hangup behaviour of 3-way call. Hang up both lines or only the active line. - Replace dots with underscores in contact value - Silently discard packets on the SIP port smaller than 10 bytes - User profile option to disable the usage of the domain name in the contact header. - Graceful release of calls when quitting Twinkle - Changed call hold default from RFC2543 to RFC3264 Bug fixes --------- - An '=' in a value of a user profile or system settings parameter caused a syntax error - If a default startup profile was renamed, the default startup list was not updated - When call was put on-hold using RFC2543 method, the host in the SDP o= line was erroneously set to 0.0.0.0 - When a response with wrong tags but correct branch was received, a line would hang forever (RFC 3261 did not specify this scenario). - If far end responds with 200 OK to CANCEL, but never sends 487 on INVITE as mandated by RFC 3261, then a line would hang forever - CPU load was sometimes excessive when using ALSA 01 jan 2006 - Release 0.5 ========================= - Run multiple user profiles in parallel - Add/remove users while Twinkle is running - The SIP UDP port and RTP port settings have been moved from the user profile to system settings. Changes of the default values in the user profile will be lost. - DNS SRV support for SIP and STUN - ICMP processing - SIP failover on 503 response - SIP and STUN failover on ICMP error - When a call is originated from the call history, copy the subject to the call window (prefixed with "Re:" when replying to a call). - Remove '/' from a phone number taken from KAddressbook. / is used in Germany to separate the area code from the local number. - Queue incoming in-dialog request if ACK has not been received yet. - Clear credentials cache when user changes realm, username or password - Added micro seconds to timestamps in log - Detecting a soundcard playing out at slightly less than 8000 samples per second is now done on the RTP queue status. This seems to be more reliable than checking the ALSA sound buffer filling. - OSS fragment size and ALSA period size are now changeable via the system settings. Some soundcard problems may be solved by changing these values. - Default ALSA period size for capturing lowered from 128 to 32. This seems to give better performance on some sound cards. Bug fixes --------- - With certain ALSA settings (eg. mic=default, speaker=plughw), the ALSA device got locked up after 1 call. - The ports used for NAT discovery via STUN stayed open. - When a STUN transaction for a media port failed, the GUI did not clear the line information fields. - Sending DTMF events took many unnecessary CPU cycles - Parse failure when Server or User-Agent header contained comment only Newly supported RFC's --------------------- RFC 2782 - A DNS RR for specifying the location of services (DNS SRV) RFC 3263 - Session Initiation Protocol (SIP): Locating SIP Servers 28 nov 2005 - Release 0.4.2 =========================== - Microphone noise reduction (can be disabled in system settings) - System tray icon shows status of active line and enabled services - Call history option added to system tray menu Bug fixes --------- - Twinkle crashes at startup when the systray icon is disabled in the system settings. - Line stays forever in dialing state when pressing ESC in the call window 19 nov 2005 - Release 0.4.1 =========================== - Fixed build problems with gcc-4.0.2 and qt3-3.4.4 18 nov 2005 - Release 0.4 ========================= - Interface to KAddressbook - History of incoming and outgoing calls (successful and missed calls) - History of 10 last calls on call dialog window for redialling - Call and service menu options added to KDE sys tray icon - Allow a missing mandatory Expires header in a 2XX response on SUBSCRIBE - Big Endian support for sound playing (eg. PPC platforms) - System setting to start Twinkle hidden in system tray - System setting to start with a default profile - System setting to start on a default IP address - Command line option (-i) for IP address Bug fixes --------- - send a 500 failure response on a request that is received out of order instead of discarding the request. - 64bit fix in events.cpp - race condition on starting/stopping audio threads could cause a crash - segmentation fault when RTP port could not be opened. - CLI looped forever on reaching EOF - 64bit fix in events.cpp - ALSA lib pcm_hw.c:590:(snd_pcm_hw_pause) SNDRV_PCM_IOCTL_PAUSE failed - sometimes when quitting Twinkle a segmentation fault occurred Build improvements ------------------ - Removed platform dependent code from stunRand() in stun.cxx - It should be possible to build Twinkle without the KDE addons on a non-KDE system - new option --without-kde added to configure to build a non-KDE version of Twinkle 22 oct 2005 - Release 0.3.2 =========================== - Fixed several build problams with KDE include files and libraries. If you already succesfully installed release 0.3.1 then there is no need to upgrade to 0.3.2 as there is no new functionality. 16 oct 2005 - Release 0.3.1 =========================== This is a minor bug fix release. Bug fixes: ---------- - Command line options -f and -share were broken in release 0.3 This release fixes the command line options. 09 oct 2005 - Release 0.3 ========================= New functionality: ------------------ - ALSA support - System tray icon - Send NAT keep alive packets when Twinkle sits behind a symmetric firewall (discovered via STUN) - Allow missing or wrong Contact header in a 200 OK response on a REGISTER Bug fixes: ---------- - Hostnames in Via and Warning headers were erroneously converted to lower case. - t_ts_non_invite::timeout assert( t==TIMER_J ) when ACK is received for a non-INVITE request that had INVITE as method in the CSeq header. - The SIP/SDP parser accepted a port number > 65535. This caused an assert - Segmentation fault on some syntax errors in SIP headers - Line got stuck when CSeq sequence nr 0 was received. RFC 3261 allows 0. - With 100rel required, every 1XX after the first 1XX response were discarded. - Fixed build problems on 64-bit architectures. - Dead lock due to logging in UDP sender. - Segmentation fault when packet loss occurred while the sequence number in the RTP packets wrapped around. - Route set was not recomputed on reception of a 2XX response, when a 1XX repsonse before already contained a Record-Route header. 30 jul 2005 - Release 0.2.1 =========================== New functionality: ------------------ - Clear button on log view window. Bug fixes: ---------- - The system settings window confused the speaker and mic settings. - Log view window sometimes opened behind other windows. - Segmentation fault when SUBSCRIBE with expires=0 was received to end a refer subscription. - When a call transfer fails, the original call is received. If the line for this call is not the active call however, the call should stay on-hold. - On rare occasions a segmentation fault occurred when the ring tone was stopped. - Log view window sometimes caused deadlock. 24 jul 2005 - Release 0.2 ========================= New functionality: ------------------ - STUN support for NAT traversal - Blind call transfer service - Reject call transfer request - Auto answer service - REFER, NOTIFY and SUBSCRIBE support for call transfer scenario's * REFER is sent for blind call transfer. Twinkle accpets incoming NOTIFY messages about the transfer progress. Twinkle can send SUBSCRIBE to extend refer event subscription * Incoming REFER within dialog is handled by Twinkle Twinkle sends NOTIFY messages during transfer. Incoming SUBSCRIBE to extend refer event subscription is granted. - Retry re-INVITE after a glare (491 response, RFC 3261 14.1) - Respond with 416 if a request with a non-sip URI is received - Multiple sound card support for playing ring tone to a different device than speech - The To-tag in a 200 OK on a CANCEL was different than the To-tag in a provisional response on the INVITE. RFC 3261 recommends that these To-tags are the same. Twinkle now uses the same To-tag. - Show error messages to user when trying to submit invalid values on the user profile - DTMF volume configurable via user profile - Log viewer - User profile wizard - Help texts for many input fields (e.g. in user profile). Help can be accessed by pressing Ctrl+F1 or using the question mark from the title bar. Bug fixes: ---------- - A retransmission of an incoming INVITE after a 2XX has been sent was seen as a new INVITE. - If an OPTIONS request timed out then the GUI did not release its lock causing a deadlock. - If the URI in a To, From, Contact or Reply-To header is not enclosed by < and >, then the parameters (separated by a semi-colon) belong to the header, NOT to the URI. They were parsed as parameters of the URI. This could cause the loss of a tag-parameter causing call setup failures. - Do not resize window when setting a long string in to, from or subject Newly supported RFC's --------------------- RFC 3265 - Session Initiation Protocol (SIP)-Specific Event Notification RFC 3420 - Internet Media Type message/sipfrag RFC 3489 - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs) RFC 3515 - The Session Initiation Protocol (SIP) Refer Method RFC 3892 - The Session Initiation Protocol (SIP) Referred-By Mechanism 27 apr 2005 - Release 0.1 ========================= First release of Twinkle, a SIP VoIP client. - Basic calls - 2 call appearances (lines) - Call Waiting - Call Hold - 3-way conference calling - Mute - Call redirection on demand - Call redirection unconditional - Call redirection when busy - Call redirection no answer - Reject call redirection request - Call reject - Do not disturb - Send DTMF digits to navigate IVR systems - NAT traversal through static provisioning - Audio codecs: G.711 A-law, G.711 u-law, GSM Supported RFC's --------------- - RFC 2327 - SDP: Session Description Protocol - RFC 2833 - RTP Payload for DTMF Digits - RFC 3261 - SIP: Session Initiation Protocol - RFC 3262 - Reliability of Provisional Responses in SIP - RFC 3264 - An Offer/Answer Model with the Session Description Protocol (SDP) - RFC 3581 - An extension to SIP for Symmetric Response Routing - RFC 3550 - RTP: A Transport Protocol for Real-Time Applications RFC 3261 is not fully implemented yet. - No TCP transport support, only UDP - No DNS SRV support, only DNS A-record lookup - Only plain SDP bodies are supported, no multi-part MIME or S/MIME - Only sip: URI support, no sips: URI support twinkle-1.4.2/COPYING0000644000175000001440000004311010503576750011152 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. twinkle-1.4.2/Doxyfile0000644000175000001440000014531510646743264011643 00000000000000# Doxyfile 1.5.0 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = Twinkle # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src src/utils src/im src/presence src/patterns # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.cpp *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = src/twinkle_config.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = t_ #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO