├── .gitignore ├── COPYING ├── Makefile ├── NEWS ├── README.md ├── TODO ├── config.mk ├── docs ├── FAQ ├── GENERAL ├── INTERNAL ├── MUC ├── STARTUP └── XEP ├── help ├── affiliation ├── presence ├── role ├── roster ├── xmppconnect └── xmppserver └── src ├── Makefile ├── core ├── Makefile ├── loudmouth-tools.c ├── loudmouth-tools.h ├── module.h ├── protocol.c ├── protocol.h ├── rosters-tools.c ├── rosters-tools.h ├── rosters.c ├── rosters.h ├── stanzas.c ├── stanzas.h ├── tools.c ├── tools.h ├── xep │ ├── chatstates.c │ ├── chatstates.h │ ├── composing.c │ ├── composing.h │ ├── datetime.c │ ├── datetime.h │ ├── delay.c │ ├── delay.h │ ├── disco.c │ ├── disco.h │ ├── muc-affiliation.c │ ├── muc-affiliation.h │ ├── muc-commands.c │ ├── muc-commands.h │ ├── muc-events.c │ ├── muc-events.h │ ├── muc-nicklist.c │ ├── muc-nicklist.h │ ├── muc-reconnect.c │ ├── muc-reconnect.h │ ├── muc-role.c │ ├── muc-role.h │ ├── muc.c │ ├── muc.h │ ├── oob.c │ ├── oob.h │ ├── ping.c │ ├── ping.h │ ├── registration.c │ ├── registration.h │ ├── tool_datalist.c │ ├── tool_datalist.h │ ├── vcard.c │ ├── vcard.h │ ├── version.c │ ├── version.h │ ├── xep.c │ └── xep.h ├── xmpp-commands.c ├── xmpp-commands.h ├── xmpp-core.c ├── xmpp-queries.c ├── xmpp-queries.h ├── xmpp-servers-reconnect.c ├── xmpp-servers-reconnect.h ├── xmpp-servers.c ├── xmpp-servers.h ├── xmpp-settings.c ├── xmpp-settings.h └── xmpp.h ├── fe-common ├── Makefile ├── fe-rosters.c ├── fe-rosters.h ├── fe-stanzas.c ├── fe-stanzas.h ├── fe-xmpp-core.c ├── fe-xmpp-messages.c ├── fe-xmpp-messages.h ├── fe-xmpp-queries.c ├── fe-xmpp-queries.h ├── fe-xmpp-status.c ├── fe-xmpp-status.h ├── fe-xmpp-windows.c ├── fe-xmpp-windows.h ├── module-formats.c ├── module-formats.h ├── module.h ├── xep │ ├── fe-composing.c │ ├── fe-composing.h │ ├── fe-delay.c │ ├── fe-delay.h │ ├── fe-muc.c │ ├── fe-muc.h │ ├── fe-ping.c │ ├── fe-ping.h │ ├── fe-registration.c │ ├── fe-registration.h │ ├── fe-vcard.c │ ├── fe-vcard.h │ ├── fe-version.c │ ├── fe-version.h │ ├── fe-xep.c │ └── fe-xep.h ├── xmpp-completion.c ├── xmpp-completion.h ├── xmpp-formats.c └── xmpp-formats.h ├── fe-text ├── Makefile ├── module.h ├── text-xmpp-core.c └── xep │ ├── text-composing.c │ ├── text-composing.h │ ├── text-muc.c │ ├── text-muc.h │ ├── text-xep.c │ └── text-xep.h └── rules.mk /.gitignore: -------------------------------------------------------------------------------- 1 | irssi-0.* 2 | *.o 3 | *.so 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include config.mk 2 | 3 | all clean user-install user-uninstall: 4 | @cd src/ && ${MAKE} $@ 5 | 6 | install: 7 | @cd src/ && ${MAKE} $@ 8 | @${MAKE} doc-install help-install 9 | 10 | uninstall: doc-uninstall help-uninstall 11 | @cd src/ && ${MAKE} $@ 12 | 13 | doc-install: 14 | @echo installing documentation files to ${DESTDIR}${IRSSI_DOC}/irssi-xmpp 15 | @install -d ${DESTDIR}${IRSSI_DOC}/irssi-xmpp 16 | @cd docs/ && install -m 644 FAQ GENERAL MUC STARTUP XEP ${DESTDIR}${IRSSI_DOC}/irssi-xmpp 17 | 18 | doc-uninstall: 19 | @echo uninstalling documentation files from ${DESTDIR}${IRSSI_DOC}/irssi-xmpp 20 | @rm -rf ${DESTDIR}${IRSSI_DOC}/irssi-xmpp 21 | 22 | help-install: 23 | @echo installing command help files to ${DESTDIR}${IRSSI_HELP} 24 | @install -d ${DESTDIR}${IRSSI_HELP} 25 | @cd help/ && install -m 644 presence roster role affiliation xmppconnect xmppserver ${DESTDIR}${IRSSI_HELP} 26 | 27 | help-uninstall: 28 | @echo uninstalling command help files from ${DESTDIR}${IRSSI_HELP} 29 | @cd ${DESTDIR}${IRSSI_HELP} && rm -f presence roster xmppconnect xmppserver 30 | 31 | .PHONY: all clean install uninstall user-install user-uninstall doc-install doc-uninstall help-install help-uninstall 32 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 0.54 - 02/10/2017 2 | 3 | - Irssi 1.0.0 support 4 | 5 | 0.53 - 18/03/2016 6 | 7 | - Irssi 0.8.18 support 8 | - Bug fixes and stability improvements 9 | 10 | 0.52 - 15/02/2012 11 | 12 | - Add a way to dynamicly change the priority while away 13 | (setting "xmpp_priority_away") 14 | - No more password prompt on reconnection 15 | - Don't forget the resource part of the jid on reconnection 16 | - Fix MUC invites to be compliant 17 | - and some minor bug, typo and spelling mistakes fixes 18 | 19 | 0.51 - 14/05/2010 20 | 21 | + Add STARTTLS support (enabled by default if the parameter -ssl 22 | is not specified) 23 | - Rework the way connections are performed 24 | - Add a password prompt if no password was specified 25 | - Add a connection timeout in case there is no response from the 26 | server, so the connection will be reseted after a certain 27 | amount of time (setting "server_connect_timeout") 28 | - /CYCLE command 29 | - and many others minor changes and fixes 30 | 31 | 0.50 - 07/08/2009 32 | 33 | + Complete rewrite with a modular architecture 34 | + Better integration in irssi, many bug fixes and a big code cleanup 35 | + Better support of XMPP 36 | + Multi-User Chat (XEP-0045), Entity Use Cases and Occupant Use Cases 37 | + Message Events (XEP-0022) and Chat State Notifications (XEP-0085) 38 | showed in the status-bar (status-bar "xmpp_composing"), you can 39 | disable events sending (setting "xmpp_send_composing") 40 | + XMPP Ping (XEP-0199) support using the command /PING, it also allows 41 | the lag-meter to work 42 | + Software Version (XEP-0092) support using /VER and vCard (XEP-0054) 43 | using /WHOIS (partial retrieve) 44 | + Delayed Delivery (XEP-0203) support 45 | + Better UTF-8 support 46 | + HTTP proxy support 47 | + commands /XMPPCONNECT and /XMPPSERVER to connect easily to an 48 | account 49 | + command /XMPPREGISTER to register an account using the In-Band 50 | Registration (XEP-0077) 51 | - /ME command on queries and rooms 52 | - tab completion of JIDs, resources, user names and groups 53 | (even with spaces) 54 | - changing the priority (setting "xmpp_priority") takes effect 55 | immediately 56 | - basic status changes window (setting "xmpp_status_window") and raw 57 | window (setting "xmpp_raw_window") 58 | - and many others minor changes and fixes 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | irssi-xmpp 2 | ========== 3 | 4 | **Homepage:** https://github.com/cdidier/irssi-xmpp 5 | 6 | 7 | ## About ## 8 | 9 | irssi-xmpp is an irssi plugin to connect to the XMPP network (jabber). 10 | 11 | Its main features are: 12 | * Sending and receiving messages in irssi's query windows 13 | * A roster with contact & resource tracking (contact list) 14 | * Contact management (add, remove, manage subscriptions) 15 | * MUC (Multi-User Chat) 16 | * Tab completion of commands, JIDs and resources 17 | * Message Events ("composing") 18 | * Support for multiple accounts 19 | * Unicode support (UTF-8) 20 | * StartTLS, SSL (deprecated) and HTTP proxy support 21 | * ... 22 | 23 | To deal with the XMPP protocol, it uses of the Loudmouth library. 24 | Written in C and released under the GNU General Public License version 2. 25 | 26 | 27 | ## Installation ## 28 | 29 | ### Requirement ### 30 | * Loudmouth (>= 1.4.x): https://github.com/mcabber/loudmouth 31 | * Irssi (>= 0.8.13) and its sources unpacked and configured: 32 | http://irssi.org/ 33 | 34 | ### Procedure ### 35 | * edit the file **config.mk** if needed and export this environment variable: 36 | ``` $ export IRSSI_INCLUDE=/path/to/irssi/sources ``` 37 | * build the sources: 38 | ```$ make ``` 39 | * install the module: 40 | * in your home directory: 41 | ``` $ make user-install ``` 42 | * in the base system: 43 | ``` # make install ``` 44 | 45 | ### Packages ### 46 | * Debian/Ubuntu package: ``` apt-get install irssi-plugin-xmpp ``` ([more info](https://packages.debian.org/sid/irssi-plugin-xmpp)) 47 | * OpenBSD port: ``` pkg_add irssi-xmpp ``` ([more info](http://openports.se/net/irssi-xmpp)) 48 | * FreeBSD port: ``` pkg_add -r irssi-xmpp ``` ([more info](http://www.freshports.org/irc/irssi-xmpp/)) 49 | * MacOS Homebrew: ``` brew install simmel/irssi/irssi-xmpp ``` ([more info](https://github.com/simmel/homebrew-irssi)) 50 | * and in many package repository of Linux distributions... 51 | 52 | ## Documentation ## 53 | 54 | In the directory **docs/**: 55 | * **STARTUP**: Getting started 56 | * **GENERAL**: How to use irssi-xmpp and related commands 57 | * **MUC**: How to use Multi-User Chat and related commands 58 | * **FAQ**: Frequently Asked Questions and Troubleshooting 59 | * **XEP**: XMPP Extensions supported 60 | * **INTERNAL**: How irssi-xmpp works 61 | 62 | In the directory **help/** you can find the help files of each irssi-xmpp 63 | specific commands, which can be viewed in irssi with the command /HELP. 64 | 65 | 66 | ## Bugs and suggestions ## 67 | 68 | * On Github: https://github.com/cdidier/irssi-xmpp/issues 69 | 70 | * MUC room: irssi-xmpp@chat.jabberfr.org 71 | 72 | If irssi crashes, please build irssi with debug symbols and the module 73 | irssi-xmpp in debug mode (take a look at **config.mk** to activate it). 74 | Then you can run irssi in gdb and print the backtrace ("bt full") when 75 | irssi crashes. Paste the backtrace in your message would help to fix 76 | this bug. 77 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Next release(s): 2 | - Fix IPv6 support 3 | - Assign threads to query windows 4 | - Implement bookmarks (to autojoin rooms) 5 | - Write the documentation in help/ for the commmands: 6 | ROSTER, PRESENCE, XMPPREGISTER, XMPPUNREGISTER, XMPPPASSWD 7 | - Handle errors and print errors messages (many errors are not handled 8 | yet, specially in MUC) 9 | - Rewrite completion (src/fe-common/xmpp-completion.c) 10 | - Implement the commands /SERVICES DISCOVER/LOGON/LOGOFF to 11 | print info/activate/deactivate a service (like a gateway) 12 | 13 | 14 | 15 | Delayed tasks: 16 | - Print name instead of jid in queries messages: 17 | One way to do it is to create new signals (like "message xmpp private" 18 | instead of "message private") and handle these new signals to print the 19 | nickname. The major problem is that you have to stop the signal "message 20 | private" to replace it with "message xmpp private", but many things in 21 | irssi handle the original signal so you have to recreate the same 22 | behaviors inside irssi-xmpp (which is complicated and boring). For 23 | inspiration you can see how the signal "message own_public" is handled 24 | in src/fe-common/fe-xmpp-messages.c 25 | The other (and better) way to do it, is to modify some signal emitted 26 | by irssi (at least "message private", to add a new parameter which will 27 | be the nick to display) and to modify the way irssi handle these new 28 | signals. 29 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | # paths 2 | PREFIX ?= /usr/local 3 | 4 | # where are the sources of irssi? 5 | IRSSI_INCLUDE ?= ${PREFIX}/include/irssi 6 | # where should be installed the module? 7 | IRSSI_LIB ?= ${PREFIX}/lib/irssi 8 | # where should be installed the documentation? 9 | IRSSI_DOC ?= ${PREFIX}/share/doc/irssi 10 | # where should be installed the help for commands ? 11 | IRSSI_HELP ?= ${PREFIX}/share/irssi/help 12 | 13 | # includes and libs 14 | INCS = ${LIB_INCS} \ 15 | -I../../src/core \ 16 | -I${IRSSI_INCLUDE} \ 17 | -I${IRSSI_INCLUDE}/src \ 18 | -I${IRSSI_INCLUDE}/src/core \ 19 | -I$(IRSSI_INCLUDE)/src/fe-common/core \ 20 | -I$(IRSSI_INCLUDE)/src/fe-text \ 21 | `pkg-config --cflags glib-2.0` \ 22 | `pkg-config --cflags loudmouth-1.0` 23 | LIBS = ${LIB_LIBS} 24 | 25 | # flags 26 | CFLAGS += -fPIC -DUOFF_T_LONG 27 | LDFLAGS += -shared 28 | 29 | # debug 30 | #CFLAGS += -std=c99 -W -g -Wall -Wno-unused-parameter 31 | #CFLAGS += -Wno-deprecated-declarations 32 | #CFLAGS += -Wno-cast-function-type 33 | 34 | # compiler and linker 35 | CC ?= cc 36 | -------------------------------------------------------------------------------- /docs/FAQ: -------------------------------------------------------------------------------- 1 | 1. Connection: 2 | ============== 3 | 4 | 1.1 How can I automatically load irssi-xmpp at irssi startup ? 5 | 6 | Simply put "load xmpp" in your startup file (~/.irssi/startup): 7 | echo "load xmpp" >> ~/.irssi/startup 8 | 9 | 1.2 How can I automatically connect to my account at irssi startup ? 10 | 11 | You can put these things in your config file (The config file can be 12 | found here : "~/.irssi/config"): 13 | 14 | To create a XMPP network, add to chatnets section: 15 | = { 16 | type = "XMPP"; 17 | nick = ""; 18 | }; 19 | 20 | Then you can add this at the end of the servers section: 21 | { 22 | address = "
"; 23 | port=""; 24 | use_ssl = "{yes|no}"; 25 | chatnet = ""; 26 | password = ""; 27 | autoconnect = "{yes|no}"; 28 | }; 29 | 30 | Or in irssi, you can type this: 31 | /SERVER ADD -xmppnet
32 | 33 | If 0 is specified as port, the default port will be used (5222 for a 34 | regular connection or 5223 for SSL). 35 | 36 | Now you can connect to your jabber account by typing: 37 | /CONNECT 38 | Or just restart irssi if you have set autoconnect to yes. 39 | 40 | 1.3 How can I use my gmail/gtalk account ? 41 | 42 | You have to use the server "talk.google.com", so the command is: 43 | /XMPPCONNECT -host talk.google.com 44 | 45 | You don't need to specify the -ssl switch because STARTTLS will be 46 | used automatically. 47 | 48 | 2. General: 49 | =========== 50 | 51 | 2.1 Why the lagmeter is not working ? 52 | 53 | The server need to support the XEP-0199 (XMPP Ping). If it doesn't 54 | support it, the lagmeter won't work. 55 | 56 | If your server support the XMPP Ping, maybe you didn't add the 57 | composing item in the statusbar. Take a look at the file GENERAL 58 | (section "Composing in the statusbar:). 59 | 60 | 2.2 How can I be away on all servers (both IRC servers and XMPP 61 | servers) ? 62 | 63 | Simply use this command: 64 | /foreach server /away -one 65 | 66 | Or set up an alias like this 67 | /alias aaway /foreach server /away -one 68 | 69 | 3. Scripting: 70 | ============= 71 | 72 | 3.1 How can I use or write scripts with irssi-xmpp ? 73 | 74 | ... 75 | 76 | 3.2 My script seems to be incompatible with irssi-xmpp and throws warnings 77 | such as: Can't locate object method "xxx" via package "Irssi::Xmpp::Server". 78 | How can I get rid of that ? 79 | 80 | Basically, it's because the script is IRC-specific and won't work with 81 | an XMPP server. Try to add a condition in the functions of your script 82 | to verify if the server is an IRC server and simply return if it is 83 | not. 84 | 85 | 4. Themes: 86 | ========== 87 | 88 | 4.1 How can I change the theme of the messages of irssi-xmpp ? 89 | 90 | In the same way you can change the theme of the messages of irssi. 91 | Take a look at the source file src/fe-common/module-formats.c to see 92 | the whole list of irssi-xmpp messages. 93 | -------------------------------------------------------------------------------- /docs/GENERAL: -------------------------------------------------------------------------------- 1 | General commands: 2 | ================= 3 | 4 | These commands are the general commands for a basic usage of irssi-xmpp. 5 | 6 | You may notice that some commands accept as parameter a JID, a full JID 7 | (a JID with a resource) or a name. If you specify a name, it will be 8 | resolved through the roster. But if the name cannot be found in your 9 | roster, irssi-xmpp will assume that the name is a JID. 10 | 11 | Some commands require a full JID, but if you type only a JID or a name, 12 | these commands will automatically use the highest resource for this 13 | contact in your roster. 14 | 15 | /QUERY [/] 16 | /QUERY 17 | Starts a private conversation with the JID. If the user is online and 18 | the resource isn't specified, the conversation window will be on the 19 | resource with the highest priority. 20 | 21 | /MSG [/] 22 | Sends a message to a jid. There is no name resolution through the roster so 23 | the jid must be valid. (Prefer /QUERY if you want a normal discussion in 24 | a query window.) 25 | 26 | /ME 27 | Sends an "ACTION", useable in a query or in a room. 28 | 29 | /AWAY [away|chat|dnd|xa] 30 | This command marks you as being "away". If the away mode isn't specified, 31 | the "xmpp_default_away_mode" setting will be used. You can remove your away 32 | status by using AWAY with no arguments. 33 | 34 | /ROSTER 35 | Shows your contacts in a list. 36 | 37 | /ROSTER FULL 38 | Shows all your contacts in a list, even those who are offline. 39 | 40 | /ROSTER ADD [-nosub] 41 | Adds a JID to your contact list. (Use the parameter "-nosub" if you 42 | don't want to send a subscribe request.) 43 | 44 | /ROSTER REMOVE 45 | Removes a JID from your contact list. The subscriptions will be removed too. 46 | 47 | /ROSTER NAME 48 | Changes the name (or nickname) of a JID. 49 | 50 | /ROSTER GROUP 51 | Changes the group of a JID. 52 | 53 | /WHOIS 54 | /WHOIS 55 | Requests the vcard related to the JID. 56 | 57 | /VER / 58 | /VER 59 | Requests the software version of the resource. 60 | 61 | /QUOTE 62 | Sends server raw data without parsing. You need to make sure the value is 63 | XML valid. 64 | 65 | /XMPPCONNECT [-ssl] [-host ] [-port ] 66 | [/] 67 | /XMPPSERVER [-ssl] [-host ] [-port ] 68 | [/] 69 | See the "Connection" section of the STARTUP file. 70 | 71 | Subscription commands: 72 | ====================== 73 | 74 | These commands are useful if you want to manage the subscription of your 75 | contacts. 76 | 77 | /PRESENCE ACCEPT 78 | Accepts a subscription request, so the contact will be able to see your 79 | presence. 80 | 81 | /PRESENCE DENY 82 | Denies a subscription, so the contact won't see your presence anymore. 83 | 84 | /PRESENCE SUBSCRIBE 85 | Sends a subscription request to a JID. If the contact accepts your request, 86 | you'll be able to see their presence. 87 | 88 | /PRESENCE UNSUBSCRIBE 89 | Unsubscribes to the contact's presence, so you won't see their presence 90 | anymore. 91 | 92 | Subscription status: 93 | ==================== 94 | 95 | These are the subscription status displayed in the roster list with their 96 | description: 97 | 98 | both: The contact and you can see each other's presence. (not displayed) 99 | from: The contact can see your presence. 100 | to: You can see the contact's presence. 101 | none: The contact and you cannot see each other's presence. 102 | 103 | Settings: 104 | ========= 105 | 106 | In "xmpp" section: 107 | 108 | /SET xmpp_priority 109 | Sets the priority of your connection. It's a number between -128 and 127. 110 | Priority changes will take effect immediatly for all your connected 111 | accounts. (default: 0) 112 | 113 | /SET xmpp_priority_away 114 | Sets the priority of your connection when your are away. (default: -1) 115 | 116 | /SET xmpp_send_version ON/OFF 117 | Sends information about your client: name (irssi-xmpp), version and operating 118 | system. (default: ON) 119 | 120 | /SET xmpp_default_away_mode {away|chat|dnd|xa} 121 | Sets the default away mode when you just type "/AWAY ". 122 | (default: away) 123 | 124 | /SET xmpp_send_composing ON/OFF 125 | Enables or disables the sending of your chat state notifications. 126 | (default: ON) 127 | 128 | In "xmpp_lookandfeel" section: 129 | 130 | /SET xmpp_set_nick_as_username ON/OFF 131 | Sets whether your JID's username should be used as nick in query 132 | windows. If this setting is OFF, your nick will be your JID. If it's 133 | ON, your nick will be the username of your JID. (default: OFF) 134 | 135 | /SET xmpp_status_window ON/OFF 136 | Creates a new window that displays every status change of your contacts. 137 | (default: OFF) 138 | 139 | /SET xmpp_timestamp_format 140 | Sets the timestamp format that should be used to display the delayed 141 | messages. (default: %Y-%m-%d %H:%M) 142 | 143 | /SET xmpp_history_maxstanzas 144 | Sets the maximum number of messages that should be retrieved from the 145 | archives when joining a room. 146 | (default: 30) 147 | 148 | /SET xmpp_xml_console ON/OFF 149 | Creates a new window where the raw XML messages are displayed. Useful for 150 | debugging. (default: OFF) 151 | 152 | In "xmpp_proxy" section: 153 | 154 | See the "Proxy usage" section of this file. 155 | 156 | In "xmpp_roster" section: 157 | 158 | /SET xmpp_roster_show_offline ON/OFF 159 | Shows offline contacts in the roster. (default: ON) 160 | 161 | /SET xmpp_roster_show_unsubscribed ON/OFF 162 | Shows unsubscribed contacts in the roster when they are offline. 163 | (default: ON) 164 | 165 | /SET xmpp_roster_default_group 166 | Sets the default group where the contacts will be displayed if the group name 167 | is unspecified. (default: General) 168 | 169 | /SET xmpp_roster_service_name 170 | Sets the default group where the services and the transports will be 171 | displayed. (default: Agents/Transports) 172 | (Not used yet!) 173 | 174 | Away status: 175 | =========== 176 | 177 | In this section you can find the descriptions of each away status available 178 | in jabber: 179 | 180 | away: Away 181 | chat: Free for chat 182 | dnd: Do not disturb 183 | xa: Not available 184 | 185 | Proxy usage: 186 | ============ 187 | 188 | To connect to an account through a proxy, you must set these settings 189 | according to your proxy configuration. Please note that these settings 190 | are general so they affect all the jabber accounts you configured in 191 | irssi. 192 | 193 | /SET xmpp_use_proxy ON/OFF 194 | Enables or disables the proxy. (default: OFF) 195 | 196 | /SET xmpp_proxy_address 197 | /SET xmpp_proxy_port 198 | /SET xmpp_proxy_user 199 | /SET xmpp_proxy_password 200 | Sets the connection parameters to connect to the proxy. 201 | 202 | /SET xmpp_proxy_type 203 | Sets the type of the proxy. Currently, irssi-xmpp only supports the HTTP 204 | method. (default: http) 205 | 206 | Composing in the statusbar: 207 | =========================== 208 | 209 | irssi-xmpp supports the XEP-0085: Chat State Notifications, so you can see when 210 | your contacts are typing a messages with "composing" appearing in the statusbar. 211 | To add this statusbar element, you can use this command : 212 | 213 | /STATUSBAR WINDOW ADD xmpp_composing 214 | 215 | Or for example: 216 | 217 | /STATUSBAR WINDOW ADD -before barend -alignment right xmpp_composing 218 | -------------------------------------------------------------------------------- /docs/INTERNAL: -------------------------------------------------------------------------------- 1 | TODO: finnish writting this doc 2 | 3 | Sources layout: 4 | =============== 5 | 6 | src/core 7 | src/core/xep 8 | src/fe-common 9 | src/fe-common/xep 10 | src/fe-text 11 | 12 | Signals: 13 | ======== 14 | 15 | xmpp xml recv 16 | xmpp xml send 17 | 18 | xmpp recv message 19 | xmpp recv presence 20 | xmpp recv iq 21 | xmpp recv others 22 | xmpp send message 23 | xmpp send presence 24 | xmpp send iq 25 | xmpp send others 26 | 27 | xmpp ssl error 28 | xmpp server status 29 | 30 | xmpp presence online 31 | xmpp presence offline 32 | xmpp presence changed 33 | 34 | xmpp features 35 | xmpp server features 36 | 37 | xmpp composing show 38 | xmpp composing hide 39 | xmpp composing start 40 | xmpp composing stop 41 | 42 | xmpp vcard 43 | 44 | xmpp version 45 | -------------------------------------------------------------------------------- /docs/MUC: -------------------------------------------------------------------------------- 1 | MUC commands: 2 | ============= 3 | 4 | /JOIN [/] 5 | Join a room. If your nick is not specified, the value of the setting "nick" 6 | will be used as your nick in this room. 7 | Unlike irssi default behaviour (that you can pass a list of channels 8 | separated with a comma), only one room can be passed to this command! 9 | 10 | /PART [] [] 11 | Leaves a room. 12 | 13 | /QUERY 14 | Opens a query window with the nick in the room. 15 | 16 | /NICK [] 17 | Changes your nick in a specific room. 18 | 19 | /TOPIC [] 20 | Changes the topic of the room, if you have the right to do it. 21 | 22 | /NAME 23 | Lists the nicks in the room. 24 | 25 | /INVITE [/] [] 26 | /INVITE [] 27 | Invites the specified contact to the current or specified room. 28 | 29 | Administration commands: 30 | ======================== 31 | 32 | /DESTROY [] [] [] 33 | Destroy a room, if you have the right to do it. 34 | 35 | /ROLE [] 36 | List all user having a specific role, if you have the right to do it. 37 | 38 | /ROLE [] [] 39 | Give nick a specific role, if you have the right to do it. 40 | 41 | /KICK [] [] 42 | Kick a specific nick, if you have the right to do it. 43 | Equivalent to /ROLE none . 44 | 45 | /AFFILIATION [] 46 | List all user having a specific affiliation, if you have the right to do it. 47 | 48 | /AFFILIATION [] [] 49 | Give jid a specific affiliation, if you have the right to do it. 50 | 51 | /BAN [] [] 52 | Ban a specific jid, if you have the right to do it. 53 | Equivalent to /AFFILIATION outcast . 54 | 55 | /MODE [] 56 | Set channel mode. 57 | Available mode are Mmkpu. 58 | 59 | /MODE [] [] 60 | Get channel mode. 61 | -------------------------------------------------------------------------------- /docs/STARTUP: -------------------------------------------------------------------------------- 1 | Running irssi-xmpp: 2 | =================== 3 | 4 | Usage: 5 | /LOAD xmpp 6 | 7 | Simply load the module in irssi. Currently you cannot load it automatically, 8 | unless using a script or something like that. 9 | 10 | The module should be placed in "~/.irssi/modules/", or you should load it with 11 | the full path. 12 | 13 | You can unload it using: 14 | /UNLOAD xmpp 15 | 16 | Connection: 17 | =========== 18 | 19 | Usage: 20 | /XMPPCONNECT [-ssl] [-host ] [-port ] 21 | [/] 22 | 23 | The "jid" is your Jabber ID (something like "username@server"). You can add 24 | "/" at the end of the "jid" to set your own resource. 25 | 26 | Please note that irssi-xmpp doesn't support SRV record (yet), so you must 27 | specify the host with the parameter "-host". 28 | 29 | You can also use /XMPPSERVER to replace the current connection. See the FAQ 30 | if you want to automatically connect to the server at startup 31 | 32 | If available, StartTLS will be used by default. Use the "-ssl" switch 33 | only if you want to use the deprecated SSL encryption. 34 | 35 | Automation: 36 | =========== 37 | 38 | If you want to automatically load the module and connect to an account, 39 | take a look at the FAQ. Everything is explained in it. 40 | 41 | Register: 42 | ========= 43 | 44 | You can register an account directly with irssi-xmpp using the command 45 | /XMPPREGISTER. 46 | 47 | -------------------------------------------------------------------------------- /docs/XEP: -------------------------------------------------------------------------------- 1 | XEPs (XMPP Extension Protocol) support: 2 | 3 | Fully supported: 4 | XEP-0022: Message Events (Superseded by XEP-0085) 5 | XEP-0066: Out of Band Data 6 | XEP-0077: In-Band Registration 7 | XEP-0091: Delayed Delivery (Superseded by XEP-0203) 8 | XEP-0092: Software Version 9 | XEP-0199: XMPP Ping 10 | 11 | Partially supported: 12 | XEP-0030: Service Discovery 13 | XEP-0045: Multi-User Chat (Entity Use Cases and Occupant Use Cases) 14 | XEP-0054: vcard-temp 15 | XEP-0082: XMPP Date and Time Profiles 16 | XEP-0085: Chat State Notifications 17 | XEP-0203: Delayed Delivery 18 | -------------------------------------------------------------------------------- /help/affiliation: -------------------------------------------------------------------------------- 1 | 2 | Syntax: 3 | 4 | AFFILIATION [] [] [] 5 | 6 | Parameters: 7 | 8 | An affiliation type and optionnaly a jid, a reason and a channel. 9 | 10 | Type must be one of: 11 | - none 12 | - owner 13 | - admin 14 | - member 15 | - outcast 16 | 17 | Description: 18 | 19 | When called without a jid, list all user having a specific affiliation, if you have the right to do it. 20 | Otherwise, give jid a specific affiliation, if you have the right to do it. 21 | 22 | Examples: 23 | 24 | /AFFILIATION outcast 25 | /AFFILIATION admin john 26 | 27 | See also: ROLE, KICK, BAN 28 | -------------------------------------------------------------------------------- /help/presence: -------------------------------------------------------------------------------- 1 | 2 | PRESENCE 3 | 4 | Handle presence subscription. 5 | 6 | See also: ROSTER 7 | 8 | -------------------------------------------------------------------------------- /help/role: -------------------------------------------------------------------------------- 1 | 2 | Syntax: 3 | 4 | ROLE [] [] [] 5 | 6 | Parameters: 7 | 8 | A role type and optionnaly a nick, a reason and a channel. 9 | 10 | Type must be one of: 11 | - none 12 | - moderator 13 | - participant 14 | - visitor 15 | 16 | Description: 17 | 18 | When called without a nick, list all user having a specific role, if you have the right to do it. 19 | Otherwise, give nick a specific role, if you have the right to do it. 20 | 21 | Examples: 22 | 23 | /ROLE participant 24 | /ROLE moderartor john 25 | 26 | See also: AFFILIATION, KICK, BAN 27 | -------------------------------------------------------------------------------- /help/roster: -------------------------------------------------------------------------------- 1 | 2 | ROSTER [full] 3 | ROSTER add 4 | ROSTER remove 5 | ROSTER name 6 | ROSTER group 7 | 8 | This command includes various subcommands for handling your contact list. 9 | 10 | See also: PRESENCE 11 | 12 | -------------------------------------------------------------------------------- /help/xmppconnect: -------------------------------------------------------------------------------- 1 | 2 | XMPPCONNECT %|[-ssl] [-host ] [-port ] [/] 3 | 4 | -ssl: use SSL when connecting (deprecated, StartTLS will be used by default if this parameter is not specified) 5 | -host: the host 6 | -port: the port (if not specified, 5222 is used for a normal connection or 5223 for an SSL connection) 7 | 8 | This command makes irssi to connect to specified XMPP account. Current connections are kept and a new one is created. 9 | 10 | See also: XMPPSERVER, SERVER, DISCONNECT, RMRECONNS 11 | 12 | -------------------------------------------------------------------------------- /help/xmppserver: -------------------------------------------------------------------------------- 1 | 2 | XMPPSERVER %|[-ssl] [-server ] [-port ] [/] 3 | 4 | -ssl: use SSL when connecting (deprecated, StartTLS will be used by default if this parameter is not specified) 5 | -host: the host 6 | -port: the port (if not specified, 5222 is used for a normal connection or 5223 for an SSL connection) 7 | 8 | This command disconnects the server in active window and connects to the new one. It will take the same arguments as /XMPPCONNECT. 9 | 10 | See also: XMPPCONNECT, CONNECT, SERVER, DISCONNECT, RECONNECT, RMRECONNS 11 | 12 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all clean user-install install: 2 | @echo "core module:" 3 | @cd core/ && ${MAKE} $@ 4 | @echo "fe-common submodule:" 5 | @cd fe-common/ && ${MAKE} $@ 6 | @echo "fe-text submodule:" 7 | @cd fe-text/ && ${MAKE} $@ 8 | 9 | .PHONY: all clean user-install install 10 | -------------------------------------------------------------------------------- /src/core/Makefile: -------------------------------------------------------------------------------- 1 | LIB= xmpp_core 2 | SRCS= xmpp-commands.c \ 3 | xmpp-core.c \ 4 | xmpp-queries.c \ 5 | xmpp-servers.c \ 6 | xmpp-servers-reconnect.c \ 7 | xmpp-settings.c \ 8 | loudmouth-tools.c \ 9 | protocol.c \ 10 | rosters.c \ 11 | rosters-tools.c \ 12 | stanzas.c \ 13 | tools.c \ 14 | xep/chatstates.c \ 15 | xep/composing.c \ 16 | xep/datetime.c \ 17 | xep/delay.c \ 18 | xep/disco.c \ 19 | xep/muc-affiliation.c \ 20 | xep/muc-commands.c \ 21 | xep/muc-events.c \ 22 | xep/muc-nicklist.c \ 23 | xep/muc-reconnect.c \ 24 | xep/muc-role.c \ 25 | xep/muc.c \ 26 | xep/oob.c \ 27 | xep/ping.c \ 28 | xep/registration.c \ 29 | xep/tool_datalist.c \ 30 | xep/vcard.c \ 31 | xep/version.c \ 32 | xep/xep.c 33 | 34 | LIB_LIBS = `pkg-config --libs loudmouth-1.0 | sed -e's/-lidn//'` 35 | 36 | include ../rules.mk 37 | -------------------------------------------------------------------------------- /src/core/loudmouth-tools.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include "loudmouth/loudmouth.h" 20 | 21 | LmMessageNode * 22 | lm_find_node(LmMessageNode *node, const char *name, 23 | const char *attribute, const char *value) 24 | { 25 | LmMessageNode *l; 26 | const char *v; 27 | 28 | g_return_val_if_fail(name != NULL, NULL); 29 | g_return_val_if_fail(attribute != NULL, NULL); 30 | g_return_val_if_fail(value != NULL, NULL); 31 | if (node == NULL) 32 | return NULL; 33 | for (l = node->children; l != NULL; l = l->next) 34 | if (strcmp(l->name, name) == 0) { 35 | v = lm_message_node_get_attribute(l, attribute); 36 | if (v != NULL && strcmp(value, v) == 0) 37 | return l; 38 | } 39 | return NULL; 40 | } 41 | -------------------------------------------------------------------------------- /src/core/loudmouth-tools.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOUDMOUTH_TOOLS_H 2 | #define __LOUDMOUTH_TOOLS_H 3 | 4 | __BEGIN_DECLS 5 | LmMessageNode *lm_find_node(LmMessageNode *, const char *, 6 | const char *, const char *); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/module.h: -------------------------------------------------------------------------------- 1 | #define MODULE_NAME "xmpp/core" 2 | 3 | #include "irssi-config.h" 4 | #include "common.h" 5 | #include "xmpp.h" 6 | -------------------------------------------------------------------------------- /src/core/protocol.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "signals.h" 20 | 21 | #include "xmpp-servers.h" 22 | #include "rosters-tools.h" 23 | #include "tools.h" 24 | 25 | static void 26 | sig_set_presence(XMPP_SERVER_REC *server, const int show, const char *status, 27 | const int priority) 28 | { 29 | LmMessage *lmsg; 30 | char *str; 31 | 32 | g_return_if_fail(IS_XMPP_SERVER(server)); 33 | if (!xmpp_presence_changed(show, server->show, status, 34 | server->away_reason, priority, server->priority)) { 35 | signal_stop(); 36 | return; 37 | } 38 | server->show = show; 39 | g_free(server->away_reason); 40 | server->away_reason = g_strdup(status); 41 | if (!xmpp_priority_out_of_bound(priority)) 42 | server->priority = priority; 43 | lmsg = lm_message_new(NULL, LM_MESSAGE_TYPE_PRESENCE); 44 | if (show != XMPP_PRESENCE_AVAILABLE) 45 | lm_message_node_add_child(lmsg->node, "show", 46 | xmpp_presence_show[server->show]); 47 | if (status != NULL) { 48 | str = xmpp_recode_out(server->away_reason); 49 | lm_message_node_add_child(lmsg->node, "status", str); 50 | g_free(str); 51 | } 52 | str = g_strdup_printf("%d", server->priority); 53 | lm_message_node_add_child(lmsg->node, "priority", str); 54 | g_free(str); 55 | signal_emit("xmpp send presence", 2, server, lmsg); 56 | lm_message_unref(lmsg); 57 | if (show != XMPP_PRESENCE_AVAILABLE) /* away */ 58 | signal_emit("event 306", 2, server, server->jid); 59 | else if (server->usermode_away) /* unaway */ 60 | signal_emit("event 305", 2, server, server->jid); 61 | } 62 | 63 | static void 64 | sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 65 | const char *id, const char *from, const char *to) 66 | { 67 | LmMessageNode *node; 68 | char *str, *subject; 69 | 70 | if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET 71 | && type != LM_MESSAGE_SUB_TYPE_HEADLINE 72 | && type != LM_MESSAGE_SUB_TYPE_NORMAL 73 | && type != LM_MESSAGE_SUB_TYPE_CHAT) 74 | || server->ischannel(SERVER(server), from)) 75 | return; 76 | node = lm_message_node_get_child(lmsg->node, "subject"); 77 | if (node != NULL && node->value != NULL && *node->value != '\0') { 78 | str = xmpp_recode_in(node->value); 79 | subject = g_strconcat("Subject: ", str, (void *)NULL); 80 | g_free(str); 81 | signal_emit("message private", 4, server, subject, from, from); 82 | g_free(subject); 83 | } 84 | node = lm_message_node_get_child(lmsg->node, "body"); 85 | if (node != NULL && node->value != NULL && *node->value != '\0') { 86 | str = xmpp_recode_in(node->value); 87 | if (g_ascii_strncasecmp(str, "/me ", 4) == 0) 88 | signal_emit("message xmpp action", 5, 89 | server, str+4, from, from, 90 | GINT_TO_POINTER(SEND_TARGET_NICK)); 91 | else 92 | signal_emit("message private", 4, server, 93 | str, from, from); 94 | g_free(str); 95 | } 96 | } 97 | 98 | void 99 | protocol_init(void) 100 | { 101 | signal_add_first("xmpp set presence", sig_set_presence); 102 | signal_add("xmpp recv message", sig_recv_message); 103 | } 104 | 105 | void 106 | protocol_deinit(void) 107 | { 108 | signal_remove("xmpp set presence", sig_set_presence); 109 | signal_remove("xmpp recv message", sig_recv_message); 110 | } 111 | -------------------------------------------------------------------------------- /src/core/protocol.h: -------------------------------------------------------------------------------- 1 | #ifndef __PROTOCOL_H 2 | #define __PROTOCOL_H 3 | 4 | #include "xmpp-servers.h" 5 | 6 | __BEGIN_DECLS 7 | void protocol_init(void); 8 | void protocol_deinit(void); 9 | __END_DECLS 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/core/rosters-tools.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "module.h" 22 | 23 | #include "xmpp-servers.h" 24 | #include "rosters-tools.h" 25 | #include "tools.h" 26 | 27 | static int 28 | find_user_func(gconstpointer user, gconstpointer jid) 29 | { 30 | g_return_val_if_fail(user != NULL, -1); 31 | g_return_val_if_fail(jid != NULL, -1); 32 | return strcmp(((XMPP_ROSTER_USER_REC *)user)->jid, jid); 33 | } 34 | 35 | static int 36 | find_username_func(gconstpointer user_pointer, gconstpointer name) 37 | { 38 | XMPP_ROSTER_USER_REC *user; 39 | 40 | g_return_val_if_fail(user_pointer != NULL, -1); 41 | user = (XMPP_ROSTER_USER_REC *)user_pointer; 42 | if (user->name == NULL) 43 | return -1; 44 | return strcmp(user->name, name); 45 | } 46 | 47 | static int 48 | find_resource_func(gconstpointer resource, gconstpointer name) 49 | { 50 | char *res; 51 | 52 | g_return_val_if_fail(resource != NULL, -1); 53 | res = ((XMPP_ROSTER_RESOURCE_REC *)resource)->name; 54 | if(res == NULL && name == NULL) 55 | return 0; 56 | if (res == NULL || name == NULL) 57 | return -1; 58 | return strcmp(res, name); 59 | } 60 | 61 | XMPP_ROSTER_GROUP_REC * 62 | find_group_from_user(XMPP_SERVER_REC *server, XMPP_ROSTER_USER_REC *user) 63 | { 64 | GSList *gl, *gl_found; 65 | 66 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 67 | gl = server->roster; 68 | gl_found = NULL; 69 | while (gl_found != NULL && gl != NULL) { 70 | gl_found = g_slist_find(gl, user); 71 | gl = gl->next; 72 | } 73 | return (XMPP_ROSTER_GROUP_REC *)gl->data; 74 | } 75 | 76 | XMPP_ROSTER_USER_REC * 77 | rosters_find_user(GSList *groups, const char *jid, 78 | XMPP_ROSTER_GROUP_REC **group, XMPP_ROSTER_RESOURCE_REC **resource) 79 | { 80 | GSList *group_tmp, *gl, *ul; 81 | char *pos; 82 | 83 | if ((pos = xmpp_find_resource_sep(jid)) != NULL) 84 | *pos = '\0'; 85 | group_tmp = ul = NULL; 86 | for (gl = groups; ul == NULL && gl != NULL; 87 | gl = gl->next) { 88 | ul = g_slist_find_custom( 89 | ((XMPP_ROSTER_GROUP_REC *)gl->data)->users, jid, 90 | find_user_func); 91 | group_tmp = gl; 92 | } 93 | if (group != NULL) 94 | *group = ul != NULL ? 95 | (XMPP_ROSTER_GROUP_REC *)group_tmp->data : NULL; 96 | if (resource != NULL) 97 | *resource = ul != NULL && pos != NULL ? 98 | rosters_find_resource( 99 | ((XMPP_ROSTER_USER_REC *)ul->data)->resources, pos+1) 100 | : NULL; 101 | if (pos != NULL) 102 | *pos = '/'; 103 | return ul != NULL ? 104 | (XMPP_ROSTER_USER_REC *)ul->data : NULL; 105 | } 106 | 107 | XMPP_ROSTER_USER_REC * 108 | find_username(GSList *groups, const char *name, XMPP_ROSTER_GROUP_REC **group) 109 | { 110 | GSList *gl, *group_tmp, *ul; 111 | 112 | gl = groups; 113 | group_tmp = ul = NULL; 114 | while (ul == NULL && gl != NULL) { 115 | ul = g_slist_find_custom( 116 | ((XMPP_ROSTER_GROUP_REC *)gl->data)->users, name, 117 | find_username_func); 118 | group_tmp = gl; 119 | gl = g_slist_next(gl); 120 | } 121 | if (group != NULL && group_tmp != NULL) 122 | *group = group_tmp->data; 123 | return ul ? (XMPP_ROSTER_USER_REC *)ul->data : NULL; 124 | } 125 | 126 | XMPP_ROSTER_RESOURCE_REC * 127 | rosters_find_resource(GSList *resources, const char *res) 128 | { 129 | GSList *resource; 130 | 131 | if (resources == NULL) 132 | return NULL; 133 | resource = g_slist_find_custom(resources, res, find_resource_func); 134 | return resource != NULL ? 135 | (XMPP_ROSTER_RESOURCE_REC *)resource->data : NULL; 136 | } 137 | 138 | XMPP_ROSTER_RESOURCE_REC * 139 | rosters_find_own_resource(XMPP_SERVER_REC *server, const char *resource) 140 | { 141 | GSList *resource_list; 142 | 143 | g_return_val_if_fail(server != NULL, NULL); 144 | resource_list = g_slist_find_custom(server->my_resources, resource, 145 | find_resource_func); 146 | return resource_list ? 147 | (XMPP_ROSTER_RESOURCE_REC *)resource_list->data : NULL; 148 | } 149 | 150 | char * 151 | rosters_resolve_name(XMPP_SERVER_REC *server, const char *name) 152 | { 153 | XMPP_ROSTER_USER_REC *user; 154 | XMPP_ROSTER_RESOURCE_REC *resource; 155 | char *res, *str; 156 | 157 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 158 | g_return_val_if_fail(name != NULL, NULL); 159 | g_strstrip((char *)name); 160 | user = find_username(server->roster, name, NULL); 161 | if (user == NULL) 162 | user = rosters_find_user(server->roster, name, NULL, NULL); 163 | if (user != NULL) { 164 | if (!xmpp_have_resource(name)) { 165 | /* if unspecified, use the highest resource */ 166 | if (user->resources != NULL) { 167 | resource = user->resources->data; 168 | res = resource->name; 169 | if (res != NULL && *res != '\0') 170 | return g_strconcat(user->jid, "/", 171 | res, (void *)NULL); 172 | } 173 | return g_strdup(user->jid); 174 | } 175 | res = xmpp_extract_resource(name); 176 | str = g_strconcat(user->jid, "/", res, (void *)NULL); 177 | g_free(res); 178 | return str; 179 | } 180 | return NULL; 181 | } 182 | 183 | char * 184 | rosters_get_name(XMPP_SERVER_REC *server, const char *full_jid) 185 | { 186 | GSList *gl, *ul; 187 | XMPP_ROSTER_GROUP_REC *group; 188 | XMPP_ROSTER_USER_REC *user; 189 | char *jid; 190 | 191 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 192 | g_return_val_if_fail(full_jid != NULL, NULL); 193 | if ((jid = xmpp_strip_resource(full_jid)) == NULL) 194 | return NULL; 195 | for (gl = server->roster; gl != NULL; gl = gl->next) { 196 | group = gl->data; 197 | for (ul = group->users; ul != NULL; ul = ul->next) { 198 | user = ul->data; 199 | if (strcmp(jid, user->jid) == 0) { 200 | g_free(jid); 201 | return user->name; 202 | } 203 | } 204 | } 205 | g_free(jid); 206 | return NULL; 207 | } 208 | 209 | int 210 | xmpp_get_show(const char *show) 211 | { 212 | if (show != NULL && *show != '\0') { 213 | if (g_ascii_strcasecmp(show, 214 | xmpp_presence_show[XMPP_PRESENCE_CHAT]) == 0) 215 | return XMPP_PRESENCE_CHAT; 216 | else if (g_ascii_strcasecmp(show, 217 | xmpp_presence_show[XMPP_PRESENCE_DND]) == 0) 218 | return XMPP_PRESENCE_DND; 219 | else if (g_ascii_strcasecmp(show, 220 | xmpp_presence_show[XMPP_PRESENCE_XA]) == 0) 221 | return XMPP_PRESENCE_XA; 222 | else if (g_ascii_strcasecmp(show, 223 | xmpp_presence_show[XMPP_PRESENCE_AWAY]) == 0) 224 | return XMPP_PRESENCE_AWAY; 225 | else if (g_ascii_strcasecmp(show, 226 | xmpp_presence_show[XMPP_PRESENCE_ONLINE]) == 0) 227 | return XMPP_PRESENCE_AVAILABLE; 228 | } 229 | return XMPP_PRESENCE_AVAILABLE; 230 | } 231 | -------------------------------------------------------------------------------- /src/core/rosters-tools.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROSTER_TOOLS_H 2 | #define __ROSTER_TOOLS_H 3 | 4 | #include "rosters.h" 5 | 6 | __BEGIN_DECLS 7 | XMPP_ROSTER_USER_REC *rosters_find_user(GSList *, const char *, 8 | XMPP_ROSTER_GROUP_REC **, 9 | XMPP_ROSTER_RESOURCE_REC **); 10 | XMPP_ROSTER_RESOURCE_REC *rosters_find_resource(GSList *, const char *); 11 | void rosters_reorder(XMPP_ROSTER_GROUP_REC *); 12 | char *rosters_resolve_name(XMPP_SERVER_REC *, const char *); 13 | char *rosters_get_name(XMPP_SERVER_REC *, const char *); 14 | int xmpp_get_show(const char *); 15 | __END_DECLS 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/core/rosters.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROSTER_H 2 | #define __ROSTER_H 3 | 4 | enum { 5 | XMPP_PRESENCE_UNAVAILABLE, 6 | XMPP_PRESENCE_ERROR, 7 | XMPP_PRESENCE_XA, 8 | XMPP_PRESENCE_DND, 9 | XMPP_PRESENCE_AWAY, 10 | XMPP_PRESENCE_AVAILABLE, 11 | XMPP_PRESENCE_CHAT, 12 | XMPP_PRESENCE_ONLINE, 13 | XMPP_PRESENCE_SHOW_LEN 14 | }; 15 | extern const char *xmpp_presence_show[]; 16 | 17 | enum { 18 | XMPP_SUBSCRIPTION_REMOVE, 19 | XMPP_SUBSCRIPTION_NONE, 20 | XMPP_SUBSCRIPTION_TO, 21 | XMPP_SUBSCRIPTION_FROM, 22 | XMPP_SUBSCRIPTION_BOTH 23 | }; 24 | extern const char *xmpp_subscription[]; 25 | 26 | /* roster structure */ 27 | typedef struct _XMPP_ROSTER_RESOURCE_REC { 28 | char *name; 29 | int priority; 30 | int show; 31 | char *status; 32 | char *composing_id; 33 | } XMPP_ROSTER_RESOURCE_REC; 34 | 35 | typedef struct _XMPP_ROSTER_USER_REC { 36 | char *jid; 37 | char *name; 38 | int subscription; 39 | gboolean error; 40 | GSList *resources; 41 | } XMPP_ROSTER_USER_REC; 42 | 43 | typedef struct _XMPP_ROSTER_GROUP_REC { 44 | char *name; 45 | GSList *users; 46 | } XMPP_ROSTER_GROUP_REC; 47 | 48 | __BEGIN_DECLS 49 | void rosters_init(void); 50 | void rosters_deinit(void); 51 | __END_DECLS 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/core/stanzas.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "settings.h" 20 | #include "signals.h" 21 | 22 | #include "xmpp-servers.h" 23 | #include "tools.h" 24 | 25 | static int message_types[] = { 26 | LM_MESSAGE_TYPE_MESSAGE, 27 | LM_MESSAGE_TYPE_PRESENCE, 28 | LM_MESSAGE_TYPE_IQ, 29 | -1 30 | }; 31 | 32 | static void 33 | send_stanza(XMPP_SERVER_REC *server, LmMessage *lmsg) 34 | { 35 | char *xml, *recoded; 36 | 37 | g_return_if_fail(IS_XMPP_SERVER(server)); 38 | g_return_if_fail(lmsg != NULL); 39 | xml = lm_message_node_to_string(lmsg->node); 40 | recoded = xmpp_recode_in(xml); 41 | g_free(xml); 42 | signal_emit("xmpp xml out", 2, server, recoded); 43 | g_free(recoded); 44 | lm_connection_send(server->lmconn, lmsg, NULL); 45 | } 46 | 47 | static LmHandlerResult 48 | handle_stanza(LmMessageHandler *handler, LmConnection *connection, 49 | LmMessage *lmsg, gpointer user_data) 50 | { 51 | XMPP_SERVER_REC *server; 52 | int type; 53 | const char *id; 54 | char *from, *to, *raw, *xml; 55 | 56 | if ((server = XMPP_SERVER(user_data)) == NULL) 57 | return LM_HANDLER_RESULT_REMOVE_MESSAGE; 58 | xml = lm_message_node_to_string(lmsg->node); 59 | raw = xmpp_recode_in(xml); 60 | signal_emit("xmpp xml in", 2, server, raw); 61 | g_free(xml); 62 | g_free(raw); 63 | type = lm_message_get_sub_type(lmsg); 64 | id = lm_message_node_get_attribute(lmsg->node, "id"); 65 | if (id == NULL) 66 | id = ""; 67 | from = xmpp_recode_in(lm_message_node_get_attribute(lmsg->node, "from")); 68 | if (from == NULL) 69 | from = g_strdup(""); 70 | to = xmpp_recode_in(lm_message_node_get_attribute(lmsg->node, "to")); 71 | if (to == NULL) 72 | to = g_strdup(""); 73 | switch(lm_message_get_type(lmsg)) { 74 | case LM_MESSAGE_TYPE_MESSAGE: 75 | signal_emit("xmpp recv message", 6, 76 | server, lmsg, type, id, from, to); 77 | break; 78 | case LM_MESSAGE_TYPE_PRESENCE: 79 | signal_emit("xmpp recv presence", 6, 80 | server, lmsg, type, id, from, to); 81 | break; 82 | case LM_MESSAGE_TYPE_IQ: 83 | signal_emit("xmpp recv iq", 6, 84 | server, lmsg, type, id, from, to); 85 | break; 86 | default: 87 | signal_emit("xmpp recv others", 6, 88 | server, lmsg, type, id, from, to); 89 | break; 90 | } 91 | g_free(from); 92 | g_free(to); 93 | return LM_HANDLER_RESULT_REMOVE_MESSAGE; 94 | } 95 | 96 | static void 97 | free_message_handler(LmMessageHandler *h) 98 | { 99 | if (lm_message_handler_is_valid(h)) 100 | lm_message_handler_invalidate(h); 101 | lm_message_handler_unref(h); 102 | } 103 | 104 | static void 105 | unregister_stanzas(XMPP_SERVER_REC *server) 106 | { 107 | if (!IS_XMPP_SERVER(server)) 108 | return; 109 | g_slist_free_full(server->msg_handlers, 110 | (GDestroyNotify)free_message_handler); 111 | server->msg_handlers = NULL; 112 | } 113 | 114 | static void 115 | register_stanzas(XMPP_SERVER_REC *server) 116 | { 117 | LmMessageHandler *h; 118 | int i; 119 | 120 | if (!IS_XMPP_SERVER(server)) 121 | return; 122 | if (server->msg_handlers != NULL && 123 | g_slist_length(server->msg_handlers) != 0) 124 | unregister_stanzas(server); 125 | for(i = 0; message_types[i] != -1; ++i) { 126 | h = lm_message_handler_new(handle_stanza, server, NULL); 127 | lm_connection_register_message_handler(server->lmconn, h, 128 | message_types[i], LM_HANDLER_PRIORITY_NORMAL); 129 | server->msg_handlers = g_slist_prepend(server->msg_handlers, h); 130 | } 131 | } 132 | 133 | void 134 | stanzas_init(void) 135 | { 136 | signal_add("server connecting", register_stanzas); 137 | signal_add_first("server disconnected", unregister_stanzas); 138 | signal_add_last("xmpp send message", send_stanza); 139 | signal_add_last("xmpp send presence", send_stanza); 140 | signal_add_last("xmpp send iq", send_stanza); 141 | signal_add_last("xmpp send others", send_stanza); 142 | } 143 | 144 | void 145 | stanzas_deinit(void) 146 | { 147 | signal_remove("server connecting", register_stanzas); 148 | signal_remove("server disconnected", unregister_stanzas); 149 | signal_remove("xmpp send message", send_stanza); 150 | signal_remove("xmpp send presence", send_stanza); 151 | signal_remove("xmpp send iq", send_stanza); 152 | signal_remove("xmpp send others", send_stanza); 153 | } 154 | -------------------------------------------------------------------------------- /src/core/stanzas.h: -------------------------------------------------------------------------------- 1 | #ifndef __STANZAS_H 2 | #define __STANZAS_H 3 | 4 | __BEGIN_DECLS 5 | void stanzas_init(void); 6 | void stanzas_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/tools.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "recode.h" 22 | #include "settings.h" 23 | #include "signals.h" 24 | 25 | #define XMPP_PRIORITY_MIN -128 26 | #define XMPP_PRIORITY_MAX 127 27 | 28 | static const char *utf8_charset = "UTF-8"; 29 | 30 | static gboolean 31 | xmpp_get_local_charset(const char **charset) 32 | { 33 | *charset = settings_get_str("term_charset"); 34 | if (is_valid_charset(*charset)) 35 | return (g_ascii_strcasecmp(*charset, utf8_charset) == 0); 36 | return g_get_charset(charset); 37 | } 38 | 39 | char * 40 | xmpp_recode_out(const char *str) 41 | { 42 | const char *charset; 43 | char *recoded, *stripped; 44 | 45 | if (str == NULL || *str == '\0') 46 | return NULL; 47 | recoded = stripped = NULL; 48 | signal_emit("xmpp formats strip codes", 2, str, &stripped); 49 | if (stripped != NULL) 50 | str = stripped; 51 | if (!xmpp_get_local_charset(&charset) && charset != NULL) 52 | recoded = g_convert_with_fallback(str, -1, utf8_charset, 53 | charset, NULL, NULL, NULL, NULL); 54 | recoded = recoded != NULL ? recoded : g_strdup(str); 55 | g_free(stripped); 56 | return recoded; 57 | } 58 | 59 | char * 60 | xmpp_recode_in(const char *str) 61 | { 62 | const char *charset; 63 | char *recoded, *to = NULL; 64 | 65 | if (str == NULL || *str == '\0') 66 | return NULL; 67 | if (xmpp_get_local_charset(&charset) || charset == NULL) 68 | return g_strdup(str); 69 | if (settings_get_bool("recode_transliterate") && 70 | g_ascii_strcasecmp(charset, "//TRANSLIT") != 0) 71 | charset = to = g_strconcat(charset ,"//TRANSLIT", (void *)NULL); 72 | recoded = g_convert_with_fallback(str, -1, charset, utf8_charset, NULL, 73 | NULL, NULL, NULL); 74 | g_free(to); 75 | return (recoded != NULL) ? recoded : g_strdup(str); 76 | } 77 | 78 | char * 79 | xmpp_find_resource_sep(const char *jid) 80 | { 81 | return jid == NULL ? NULL : g_utf8_strchr(jid, -1, '/'); 82 | } 83 | 84 | char * 85 | xmpp_extract_resource(const char *jid) 86 | { 87 | char *pos; 88 | 89 | g_return_val_if_fail(jid != NULL, NULL); 90 | pos = xmpp_find_resource_sep(jid); 91 | return (pos != NULL) ? g_strdup(pos + 1) : NULL; 92 | } 93 | 94 | char * 95 | xmpp_strip_resource(const char *jid) 96 | { 97 | char *pos; 98 | 99 | g_return_val_if_fail(jid != NULL, NULL); 100 | pos = xmpp_find_resource_sep(jid); 101 | return (pos != NULL) ? g_strndup(jid, pos - jid) : g_strdup(jid); 102 | } 103 | 104 | char * 105 | xmpp_extract_user(const char *jid) 106 | { 107 | char *pos; 108 | 109 | g_return_val_if_fail(jid != NULL, NULL); 110 | pos = g_utf8_strchr(jid, -1, '@'); 111 | return (pos != NULL) ? g_strndup(jid, pos - jid) : 112 | xmpp_strip_resource(jid); 113 | } 114 | 115 | char * 116 | xmpp_extract_domain(const char *jid) 117 | { 118 | char *pos1, *pos2; 119 | 120 | pos1 = g_utf8_strchr(jid, -1, '@'); 121 | pos2 = xmpp_find_resource_sep(jid); 122 | if (pos1 == NULL) 123 | return NULL; 124 | if (pos2 != NULL && pos2 < pos1) 125 | return g_strdup(pos1 + 1); 126 | return (pos2 != NULL) ? 127 | g_strndup(pos1 + 1, pos2 - pos1 - 1) : g_strdup(pos1 + 1); 128 | } 129 | 130 | gboolean 131 | xmpp_have_domain(const char *jid) 132 | { 133 | char *pos; 134 | 135 | g_return_val_if_fail(jid != NULL, FALSE); 136 | pos = g_utf8_strchr(jid, -1, '@'); 137 | return (pos != NULL && *(pos+1) != '\0'); 138 | } 139 | 140 | gboolean 141 | xmpp_have_resource(const char *jid) 142 | { 143 | char *pos; 144 | 145 | g_return_val_if_fail(jid != NULL, FALSE); 146 | pos = xmpp_find_resource_sep(jid); 147 | return (pos != NULL && *(pos+1) != '\0'); 148 | } 149 | 150 | gboolean 151 | xmpp_priority_out_of_bound(const int priority) 152 | { 153 | return (XMPP_PRIORITY_MIN <= priority 154 | && priority <= XMPP_PRIORITY_MAX) ? FALSE : TRUE; 155 | } 156 | 157 | gboolean 158 | xmpp_presence_changed(const int show, const int old_show, const char *status, 159 | const char *old_status, const int priority, const int old_priority) 160 | { 161 | return (show != old_show) 162 | || (status == NULL && old_status != NULL) 163 | || (status != NULL && old_status == NULL) 164 | || (status != NULL && old_status != NULL 165 | && strcmp(status, old_status) != 0) 166 | || (priority != old_priority); 167 | } 168 | -------------------------------------------------------------------------------- /src/core/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef __TOOLS_H 2 | #define __TOOLS_H 3 | 4 | __BEGIN_DECLS 5 | char *xmpp_recode_out(const char *); 6 | char *xmpp_recode_in(const char *); 7 | 8 | char *xmpp_find_resource_sep(const char *); 9 | char *xmpp_extract_resource(const char *); 10 | char *xmpp_strip_resource(const char *); 11 | char *xmpp_extract_user(const char *); 12 | char *xmpp_extract_domain(const char *); 13 | gboolean xmpp_have_domain(const char *); 14 | gboolean xmpp_have_resource(const char *); 15 | gboolean xmpp_priority_out_of_bound(const int); 16 | gboolean xmpp_presence_changed(const int, const int, const char *, 17 | const char *, const int, const int); 18 | __END_DECLS 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/core/xep/chatstates.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0085: Chat State Notifications 20 | */ 21 | 22 | #include "module.h" 23 | #include "signals.h" 24 | 25 | #include "xmpp-servers.h" 26 | #include "disco.h" 27 | 28 | #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" 29 | 30 | static void 31 | sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 32 | const char *id, const char *from, const char *to) 33 | { 34 | if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET 35 | && type != LM_MESSAGE_SUB_TYPE_HEADLINE 36 | && type != LM_MESSAGE_SUB_TYPE_NORMAL 37 | && type != LM_MESSAGE_SUB_TYPE_CHAT) 38 | || server->ischannel(SERVER(server), from)) 39 | return; 40 | if (lm_find_node(lmsg->node, "composing", XMLNS, 41 | XMLNS_CHATSTATES) != NULL) { 42 | signal_emit("xmpp composing show", 2, server, from); 43 | } else if (lm_find_node(lmsg->node, "active", XMLNS, 44 | XMLNS_CHATSTATES) != NULL 45 | || lm_find_node(lmsg->node, "paused", XMLNS, 46 | XMLNS_CHATSTATES) != NULL) 47 | signal_emit("xmpp composing hide", 2, server, from); 48 | } 49 | 50 | void 51 | chatstates_init(void) 52 | { 53 | disco_add_feature(XMLNS_CHATSTATES); 54 | signal_add("xmpp recv message", sig_recv_message); 55 | } 56 | 57 | void 58 | chatstates_deinit(void) 59 | { 60 | signal_remove("xmpp recv message", sig_recv_message); 61 | } 62 | -------------------------------------------------------------------------------- /src/core/xep/chatstates.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHATSTATES_H 2 | #define __CHATSTATES_H 3 | 4 | __BEGIN_DECLS 5 | void chatstates_init(void); 6 | void chatstates_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/composing.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0022: Message Events 20 | */ 21 | 22 | #include 23 | 24 | #include "module.h" 25 | #include "signals.h" 26 | 27 | #include "xmpp-servers.h" 28 | #include "xmpp-queries.h" 29 | #include "tools.h" 30 | #include "tool_datalist.h" 31 | #include "disco.h" 32 | 33 | #define XMLNS_EVENT "jabber:x:event" 34 | 35 | static DATALIST *composings; 36 | 37 | #define send_start(server, dest, id) \ 38 | send_composing_event(server, dest, id, TRUE) 39 | #define send_stop(server, dest, id) \ 40 | send_composing_event(server, dest, id, FALSE) 41 | 42 | static void 43 | send_composing_event(XMPP_SERVER_REC *server, const char *dest, const char *id, 44 | gboolean composing) 45 | { 46 | LmMessage *lmsg; 47 | LmMessageNode *node; 48 | char *recoded; 49 | 50 | recoded = xmpp_recode_out(dest); 51 | lmsg = lm_message_new_with_sub_type(recoded, 52 | LM_MESSAGE_TYPE_MESSAGE, LM_MESSAGE_SUB_TYPE_CHAT); 53 | g_free(recoded); 54 | node = lm_message_node_add_child(lmsg->node, "x", NULL); 55 | lm_message_node_set_attribute(node, XMLNS, XMLNS_EVENT); 56 | if (composing) 57 | lm_message_node_add_child(node, "composing", NULL); 58 | if (id != NULL) 59 | lm_message_node_add_child(node, "id", id); 60 | signal_emit("xmpp send message", 2, server, lmsg); 61 | lm_message_unref(lmsg); 62 | } 63 | 64 | static void 65 | sig_composing_start(XMPP_SERVER_REC *server, const char *dest) 66 | { 67 | DATALIST_REC *rec; 68 | 69 | g_return_if_fail(IS_XMPP_SERVER(server)); 70 | g_return_if_fail(dest != NULL); 71 | if ((rec = datalist_find(composings, server, dest)) != NULL) 72 | send_start(server, dest, rec->data); 73 | } 74 | 75 | static void 76 | sig_composing_stop(XMPP_SERVER_REC *server, const char *dest) 77 | { 78 | DATALIST_REC *rec; 79 | 80 | g_return_if_fail(IS_XMPP_SERVER(server)); 81 | g_return_if_fail(dest != NULL); 82 | if ((rec = datalist_find(composings, server, dest)) != NULL) 83 | send_stop(server, dest, rec->data); 84 | } 85 | 86 | static void 87 | sig_composing_show(XMPP_SERVER_REC *server, const char *dest) 88 | { 89 | XMPP_QUERY_REC *query; 90 | 91 | if ((query = xmpp_query_find(server, dest)) != NULL) 92 | query->composing_visible = TRUE; 93 | } 94 | 95 | static void 96 | sig_composing_hide(XMPP_SERVER_REC *server, const char *dest) 97 | { 98 | XMPP_QUERY_REC *query; 99 | 100 | if ((query = xmpp_query_find(server, dest)) != NULL) 101 | query->composing_visible = FALSE; 102 | } 103 | 104 | static void 105 | sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 106 | const char *id, const char *from, const char *to) 107 | { 108 | LmMessageNode *node; 109 | 110 | if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET 111 | && type != LM_MESSAGE_SUB_TYPE_HEADLINE 112 | && type != LM_MESSAGE_SUB_TYPE_NORMAL 113 | && type != LM_MESSAGE_SUB_TYPE_CHAT) 114 | || server->ischannel(SERVER(server), from)) 115 | return; 116 | node = lm_find_node(lmsg->node, "x", XMLNS, XMLNS_EVENT); 117 | if (node == NULL) { 118 | signal_emit("xmpp composing hide", 2, server, from); 119 | return; 120 | } 121 | if (lm_message_node_get_child(lmsg->node, "body") != NULL 122 | || lm_message_node_get_child(lmsg->node, "subject") != NULL) { 123 | if (lm_message_node_get_child(node, "composing") != NULL) 124 | datalist_add(composings, server, from, g_strdup(id)); 125 | else 126 | datalist_remove(composings, server, from); 127 | signal_emit("xmpp composing hide", 2, server, from); 128 | } else { 129 | if (lm_message_node_get_child(node, "composing") != NULL) 130 | signal_emit("xmpp composing show", 2, server, from); 131 | else 132 | signal_emit("xmpp composing hide", 2, server, from); 133 | } 134 | } 135 | 136 | static void 137 | sig_send_message(XMPP_SERVER_REC *server, LmMessage *lmsg) 138 | { 139 | LmMessageNode *node; 140 | LmMessageSubType type; 141 | 142 | type = lm_message_get_sub_type(lmsg); 143 | if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET 144 | && type != LM_MESSAGE_SUB_TYPE_HEADLINE 145 | && type != LM_MESSAGE_SUB_TYPE_NORMAL 146 | && type != LM_MESSAGE_SUB_TYPE_CHAT) 147 | || (lm_message_node_get_child(lmsg->node, "body") == NULL 148 | && lm_message_node_get_child(lmsg->node, "subject") == NULL)) 149 | return; 150 | /* request composing events */ 151 | node = lm_message_node_add_child(lmsg->node, "x", NULL); 152 | lm_message_node_set_attribute(node, XMLNS, XMLNS_EVENT); 153 | lm_message_node_add_child(node, "composing", NULL); 154 | } 155 | 156 | static void 157 | sig_offline(XMPP_SERVER_REC *server, const char *jid) 158 | { 159 | g_return_if_fail(IS_XMPP_SERVER(server)); 160 | datalist_remove(composings, server, jid); 161 | } 162 | 163 | static void 164 | sig_disconnected(XMPP_SERVER_REC *server) 165 | { 166 | if (IS_XMPP_SERVER(server)) 167 | datalist_cleanup(composings, server); 168 | } 169 | 170 | static void 171 | freedata_func(DATALIST_REC *rec) 172 | { 173 | g_free(rec->data); 174 | } 175 | 176 | void 177 | composing_init(void) 178 | { 179 | composings = datalist_new(freedata_func); 180 | disco_add_feature(XMLNS_EVENT); 181 | signal_add("xmpp composing start", sig_composing_start); 182 | signal_add("xmpp composing stop", sig_composing_stop); 183 | signal_add("xmpp composing show", sig_composing_show); 184 | signal_add("xmpp composing hide", sig_composing_hide); 185 | signal_add("xmpp recv message", sig_recv_message); 186 | signal_add("xmpp send message", sig_send_message); 187 | signal_add("xmpp presence offline", sig_offline); 188 | signal_add("server disconnected", sig_disconnected); 189 | } 190 | 191 | void 192 | composing_deinit(void) 193 | { 194 | signal_remove("xmpp composing start", sig_composing_start); 195 | signal_remove("xmpp composing stop", sig_composing_stop); 196 | signal_remove("xmpp composing show", sig_composing_show); 197 | signal_remove("xmpp composing hide", sig_composing_hide); 198 | signal_remove("xmpp recv message", sig_recv_message); 199 | signal_remove("xmpp send message", sig_send_message); 200 | signal_remove("xmpp presence offline", sig_offline); 201 | signal_remove("server disconnected", sig_disconnected); 202 | datalist_destroy(composings); 203 | } 204 | -------------------------------------------------------------------------------- /src/core/xep/composing.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPOSING_H 2 | #define __COMPOSING_H 3 | 4 | __BEGIN_DECLS 5 | void composing_init(void); 6 | void composing_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/datetime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0082: XMPP Date and Time Profiles 20 | */ 21 | 22 | #ifdef __linux__ 23 | #define _XOPEN_SOURCE 24 | #endif 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define FORMAT "%Y-%m-%dT%T" 32 | 33 | #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 34 | 35 | static long 36 | parse_timezone(const char *tz) 37 | { 38 | const char *rfc822_timezones[][4] = { 39 | { "M", NULL }, /* UTC-12 */ 40 | { "L", NULL }, 41 | { "K", NULL }, 42 | { "I", NULL }, 43 | { "H", "PST", NULL }, /* UTC-8 */ 44 | { "G", "MST", "PDT", NULL }, /* UTC-7 */ 45 | { "F", "CST", "MDT", NULL }, /* UTC-6 */ 46 | { "E", "EST", "CDT", NULL }, /* UTC-5 */ 47 | { "D", "EDT", NULL }, /* UTC-4 */ 48 | { "C", NULL }, 49 | { "B", NULL }, 50 | { "A", NULL }, 51 | { "Z", "UT", "GMT", NULL }, /* UTC */ 52 | { "N", NULL }, 53 | { "O", NULL }, 54 | { "P", NULL }, 55 | { "Q", NULL }, 56 | { "R", NULL }, 57 | { "S", NULL }, 58 | { "T", NULL }, 59 | { "U", NULL }, 60 | { "V", NULL }, 61 | { "W", NULL }, 62 | { "X", NULL }, 63 | { "Y", NULL }, /* UTC+12 */ 64 | { NULL }, 65 | }; 66 | unsigned int i, j; 67 | 68 | if ((*tz == '+' || *tz == '-') && strlen(tz) == 5) { 69 | i = atoi(tz); 70 | return ((i/100)*60 + i%100) * 60; 71 | } 72 | for (i = 0; i < nitems(rfc822_timezones); ++i) 73 | for (j = 0; rfc822_timezones[i][j] != NULL; ++j) 74 | if (strcmp(rfc822_timezones[i][j], tz) == 0) 75 | return (i - 12) * 3600; 76 | return 0; 77 | } 78 | 79 | time_t 80 | xep82_datetime(const char *stamp) 81 | { 82 | struct tm tm; 83 | long offset; 84 | char *s; 85 | 86 | memset(&tm, 0, sizeof(struct tm)); 87 | if ((s = strptime(stamp, FORMAT, &tm)) == NULL) 88 | return (time_t)-1; 89 | /* ignore fractional second addendum */ 90 | if (*s++ == '.') 91 | while (isdigit(*s)) s++; 92 | tm.tm_isdst = -1; 93 | offset = *s != '\0' ? parse_timezone(s) : 0; 94 | return mktime(&tm) - offset; 95 | } 96 | -------------------------------------------------------------------------------- /src/core/xep/datetime.h: -------------------------------------------------------------------------------- 1 | #ifndef __DATETIME_H 2 | #define __DATETIME_H 3 | 4 | __BEGIN_DECLS 5 | time_t xep82_datetime(const char *); 6 | __END_DECLS 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/core/xep/delay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0203: Delayed Delivery 20 | */ 21 | 22 | #include "module.h" 23 | #include "signals.h" 24 | 25 | #include "xmpp-servers.h" 26 | #include "tools.h" 27 | #include "datetime.h" 28 | #include "disco.h" 29 | #include "muc.h" 30 | 31 | #define XMLNS_DELAY "urn:xmpp:delay" 32 | #define XMLNS_OLD_DELAY "jabber:x:delay" 33 | 34 | static void 35 | sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 36 | const char *id, const char *from, const char *to) 37 | { 38 | LmMessageNode *node; 39 | MUC_REC *channel; 40 | const char *stamp; 41 | char *nick, *str; 42 | time_t t; 43 | 44 | node = lm_find_node(lmsg->node, "delay", "xmlns", XMLNS_DELAY); 45 | if (node == NULL) { 46 | /* XEP-0091: Delayed Delivery (deprecated) */ 47 | node = lm_find_node(lmsg->node, "x", "xmlns", XMLNS_OLD_DELAY); 48 | if (node == NULL) 49 | return; 50 | } 51 | stamp = lm_message_node_get_attribute(node, "stamp"); 52 | if ((t = xep82_datetime(stamp)) == (time_t)-1) 53 | return; 54 | node = lm_message_node_get_child(lmsg->node, "body"); 55 | if (node == NULL || node->value == NULL || *node->value == '\0') 56 | return; 57 | if (type == LM_MESSAGE_SUB_TYPE_GROUPCHAT 58 | && (channel = get_muc(server, from)) != NULL 59 | && (nick = muc_extract_nick(from)) != NULL) { 60 | str = xmpp_recode_in(node->value); 61 | if (g_ascii_strncasecmp(str, "/me ", 4) == 0) 62 | signal_emit("message xmpp delay action", 6, 63 | server, str+4, nick, channel->name, &t, 64 | GINT_TO_POINTER(SEND_TARGET_CHANNEL)); 65 | else 66 | signal_emit("message xmpp delay", 6, server, 67 | str, nick, channel->name, &t, 68 | GINT_TO_POINTER(SEND_TARGET_CHANNEL)); 69 | g_free(str); 70 | g_free(nick); 71 | } else if ((type == LM_MESSAGE_SUB_TYPE_NOT_SET 72 | || type == LM_MESSAGE_SUB_TYPE_HEADLINE 73 | || type == LM_MESSAGE_SUB_TYPE_NORMAL 74 | || type == LM_MESSAGE_SUB_TYPE_CHAT)) { 75 | str = xmpp_recode_in(node->value); 76 | if (g_ascii_strncasecmp(str, "/me ", 4) == 0) 77 | signal_emit("message xmpp delay action", 6, 78 | server, str+4, from, from, &t, 79 | GINT_TO_POINTER(SEND_TARGET_NICK)); 80 | else 81 | signal_emit("message xmpp delay", 6, server, 82 | str, from, from, &t, 83 | GINT_TO_POINTER(SEND_TARGET_NICK)); 84 | g_free(str); 85 | } else 86 | return; 87 | signal_stop(); 88 | } 89 | 90 | void 91 | delay_init(void) 92 | { 93 | disco_add_feature(XMLNS_DELAY); 94 | signal_add_first("xmpp recv message", sig_recv_message); 95 | } 96 | 97 | void 98 | delay_deinit(void) 99 | { 100 | signal_remove("xmpp recv message", sig_recv_message); 101 | } 102 | -------------------------------------------------------------------------------- /src/core/xep/delay.h: -------------------------------------------------------------------------------- 1 | #ifndef __DELAY_H 2 | #define __DELAY_H 3 | 4 | __BEGIN_DECLS 5 | void delay_init(void); 6 | void delay_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/disco.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* XEP-0030: Service Discovery */ 19 | 20 | #include 21 | 22 | #include "module.h" 23 | #include "signals.h" 24 | 25 | #include "xmpp-servers.h" 26 | #include "tools.h" 27 | #include "disco.h" 28 | 29 | #define XMLNS_DISCO "http://jabber.org/protocol/disco#info" 30 | 31 | static GSList *my_features; 32 | 33 | void 34 | disco_add_feature(char *feature) 35 | { 36 | g_return_if_fail(feature != NULL && *feature != '\0'); 37 | my_features = g_slist_insert_sorted(my_features, feature, 38 | (GCompareFunc)strcmp); 39 | } 40 | 41 | gboolean 42 | disco_have_feature(GSList *list, const char *feature) 43 | { 44 | GSList *tmp; 45 | 46 | for (tmp = list; tmp != NULL; tmp = tmp->next) 47 | if (strcmp(feature, tmp->data) == 0) 48 | return TRUE; 49 | return FALSE; 50 | } 51 | 52 | static void 53 | cleanup_features(GSList *list) 54 | { 55 | g_slist_free_full(list, g_free); 56 | } 57 | 58 | void 59 | disco_request(XMPP_SERVER_REC *server, const char *dest) 60 | { 61 | LmMessage *lmsg; 62 | LmMessageNode *node; 63 | char *recoded; 64 | 65 | g_return_if_fail(IS_XMPP_SERVER(server)); 66 | g_return_if_fail(dest != NULL && *dest != '\0'); 67 | recoded = xmpp_recode_out(dest); 68 | lmsg = lm_message_new_with_sub_type(recoded, LM_MESSAGE_TYPE_IQ, 69 | LM_MESSAGE_SUB_TYPE_GET); 70 | g_free(recoded); 71 | node = lm_message_node_add_child(lmsg->node, "query", NULL); 72 | lm_message_node_set_attribute(node, XMLNS, XMLNS_DISCO); 73 | signal_emit("xmpp send iq", 2, server, lmsg); 74 | lm_message_unref(lmsg); 75 | } 76 | 77 | static void 78 | send_disco(XMPP_SERVER_REC *server, const char *dest) 79 | { 80 | LmMessage *lmsg; 81 | LmMessageNode *node, *child; 82 | GSList *tmp; 83 | char *recoded; 84 | 85 | recoded = xmpp_recode_out(dest); 86 | lmsg = lm_message_new_with_sub_type(recoded, LM_MESSAGE_TYPE_IQ, 87 | LM_MESSAGE_SUB_TYPE_RESULT); 88 | g_free(recoded); 89 | node = lm_message_node_add_child(lmsg->node, "query", NULL); 90 | lm_message_node_set_attribute(node, XMLNS, XMLNS_DISCO); 91 | child = lm_message_node_add_child(node, "identity", NULL); 92 | lm_message_node_set_attribute(child, "category", "client"); 93 | lm_message_node_set_attribute(child, "type", "console"); 94 | lm_message_node_set_attribute(child, "name", IRSSI_XMPP_PACKAGE); 95 | for (tmp = my_features; tmp != NULL; tmp = tmp->next) { 96 | child = lm_message_node_add_child(node, "feature", NULL); 97 | lm_message_node_set_attribute(child, "var", tmp->data); 98 | } 99 | signal_emit("xmpp send iq", 2, server, lmsg); 100 | lm_message_unref(lmsg); 101 | } 102 | 103 | static void 104 | sig_recv_iq(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 105 | const char *id, const char *from, const char *to) 106 | { 107 | LmMessageNode *node; 108 | GSList *features; 109 | 110 | if (type == LM_MESSAGE_SUB_TYPE_RESULT) { 111 | node = lm_find_node(lmsg->node, "query", XMLNS, XMLNS_DISCO); 112 | if (node == NULL) 113 | return; 114 | features = NULL; 115 | for (node = node->children; node != NULL; node = node->next) { 116 | if (strcmp(node->name, "feature") == 0) { 117 | features = g_slist_prepend(features, 118 | xmpp_recode_in( 119 | lm_message_node_get_attribute(node, "var"))); 120 | } 121 | } 122 | signal_emit("xmpp features", 3, server, from, features); 123 | if (strcmp(from, server->domain) == 0) { 124 | cleanup_features(server->server_features); 125 | server->server_features = features; 126 | signal_emit("xmpp server features", 1, server); 127 | } else 128 | cleanup_features(features); 129 | } else if (type == LM_MESSAGE_SUB_TYPE_GET) { 130 | node = lm_find_node(lmsg->node, "query", XMLNS, XMLNS_DISCO); 131 | if (node != NULL) 132 | send_disco(server, from); 133 | } 134 | } 135 | 136 | static void 137 | sig_connected(XMPP_SERVER_REC *server) 138 | { 139 | if (IS_XMPP_SERVER(server)) 140 | disco_request(server, server->domain); 141 | } 142 | 143 | static void 144 | sig_disconnected(XMPP_SERVER_REC *server) 145 | { 146 | if (!IS_XMPP_SERVER(server)) 147 | return; 148 | cleanup_features(server->server_features); 149 | server->server_features = NULL; 150 | } 151 | 152 | static void 153 | sig_disco_add_feature(const char *feature) 154 | { 155 | disco_add_feature(g_strdup(feature)); 156 | } 157 | 158 | void 159 | disco_init(void) 160 | { 161 | my_features = NULL; 162 | disco_add_feature(XMLNS_DISCO); 163 | signal_add("server connected", sig_connected); 164 | signal_add("server disconnected", sig_disconnected); 165 | signal_add("xmpp recv iq", sig_recv_iq); 166 | signal_add("xmpp register feature", sig_disco_add_feature); 167 | } 168 | 169 | void 170 | disco_deinit(void) 171 | { 172 | signal_remove("server connected", sig_connected); 173 | signal_remove("server disconnected", sig_disconnected); 174 | signal_remove("xmpp recv iq", sig_recv_iq); 175 | g_slist_free(my_features); 176 | } 177 | -------------------------------------------------------------------------------- /src/core/xep/disco.h: -------------------------------------------------------------------------------- 1 | #ifndef __DISCO_H 2 | #define __DISCO_H 3 | 4 | __BEGIN_DECLS 5 | void disco_add_feature(char *); 6 | gboolean disco_have_feature(GSList *, const char *); 7 | void disco_request(XMPP_SERVER_REC *, const char *); 8 | 9 | void disco_init(void); 10 | void disco_deinit(void); 11 | __END_DECLS 12 | 13 | #define XMLNS "xmlns" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/core/xep/muc-affiliation.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | 22 | #include "muc-affiliation.h" 23 | 24 | const char *xmpp_affiliation[] = { 25 | "none", 26 | "owner", 27 | "admin", 28 | "member", 29 | "outcast", 30 | NULL 31 | }; 32 | 33 | int 34 | xmpp_nicklist_get_affiliation(const char *affiliation) 35 | { 36 | if (affiliation != NULL) { 37 | if (g_ascii_strcasecmp(affiliation, 38 | xmpp_affiliation[XMPP_AFFILIATION_OWNER]) == 0) 39 | return XMPP_AFFILIATION_OWNER; 40 | else if (g_ascii_strcasecmp(affiliation, 41 | xmpp_affiliation[XMPP_AFFILIATION_ADMIN]) == 0) 42 | return XMPP_AFFILIATION_ADMIN; 43 | else if (g_ascii_strcasecmp(affiliation, 44 | xmpp_affiliation[XMPP_AFFILIATION_MEMBER]) == 0) 45 | return XMPP_AFFILIATION_MEMBER; 46 | else if (g_ascii_strcasecmp(affiliation, 47 | xmpp_affiliation[XMPP_AFFILIATION_OUTCAST]) == 0) 48 | return XMPP_AFFILIATION_OUTCAST; 49 | } 50 | return XMPP_AFFILIATION_NONE; 51 | } 52 | -------------------------------------------------------------------------------- /src/core/xep/muc-affiliation.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_AFFILIATION_H 2 | #define __MUC_AFFILIATION_H 3 | 4 | enum { 5 | XMPP_AFFILIATION_NONE, 6 | XMPP_AFFILIATION_OWNER, 7 | XMPP_AFFILIATION_ADMIN, 8 | XMPP_AFFILIATION_MEMBER, 9 | XMPP_AFFILIATION_OUTCAST 10 | }; 11 | extern const char *xmpp_affiliation[]; 12 | 13 | __BEGIN_DECLS 14 | int xmpp_nicklist_get_affiliation(const char *); 15 | __END_DECLS 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/core/xep/muc-commands.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_COMMANDS_H 2 | #define __MUC_COMMANDS_H 3 | 4 | __BEGIN_DECLS 5 | void muc_commands_init(void); 6 | void muc_commands_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/muc-events.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_EVENTS_H 2 | #define __MUC_EVENTS_H 3 | 4 | __BEGIN_DECLS 5 | void muc_events_init(void); 6 | void muc_events_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/muc-nicklist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "signals.h" 22 | 23 | #include "rosters.h" 24 | #include "muc-affiliation.h" 25 | #include "muc-nicklist.h" 26 | #include "muc-role.h" 27 | 28 | XMPP_NICK_REC * 29 | xmpp_nicklist_insert(MUC_REC *channel, const char *nickname, 30 | const char *full_jid) 31 | { 32 | XMPP_NICK_REC *rec; 33 | 34 | g_return_val_if_fail(IS_MUC(channel), NULL); 35 | g_return_val_if_fail(nickname != NULL, NULL); 36 | rec = g_new0(XMPP_NICK_REC, 1); 37 | rec->nick = g_strdup(nickname); 38 | rec->host = (full_jid != NULL) ? 39 | g_strdup(full_jid) : g_strconcat(channel->name, "/", rec->nick, (void *)NULL); 40 | rec->show = XMPP_PRESENCE_AVAILABLE; 41 | rec->status = NULL; 42 | rec->affiliation = XMPP_AFFILIATION_NONE; 43 | rec->role = XMPP_ROLE_NONE; 44 | nicklist_insert(CHANNEL(channel), (NICK_REC *)rec); 45 | return rec; 46 | } 47 | 48 | static void 49 | nick_hash_add(CHANNEL_REC *channel, NICK_REC *nick) 50 | { 51 | NICK_REC *list; 52 | 53 | nick->next = NULL; 54 | list = g_hash_table_lookup(channel->nicks, nick->nick); 55 | if (list == NULL) 56 | g_hash_table_insert(channel->nicks, nick->nick, nick); 57 | else { 58 | /* multiple nicks with same name */ 59 | while (list->next != NULL) 60 | list = list->next; 61 | list->next = nick; 62 | } 63 | /* move our own nick to beginning of the nick list.. */ 64 | if (nick == channel->ownnick) 65 | nicklist_set_own(channel, nick); 66 | } 67 | 68 | static void 69 | nick_hash_remove(CHANNEL_REC *channel, NICK_REC *nick) 70 | { 71 | NICK_REC *list; 72 | 73 | list = g_hash_table_lookup(channel->nicks, nick->nick); 74 | if (list == NULL) 75 | return; 76 | if (list == nick || list->next == NULL) { 77 | g_hash_table_remove(channel->nicks, nick->nick); 78 | if (list->next != NULL) 79 | g_hash_table_insert(channel->nicks, nick->next->nick, 80 | nick->next); 81 | } else { 82 | while (list->next != nick) 83 | list = list->next; 84 | list->next = nick->next; 85 | } 86 | } 87 | 88 | void 89 | xmpp_nicklist_rename(MUC_REC *channel, XMPP_NICK_REC *nick, 90 | const char *oldnick, const char *newnick) 91 | { 92 | 93 | g_return_if_fail(IS_MUC(channel)); 94 | g_return_if_fail(IS_XMPP_NICK(nick)); 95 | g_return_if_fail(oldnick != NULL); 96 | g_return_if_fail(newnick != NULL); 97 | /* remove old nick from hash table */ 98 | nick_hash_remove(CHANNEL(channel), NICK(nick)); 99 | g_free(nick->nick); 100 | nick->nick = g_strdup(newnick); 101 | /* add new nick to hash table */ 102 | nick_hash_add(CHANNEL(channel), NICK(nick)); 103 | signal_emit("nicklist changed", 3, channel, nick, oldnick); 104 | if (strcmp(oldnick, channel->nick) == 0) { 105 | nicklist_set_own(CHANNEL(channel), NICK(nick)); 106 | g_free(channel->nick); 107 | channel->nick = g_strdup(newnick); 108 | } 109 | } 110 | 111 | gboolean 112 | xmpp_nicklist_modes_changed(XMPP_NICK_REC *nick, int affiliation, int role) 113 | { 114 | g_return_val_if_fail(IS_XMPP_NICK(nick), FALSE); 115 | return nick->affiliation != affiliation || nick->role != role; 116 | } 117 | 118 | void 119 | xmpp_nicklist_set_modes(XMPP_NICK_REC *nick, int affiliation, int role) 120 | { 121 | g_return_if_fail(IS_XMPP_NICK(nick)); 122 | 123 | nick->affiliation = affiliation; 124 | nick->role = role; 125 | switch (affiliation) { 126 | case XMPP_AFFILIATION_OWNER: 127 | nick->prefixes[0] = '&'; 128 | nick->prefixes[1] = '\0'; 129 | nick->op = TRUE; 130 | break; 131 | case XMPP_AFFILIATION_ADMIN: 132 | nick->prefixes[0] = '\0'; 133 | nick->op = TRUE; 134 | break; 135 | default: 136 | nick->prefixes[0] = '\0'; 137 | nick->op = FALSE; 138 | } 139 | switch (role) { 140 | case XMPP_ROLE_MODERATOR: 141 | nick->voice = TRUE; 142 | nick->halfop = TRUE; 143 | break; 144 | case XMPP_ROLE_PARTICIPANT: 145 | nick->halfop = FALSE; 146 | nick->voice = TRUE; 147 | break; 148 | default: 149 | nick->halfop = FALSE; 150 | nick->voice = FALSE; 151 | } 152 | } 153 | 154 | void 155 | xmpp_nicklist_set_presence(XMPP_NICK_REC *nick, int show, const char *status) 156 | { 157 | g_return_if_fail(IS_XMPP_NICK(nick)); 158 | nick->show = show; 159 | g_free(nick->status); 160 | nick->status = g_strdup(status); 161 | } 162 | 163 | static void 164 | sig_nicklist_remove(MUC_REC *channel, XMPP_NICK_REC *nick) 165 | { 166 | if (!IS_MUC(channel) || !IS_XMPP_NICK(nick)) 167 | return; 168 | g_free(nick->status); 169 | } 170 | 171 | void 172 | muc_nicklist_init(void) 173 | { 174 | signal_add("nicklist remove", sig_nicklist_remove); 175 | } 176 | 177 | void 178 | muc_nicklist_deinit(void) 179 | { 180 | signal_remove("nicklist remove", sig_nicklist_remove); 181 | } 182 | -------------------------------------------------------------------------------- /src/core/xep/muc-nicklist.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_NICKLIST_H 2 | #define __MUC_NICKLIST_H 3 | 4 | #include "nicklist.h" 5 | #include "muc.h" 6 | 7 | /* Returns XMPP_NICK_REC if it's XMPP channel, NULL if it isn't. */ 8 | #define XMPP_NICK(nick) \ 9 | PROTO_CHECK_CAST(NICK(nick), XMPP_NICK_REC, chat_type, "XMPP") 10 | 11 | #define IS_XMPP_NICK(nick) \ 12 | (XMPP_NICK(nick) ? TRUE : FALSE) 13 | 14 | #define xmpp_nicklist_find(channel, name) \ 15 | XMPP_NICK(nicklist_find(CHANNEL(channel), name)) 16 | 17 | 18 | struct _XMPP_NICK_REC { 19 | #include "nick-rec.h" 20 | 21 | int show; 22 | char *status; 23 | 24 | int affiliation; 25 | int role; 26 | }; 27 | 28 | __BEGIN_DECLS 29 | XMPP_NICK_REC *xmpp_nicklist_insert(MUC_REC *, const char *, const char *); 30 | void xmpp_nicklist_rename(MUC_REC *, XMPP_NICK_REC *, const char *, 31 | const char *); 32 | gboolean xmpp_nicklist_modes_changed(XMPP_NICK_REC *, int, int); 33 | void xmpp_nicklist_set_modes(XMPP_NICK_REC *, int, int); 34 | void xmpp_nicklist_set_presence(XMPP_NICK_REC *, int, 35 | const char *); 36 | 37 | void muc_nicklist_init(void); 38 | void muc_nicklist_deinit(void); 39 | __END_DECLS 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/core/xep/muc-reconnect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "servers-reconnect.h" 20 | #include "signals.h" 21 | 22 | #include "xmpp-servers.h" 23 | #include "muc.h" 24 | 25 | static void 26 | sig_conn_copy(SERVER_CONNECT_REC **dest, XMPP_SERVER_CONNECT_REC *src) 27 | { 28 | GSList *tmp; 29 | XMPP_SERVER_CONNECT_REC *conn; 30 | 31 | g_return_if_fail(dest != NULL); 32 | if (!IS_XMPP_SERVER_CONNECT(src)) 33 | return; 34 | conn = (XMPP_SERVER_CONNECT_REC *)*dest; 35 | conn->channels_list = NULL; 36 | for (tmp = src->channels_list; tmp != NULL; tmp = tmp->next) { 37 | conn->channels_list = g_slist_append(conn->channels_list, 38 | g_strdup(tmp->data)); 39 | } 40 | } 41 | 42 | static void 43 | sig_conn_remove(RECONNECT_REC *rec) 44 | { 45 | XMPP_SERVER_CONNECT_REC *conn; 46 | 47 | if (!IS_XMPP_SERVER_CONNECT(rec->conn)) 48 | return; 49 | conn = XMPP_SERVER_CONNECT(rec->conn); 50 | if (conn->channels_list != NULL) { 51 | g_slist_foreach(conn->channels_list, (GFunc)g_free, NULL); 52 | g_slist_free(conn->channels_list); 53 | conn->channels_list = NULL; 54 | } 55 | } 56 | 57 | static void 58 | save_channels(XMPP_SERVER_REC *server, XMPP_SERVER_CONNECT_REC *conn) 59 | { 60 | GSList *tmp; 61 | MUC_REC *channel; 62 | char *joindata; 63 | 64 | if (conn->channels_list != NULL) { 65 | g_slist_foreach(conn->channels_list, (GFunc)g_free, NULL); 66 | g_slist_free(conn->channels_list); 67 | conn->channels_list = NULL; 68 | } 69 | for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { 70 | channel = tmp->data; 71 | joindata = channel->get_join_data(CHANNEL(channel)); 72 | conn->channels_list = g_slist_append(conn->channels_list, 73 | joindata); 74 | } 75 | } 76 | 77 | static void 78 | restore_channels(XMPP_SERVER_REC *server) 79 | { 80 | GSList *tmp; 81 | 82 | if (server->connrec->channels_list != NULL) 83 | return; 84 | for (tmp = server->connrec->channels_list; tmp != NULL; 85 | tmp = tmp->next) { 86 | muc_join(server, tmp->data, TRUE); 87 | g_free(tmp->data); 88 | } 89 | g_slist_free(server->connrec->channels_list); 90 | server->connrec->channels_list = NULL; 91 | } 92 | 93 | static void 94 | sig_save_status(XMPP_SERVER_CONNECT_REC *conn, 95 | XMPP_SERVER_REC *server) 96 | { 97 | if (!IS_XMPP_SERVER_CONNECT(conn) || !IS_XMPP_SERVER(server) 98 | || !server->connected) 99 | return; 100 | save_channels(server, conn); 101 | } 102 | 103 | static void 104 | sig_connected(XMPP_SERVER_REC *server) 105 | { 106 | if (!IS_XMPP_SERVER(server) || !server->connrec->reconnection) 107 | return; 108 | restore_channels(server); 109 | } 110 | 111 | void 112 | muc_reconnect_init(void) 113 | { 114 | signal_add_last("server connect copy", sig_conn_copy); 115 | signal_add("server reconnect remove", sig_conn_remove); 116 | signal_add("server reconnect save status", sig_save_status); 117 | signal_add_last("server connected", sig_connected); 118 | } 119 | 120 | void 121 | muc_reconnect_deinit(void) 122 | { 123 | signal_remove("server connect copy", sig_conn_copy); 124 | signal_remove("server reconnect remove", sig_conn_remove); 125 | signal_remove("server reconnect save status", sig_save_status); 126 | signal_remove("server connected", sig_connected); 127 | } 128 | -------------------------------------------------------------------------------- /src/core/xep/muc-reconnect.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_RECONNECT_H 2 | #define __MUC_RECONNECT_H 3 | 4 | __BEGIN_DECLS 5 | void muc_reconnect_init(void); 6 | void muc_reconnect_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/muc-role.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include "muc-role.h" 23 | 24 | const char *xmpp_role[] = { 25 | "none", 26 | "moderator", 27 | "participant", 28 | "visitor", 29 | NULL 30 | }; 31 | 32 | int 33 | xmpp_nicklist_get_role(const char *role) 34 | { 35 | if (role != NULL) { 36 | if (g_ascii_strcasecmp(role, 37 | xmpp_role[XMPP_ROLE_MODERATOR]) == 0) 38 | return XMPP_ROLE_MODERATOR; 39 | else if (g_ascii_strcasecmp(role, 40 | xmpp_role[XMPP_ROLE_PARTICIPANT]) == 0) 41 | return XMPP_ROLE_PARTICIPANT; 42 | else if (g_ascii_strcasecmp(role, 43 | xmpp_role[XMPP_ROLE_VISITOR]) == 0) 44 | return XMPP_ROLE_VISITOR; 45 | } 46 | return XMPP_ROLE_NONE; 47 | } 48 | -------------------------------------------------------------------------------- /src/core/xep/muc-role.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_ROLE_H 2 | #define __MUC_ROLE_H 3 | 4 | enum { 5 | XMPP_ROLE_NONE, 6 | XMPP_ROLE_MODERATOR, 7 | XMPP_ROLE_PARTICIPANT, 8 | XMPP_ROLE_VISITOR 9 | }; 10 | extern const char *xmpp_role[]; 11 | 12 | __BEGIN_DECLS 13 | int xmpp_nicklist_get_role(const char *); 14 | __END_DECLS 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/core/xep/muc.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUC_H 2 | #define __MUC_H 3 | 4 | #include "channels.h" 5 | #include "channels-setup.h" 6 | #include "xmpp-servers.h" 7 | #include "tools.h" 8 | 9 | #define XMLNS_MUC "http://jabber.org/protocol/muc" 10 | #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" 11 | #define XMLNS_MUC_OWNER "http://jabber.org/protocol/muc#owner" 12 | #define XMLNS_MUC_ADMIN "http://jabber.org/protocol/muc#admin" 13 | 14 | #define muc_extract_nick(jid) \ 15 | xmpp_extract_resource(jid) 16 | #define muc_extract_channel(jid) \ 17 | xmpp_strip_resource(jid) 18 | 19 | #define MUC_SETUP(chansetup) \ 20 | PROTO_CHECK_CAST(CHANNEL_SETUP(chansetup), CHANNEL_SETUP_REC, chat_type, "XMPP") 21 | 22 | #define IS_MUC_SETUP(chansetup) \ 23 | (MUC_SETUP(chansetup) ? TRUE : FALSE) 24 | 25 | /* Returns MUC_REC if it's XMPP channel, NULL if it isn't. */ 26 | #define MUC(channel) \ 27 | PROTO_CHECK_CAST(CHANNEL(channel), MUC_REC, chat_type, "XMPP") 28 | 29 | #define IS_MUC(channel) \ 30 | (MUC(channel) ? TRUE : FALSE) 31 | 32 | #define muc_find(server, name) \ 33 | MUC(channel_find(SERVER(server), name)) 34 | 35 | #define STRUCT_SERVER_REC XMPP_SERVER_REC 36 | struct _MUC_REC { 37 | #include "channel-rec.h" 38 | 39 | char *nick; 40 | }; 41 | 42 | enum { 43 | MUC_ERROR_UNKNOWN, 44 | MUC_ERROR_PASSWORD_INVALID_OR_MISSING = 401, 45 | MUC_ERROR_USER_BANNED = 403, 46 | MUC_ERROR_ROOM_NOT_FOUND = 404, 47 | MUC_ERROR_ROOM_CREATION_RESTRICTED = 405, 48 | MUC_ERROR_USE_RESERVED_ROOM_NICK = 406, 49 | MUC_ERROR_NOT_ON_MEMBERS_LIST = 407, 50 | MUC_ERROR_NICK_IN_USE = 409, 51 | MUC_ERROR_MAXIMUM_USERS_REACHED = 503, 52 | }; 53 | 54 | __BEGIN_DECLS 55 | 56 | void muc_destroy(XMPP_SERVER_REC *, MUC_REC *, const char *, const char *); 57 | void muc_join(XMPP_SERVER_REC *, const char *, gboolean); 58 | void muc_part(MUC_REC *, const char *); 59 | void muc_nick(MUC_REC *, const char *); 60 | void muc_get_affiliation(XMPP_SERVER_REC *, MUC_REC *, const char *); 61 | void muc_set_affiliation(XMPP_SERVER_REC *, MUC_REC *, const char *, 62 | const char *, const char *); 63 | void muc_get_role(XMPP_SERVER_REC *, MUC_REC *, const char *); 64 | void muc_set_role(XMPP_SERVER_REC *, MUC_REC *, const char *, 65 | const char *, const char *); 66 | void muc_set_mode(XMPP_SERVER_REC *, MUC_REC *, const char *); 67 | MUC_REC *get_muc(XMPP_SERVER_REC *, const char *); 68 | 69 | void muc_init(void); 70 | void muc_deinit(void); 71 | __END_DECLS 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/core/xep/oob.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0066: Out of Band Data 20 | */ 21 | 22 | #include "module.h" 23 | #include "signals.h" 24 | 25 | #include "xmpp-servers.h" 26 | #include "tools.h" 27 | #include "disco.h" 28 | #include "muc.h" 29 | 30 | #define XMLNS_OOB_X "jabber:x:oob" 31 | #define XMLNS_OOB_IQ "jabber:iq:oob" 32 | 33 | static void 34 | lm_message_node_delete_child(LmMessageNode *child) 35 | { 36 | LmMessageNode *n; 37 | LmMessageNode *parent = child->parent; 38 | child->parent = NULL; 39 | for (n = parent->children; n; ) { 40 | LmMessageNode *next = n->next; 41 | if (n == child) { 42 | LmMessageNode *prev = n->prev; 43 | if (next != NULL) { 44 | next->prev = prev; 45 | } 46 | if (prev != NULL) { 47 | prev->next = next; 48 | } 49 | if (n == parent->children) { 50 | parent->children = next; 51 | } 52 | n->prev = NULL; 53 | n->next = NULL; 54 | lm_message_node_unref(n); 55 | } 56 | n = next; 57 | } 58 | } 59 | 60 | static void 61 | sig_recv_x(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 62 | const char *id, const char *from, const char *to) 63 | { 64 | LmMessageNode *node, *child; 65 | const char *url, *desc; 66 | char *url_recoded, *desc_recoded, *str; 67 | 68 | node = lm_find_node(lmsg->node, "x", XMLNS, XMLNS_OOB_X); 69 | if (node != NULL) { 70 | child = lm_message_node_get_child(node, "url"); 71 | if (child == NULL || child->value == NULL) 72 | return; 73 | url = child->value; 74 | child = lm_message_node_get_child(node, "desc"); 75 | desc = child != NULL ? child->value : NULL; 76 | if (lm_message_get_type(lmsg) == LM_MESSAGE_TYPE_MESSAGE) { 77 | LmMessageNode *body = lm_message_node_get_child(lmsg->node, "body"); 78 | if (body != NULL && g_strcmp0(url, lm_message_node_get_value(body)) == 0) { 79 | lm_message_node_delete_child(body); 80 | } 81 | } 82 | url_recoded = xmpp_recode_in(url); 83 | if (desc != NULL) { 84 | desc_recoded = xmpp_recode_in(desc); 85 | str = g_strconcat(desc_recoded, ": ", url_recoded, (void *)NULL); 86 | g_free(url_recoded); 87 | g_free(desc_recoded); 88 | } else 89 | str = url_recoded; 90 | if (lm_message_get_sub_type(lmsg) == LM_MESSAGE_SUB_TYPE_GROUPCHAT) { 91 | char *nick, *channel; 92 | 93 | nick = muc_extract_nick(from); 94 | channel = muc_extract_channel(from); 95 | 96 | signal_emit("message public", 5, 97 | server, str, nick, "", channel); 98 | 99 | g_free(channel); 100 | g_free(nick); 101 | } else { 102 | signal_emit("message private", 4, server, str, from, from); 103 | } 104 | g_free(str); 105 | } 106 | } 107 | 108 | void 109 | oob_init(void) 110 | { 111 | disco_add_feature(XMLNS_OOB_X); 112 | signal_add("xmpp recv message", sig_recv_x); 113 | signal_add("xmpp recv presence", sig_recv_x); 114 | } 115 | 116 | void 117 | oob_deinit(void) 118 | { 119 | signal_remove("xmpp recv message", sig_recv_x); 120 | signal_remove("xmpp recv presence", sig_recv_x); 121 | } 122 | -------------------------------------------------------------------------------- /src/core/xep/oob.h: -------------------------------------------------------------------------------- 1 | #ifndef __OOB_H 2 | #define __OOB_H 3 | 4 | __BEGIN_DECLS 5 | void oob_init(void); 6 | void oob_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/ping.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0199: XMPP Ping 20 | * and lagmeter 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #include "module.h" 27 | #include "misc.h" 28 | #include "settings.h" 29 | #include "signals.h" 30 | 31 | #include "xmpp-servers.h" 32 | #include "xmpp-commands.h" 33 | #include "tool_datalist.h" 34 | #include "disco.h" 35 | #include "tools.h" 36 | 37 | #define XMLNS_PING "urn:xmpp:ping" 38 | 39 | struct ping_data { 40 | char *id; 41 | GTimeVal time; 42 | }; 43 | 44 | static int timeout_tag; 45 | static GSList *supported_servers; 46 | static DATALIST *pings; 47 | 48 | static void 49 | request_ping(XMPP_SERVER_REC *server, const char *dest) 50 | { 51 | struct ping_data *pd; 52 | LmMessage *lmsg; 53 | LmMessageNode *node; 54 | char *recoded; 55 | 56 | recoded = xmpp_recode_in(dest); 57 | lmsg = lm_message_new_with_sub_type(recoded, 58 | LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET); 59 | g_free(recoded); 60 | node = lm_message_node_add_child(lmsg->node, "ping", NULL); 61 | lm_message_node_set_attribute(node, XMLNS, XMLNS_PING); 62 | if (strcmp(dest, server->domain) == 0) { 63 | g_free(server->ping_id); 64 | server->ping_id = 65 | g_strdup(lm_message_node_get_attribute(lmsg->node, "id")); 66 | g_get_current_time(&server->lag_sent); 67 | server->lag_last_check = time(NULL); 68 | } else { 69 | pd = g_new0(struct ping_data, 1); 70 | pd->id = 71 | g_strdup(lm_message_node_get_attribute(lmsg->node, "id")); 72 | g_get_current_time(&pd->time); 73 | datalist_add(pings, server, dest, pd); 74 | } 75 | signal_emit("xmpp send iq", 2, server, lmsg); 76 | lm_message_unref(lmsg); 77 | } 78 | 79 | static void 80 | send_ping(XMPP_SERVER_REC *server, const char *dest, const char *id) 81 | { 82 | LmMessage *lmsg; 83 | char *recoded; 84 | 85 | recoded = xmpp_recode_in(dest); 86 | lmsg = lm_message_new_with_sub_type(recoded, 87 | LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_RESULT); 88 | g_free(recoded); 89 | if (id != NULL) 90 | lm_message_node_set_attribute(lmsg->node, "id", id); 91 | signal_emit("xmpp send iq", 2, server, lmsg); 92 | lm_message_unref(lmsg); 93 | } 94 | 95 | static void 96 | sig_recv_iq(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 97 | const char *id, const char *from, const char *to) 98 | { 99 | DATALIST_REC *rec; 100 | LmMessageNode *node; 101 | GTimeVal now; 102 | struct ping_data *pd; 103 | 104 | if (type == LM_MESSAGE_SUB_TYPE_RESULT) { 105 | /* pong response from server of our ping */ 106 | if (server->ping_id != NULL 107 | && (*from == '\0' || strcmp(from, server->domain) == 0) 108 | && strcmp(id, server->ping_id) == 0) { 109 | g_get_current_time(&now); 110 | server->lag = 111 | (int)get_timeval_diff(&now, &server->lag_sent); 112 | memset(&server->lag_sent, 0, sizeof(server->lag_sent)); 113 | g_free_and_null(server->ping_id); 114 | signal_emit("server lag", 1, server); 115 | } else if (lmsg->node->children == NULL 116 | && (rec = datalist_find(pings, server, from)) != NULL) { 117 | pd = rec->data; 118 | if (strcmp(id, pd->id) == 0) { 119 | g_get_current_time(&now); 120 | signal_emit("xmpp ping", 3, server, from, 121 | get_timeval_diff(&now, &pd->time)); 122 | } 123 | } 124 | } else if (type == LM_MESSAGE_SUB_TYPE_GET) { 125 | node = lm_find_node(lmsg->node, "ping", XMLNS, XMLNS_PING); 126 | if (node == NULL) 127 | node = lm_find_node(lmsg->node, "query", XMLNS, 128 | XMLNS_PING); 129 | if (node != NULL) 130 | send_ping(server, from, 131 | lm_message_node_get_attribute(lmsg->node, "id")); 132 | } 133 | } 134 | 135 | static void 136 | sig_server_features(XMPP_SERVER_REC *server) 137 | { 138 | if (disco_have_feature(server->server_features, XMLNS_PING)) { 139 | if (g_slist_find(supported_servers, server) == NULL) { 140 | supported_servers = g_slist_prepend(supported_servers, server); 141 | } 142 | } 143 | } 144 | 145 | static void 146 | sig_disconnected(XMPP_SERVER_REC *server) 147 | { 148 | if (!IS_XMPP_SERVER(server)) 149 | return; 150 | supported_servers = g_slist_remove(supported_servers, server); 151 | datalist_cleanup(pings, server); 152 | } 153 | 154 | static int 155 | check_ping_func(void) 156 | { 157 | GSList *tmp; 158 | XMPP_SERVER_REC *server; 159 | time_t now; 160 | int lag_check_time, max_lag; 161 | 162 | lag_check_time = settings_get_time("lag_check_time")/1000; 163 | max_lag = settings_get_time("lag_max_before_disconnect")/1000; 164 | if (lag_check_time <= 0) 165 | return 1; 166 | now = time(NULL); 167 | for (tmp = supported_servers; tmp != NULL; tmp = tmp->next) { 168 | server = XMPP_SERVER(tmp->data); 169 | if (server->lag_sent.tv_sec != 0) { 170 | /* waiting for lag reply */ 171 | if (max_lag > 1 && 172 | (now - server->lag_sent.tv_sec) > max_lag) { 173 | /* too much lag - disconnect */ 174 | signal_emit("server lag disconnect", 1, 175 | server); 176 | server->connection_lost = TRUE; 177 | server_disconnect(SERVER(server)); 178 | } 179 | } else if ((server->lag_last_check + lag_check_time) < now && 180 | server->connected) { 181 | /* no commands in buffer - get the lag */ 182 | request_ping(server, server->domain); 183 | } 184 | } 185 | return 1; 186 | } 187 | 188 | /* SYNTAX: PING [[[/]]|[data)->id); 208 | g_free(rec->data); 209 | } 210 | 211 | void 212 | ping_init(void) 213 | { 214 | supported_servers = NULL; 215 | pings = datalist_new(freedata_func); 216 | disco_add_feature(XMLNS_PING); 217 | signal_add("xmpp recv iq", sig_recv_iq); 218 | signal_add("xmpp server features", sig_server_features); 219 | signal_add("server disconnected", sig_disconnected); 220 | command_bind_xmpp("ping", NULL, (SIGNAL_FUNC)cmd_ping); 221 | timeout_tag = g_timeout_add(1000, (GSourceFunc)check_ping_func, NULL); 222 | } 223 | 224 | void 225 | ping_deinit(void) 226 | { 227 | g_source_remove(timeout_tag); 228 | signal_remove("xmpp recv iq", sig_recv_iq); 229 | signal_remove("xmpp server features", sig_server_features); 230 | signal_remove("server disconnected", sig_disconnected); 231 | command_unbind("ping", (SIGNAL_FUNC)cmd_ping); 232 | g_slist_free(supported_servers); 233 | datalist_destroy(pings); 234 | } 235 | -------------------------------------------------------------------------------- /src/core/xep/ping.h: -------------------------------------------------------------------------------- 1 | #ifndef __PING_H 2 | #define __PING_H 3 | 4 | __BEGIN_DECLS 5 | void xmpp_ping_send(XMPP_SERVER_REC *, const char *); 6 | 7 | void ping_init(void); 8 | void ping_deinit(void); 9 | __END_DECLS 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/core/xep/registration.h: -------------------------------------------------------------------------------- 1 | #ifndef __REGISTRATION_H 2 | #define __REGISTRATION_H 3 | 4 | enum { 5 | REGISTRATION_ERROR_UNAUTHORIZED = 401, 6 | REGISTRATION_ERROR_UNAUTHORIZED_REG = 407, 7 | REGISTRATION_ERROR_UNIMPLEMENTED = 501, 8 | REGISTRATION_ERROR_UNAVAILABLE = 503, 9 | REGISTRATION_ERROR_CONFLICT = 409, 10 | REGISTRATION_ERROR_TIMEOUT = 408, 11 | REGISTRATION_ERROR_TIMEOUT_SERVER = 504, 12 | REGISTRATION_ERROR_CLOSED = -4, 13 | REGISTRATION_ERROR_CONNECTION = -3, 14 | REGISTRATION_ERROR_INFO = -2, 15 | REGISTRATION_ERROR_UNKNOWN = -1, 16 | }; 17 | 18 | __BEGIN_DECLS 19 | void registration_init(void); 20 | void registration_deinit(void); 21 | __END_DECLS 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/xep/tool_datalist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | 22 | #include "tool_datalist.h" 23 | 24 | DATALIST_REC * 25 | datalist_find(DATALIST *dl, XMPP_SERVER_REC *server, const char *jid) 26 | { 27 | GSList *tmp; 28 | DATALIST_REC *rec; 29 | 30 | for (tmp = dl->list; tmp != NULL; tmp = tmp->next) { 31 | rec = tmp->data; 32 | if (rec->server == server && strcmp(rec->jid, jid) == 0) 33 | return rec; 34 | } 35 | return NULL; 36 | } 37 | 38 | DATALIST_REC * 39 | datalist_add(DATALIST *dl, XMPP_SERVER_REC *server, const char *jid, 40 | void *data) 41 | { 42 | DATALIST_REC *rec; 43 | 44 | if ((rec = datalist_find(dl, server, jid)) != NULL) { 45 | dl->freedata_func(rec); 46 | rec->data = data; 47 | } else { 48 | rec = g_new0(DATALIST_REC, 1); 49 | rec->server = server; 50 | rec->jid = g_strdup(jid); 51 | rec->data = data; 52 | dl->list = g_slist_prepend(dl->list, rec); 53 | } 54 | return rec; 55 | } 56 | 57 | void 58 | datalist_free(DATALIST *dl, DATALIST_REC *rec) 59 | { 60 | dl->list = g_slist_remove(dl->list, rec); 61 | g_free(rec->jid); 62 | dl->freedata_func(rec); 63 | g_free(rec); 64 | } 65 | 66 | void 67 | datalist_remove(DATALIST *dl, XMPP_SERVER_REC *server, const char *jid) 68 | { 69 | DATALIST_REC *rec; 70 | 71 | if ((rec = datalist_find(dl, server, jid)) != NULL) 72 | datalist_free(dl, rec); 73 | } 74 | 75 | void 76 | datalist_cleanup(DATALIST *dl, XMPP_SERVER_REC *server) 77 | { 78 | GSList *tmp, *next; 79 | DATALIST_REC *rec; 80 | 81 | for (tmp = dl->list; tmp != NULL; tmp = next) { 82 | next = tmp->next; 83 | rec = tmp->data; 84 | if (server == NULL || rec->server == server) 85 | datalist_free(dl, rec); 86 | } 87 | } 88 | 89 | static void 90 | dummy_freedata_func(DATALIST_REC *rec) 91 | { 92 | } 93 | 94 | DATALIST * 95 | datalist_new(void (*freedata_func)(DATALIST_REC *)) 96 | { 97 | DATALIST *dl; 98 | 99 | dl = g_new0(DATALIST, 1); 100 | dl->list = NULL; 101 | dl->freedata_func = freedata_func == NULL ? 102 | dummy_freedata_func : freedata_func; 103 | return dl; 104 | } 105 | 106 | void 107 | datalist_destroy(DATALIST *dl) 108 | { 109 | datalist_cleanup(dl, NULL); 110 | g_free(dl); 111 | } 112 | -------------------------------------------------------------------------------- /src/core/xep/tool_datalist.h: -------------------------------------------------------------------------------- 1 | #ifndef __TOOL_DATALIST_H 2 | #define __TOOL_DATALIST_H 3 | 4 | #include "xmpp-servers.h" 5 | 6 | typedef struct datalist_rec { 7 | XMPP_SERVER_REC *server; 8 | char *jid; 9 | void *data; 10 | } DATALIST_REC; 11 | 12 | typedef struct datalist_first { 13 | GSList *list; 14 | void (*freedata_func)(DATALIST_REC *); 15 | } DATALIST; 16 | 17 | __BEGIN_DECLS 18 | DATALIST *datalist_new(void (*)(DATALIST_REC *)); 19 | void datalist_destroy(DATALIST *); 20 | DATALIST_REC *datalist_find(DATALIST *, XMPP_SERVER_REC *, const char *); 21 | DATALIST_REC *datalist_add(DATALIST *, XMPP_SERVER_REC *, const char *, 22 | void *); 23 | void datalist_free(DATALIST *, DATALIST_REC *); 24 | void datalist_remove(DATALIST *, XMPP_SERVER_REC *, const char *); 25 | void datalist_cleanup(DATALIST *, XMPP_SERVER_REC *); 26 | __END_DECLS 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/core/xep/vcard.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "queries.h" 20 | #include "signals.h" 21 | 22 | #include "xmpp-servers.h" 23 | #include "xmpp-commands.h" 24 | #include "tools.h" 25 | #include "disco.h" 26 | 27 | #define XMLNS_VCARD "vcard-temp" 28 | 29 | static void 30 | request_vcard(XMPP_SERVER_REC *server, const char *dest) 31 | { 32 | LmMessage *lmsg; 33 | LmMessageNode *node; 34 | char *recoded; 35 | 36 | recoded = xmpp_recode_out(dest); 37 | lmsg = lm_message_new_with_sub_type(recoded, 38 | LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET); 39 | g_free(recoded); 40 | node = lm_message_node_add_child(lmsg->node, "vCard", NULL); 41 | lm_message_node_set_attribute(node, XMLNS, XMLNS_VCARD); 42 | signal_emit("xmpp send iq", 2, server, lmsg); 43 | lm_message_unref(lmsg); 44 | } 45 | 46 | /* SYNTAX: VCARD [|] 47 | * SYNTAX: WHOIS [|] */ 48 | static void 49 | cmd_vcard(const char *data, XMPP_SERVER_REC *server, WI_ITEM_REC *item) 50 | { 51 | char *cmd_dest, *dest; 52 | void *free_arg; 53 | 54 | CMD_XMPP_SERVER(server); 55 | if (!cmd_get_params(data, &free_arg, 1, &cmd_dest)) 56 | return; 57 | dest = xmpp_get_dest(cmd_dest, server, item); 58 | request_vcard(server, dest); 59 | g_free(dest); 60 | cmd_params_free(free_arg); 61 | } 62 | 63 | static void 64 | vcard_handle(XMPP_SERVER_REC *server, const char *jid, LmMessageNode *node) 65 | { 66 | LmMessageNode *child, *subchild; 67 | GHashTable *ht; 68 | const char *adressing; 69 | char *value; 70 | 71 | ht = g_hash_table_new_full(g_str_hash, g_str_equal, 72 | NULL, g_free); 73 | child = node->children; 74 | while (child != NULL) { 75 | /* ignore avatar */ 76 | if (g_ascii_strcasecmp(child->name, "PHOTO") == 0) 77 | goto next; 78 | if (child->value != NULL) { 79 | value = xmpp_recode_in(child->value); 80 | g_strstrip(value); 81 | g_hash_table_insert(ht, child->name, value); 82 | goto next; 83 | } 84 | /* find the adressing type indicator */ 85 | subchild = child->children; 86 | adressing = NULL; 87 | while (subchild != NULL && adressing == NULL) { 88 | if (subchild->value == NULL && ( 89 | g_ascii_strcasecmp(subchild->name , "HOME") == 0 || 90 | g_ascii_strcasecmp(subchild->name , "WORK") == 0)) 91 | adressing = subchild->name; 92 | subchild = subchild->next; 93 | } 94 | subchild = child->children; 95 | while (subchild != NULL) { 96 | if (subchild->value != NULL) { 97 | value = xmpp_recode_in(subchild->value); 98 | /* TODO sub... */ 99 | g_free(value); 100 | } 101 | subchild = subchild->next; 102 | } 103 | 104 | next: 105 | child = child->next; 106 | } 107 | signal_emit("xmpp vcard", 3, server, jid, ht); 108 | g_hash_table_destroy(ht); 109 | } 110 | 111 | static void 112 | sig_recv_iq(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type, 113 | const char *id, const char *from, const char *to) 114 | { 115 | LmMessageNode *node; 116 | 117 | if (type != LM_MESSAGE_SUB_TYPE_RESULT) 118 | return; 119 | node = lm_find_node(lmsg->node, "vCard", XMLNS, XMLNS_VCARD); 120 | if (node != NULL) 121 | vcard_handle(server, from, node); 122 | } 123 | 124 | void 125 | vcard_init(void) 126 | { 127 | disco_add_feature(XMLNS_VCARD); 128 | command_bind_xmpp("vcard", NULL, (SIGNAL_FUNC)cmd_vcard); 129 | command_bind_xmpp("whois", NULL, (SIGNAL_FUNC)cmd_vcard); 130 | signal_add("xmpp recv iq", sig_recv_iq); 131 | } 132 | 133 | void 134 | vcard_deinit(void) 135 | { 136 | command_unbind("vcard", (SIGNAL_FUNC)cmd_vcard); 137 | command_unbind("whois", (SIGNAL_FUNC)cmd_vcard); 138 | signal_remove("xmpp recv iq", sig_recv_iq); 139 | } 140 | -------------------------------------------------------------------------------- /src/core/xep/vcard.h: -------------------------------------------------------------------------------- 1 | #ifndef __VCARD_H 2 | #define __VCARD_H 3 | 4 | __BEGIN_DECLS 5 | void vcard_init(void); 6 | void vcard_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /* 19 | * XEP-0092: Software Version 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "module.h" 26 | #include "queries.h" 27 | #include "settings.h" 28 | #include "signals.h" 29 | 30 | #include "xmpp-servers.h" 31 | #include "xmpp-commands.h" 32 | #include "disco.h" 33 | #include "tools.h" 34 | 35 | #define XMLNS_VERSION "jabber:iq:version" 36 | 37 | static void 38 | send_version(XMPP_SERVER_REC *server, const char *dest, 39 | const char *id) 40 | { 41 | LmMessage *lmsg; 42 | LmMessageNode *node; 43 | struct utsname u; 44 | char *recoded; 45 | 46 | recoded = xmpp_recode_out(dest); 47 | lmsg = lm_message_new_with_sub_type(recoded, LM_MESSAGE_TYPE_IQ, 48 | LM_MESSAGE_SUB_TYPE_RESULT); 49 | g_free(recoded); 50 | if (id != NULL) 51 | lm_message_node_set_attribute(lmsg->node, "id", id); 52 | node = lm_message_node_add_child(lmsg->node, "query", NULL); 53 | lm_message_node_set_attribute(node, XMLNS, XMLNS_VERSION); 54 | if (settings_get_bool("xmpp_send_version")) { 55 | lm_message_node_add_child(node, "name", 56 | IRSSI_XMPP_PACKAGE); 57 | lm_message_node_add_child(node, "version", 58 | IRSSI_XMPP_VERSION); 59 | if (uname(&u) == 0) 60 | lm_message_node_add_child(node, "os", u.sysname); 61 | } 62 | signal_emit("xmpp send iq", 2, server, lmsg); 63 | lm_message_unref(lmsg); 64 | } 65 | 66 | static void 67 | request_version(XMPP_SERVER_REC *server, const char *dest) 68 | { 69 | LmMessage *lmsg; 70 | LmMessageNode *node; 71 | char *recoded; 72 | 73 | recoded = xmpp_recode_out(dest); 74 | lmsg = lm_message_new_with_sub_type(recoded, 75 | LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET); 76 | g_free(recoded); 77 | node = lm_message_node_add_child(lmsg->node, "query", NULL); 78 | lm_message_node_set_attribute(node, XMLNS, XMLNS_VERSION); 79 | signal_emit("xmpp send iq", 2, server, lmsg); 80 | lm_message_unref(lmsg); 81 | } 82 | 83 | /* SYNTAX: VER [[[/]]|[node,"query", XMLNS, 108 | XMLNS_VERSION)) != NULL) { 109 | name = version = os = NULL; 110 | for (child = node->children; child != NULL; child = child->next) { 111 | if (child->value == NULL) 112 | continue; 113 | if (name == NULL && strcmp(child->name, "name") == 0) 114 | g_strstrip(name = xmpp_recode_in(child->value)); 115 | else if (version == NULL 116 | && strcmp(child->name, "version") == 0) 117 | g_strstrip(version = xmpp_recode_in(child->value)); 118 | else if (os == NULL && strcmp(child->name, "os") == 0) 119 | g_strstrip(os = xmpp_recode_in(child->value)); 120 | } 121 | signal_emit("xmpp version", 5, server, from, name, version, os); 122 | g_free(name); 123 | g_free(version); 124 | g_free(os); 125 | } else if (type == LM_MESSAGE_SUB_TYPE_GET 126 | && (node = lm_find_node(lmsg->node,"query", XMLNS, 127 | XMLNS_VERSION)) != NULL) 128 | send_version(server, from, id); 129 | } 130 | 131 | void 132 | version_init(void) 133 | { 134 | disco_add_feature(XMLNS_VERSION); 135 | settings_add_bool("xmpp", "xmpp_send_version", TRUE); 136 | command_bind_xmpp("ver", NULL, (SIGNAL_FUNC)cmd_ver); 137 | signal_add("xmpp recv iq", sig_recv_iq); 138 | } 139 | 140 | void 141 | version_deinit(void) 142 | { 143 | command_unbind("ver", (SIGNAL_FUNC)cmd_ver); 144 | signal_remove("xmpp recv iq", sig_recv_iq); 145 | } 146 | -------------------------------------------------------------------------------- /src/core/xep/version.h: -------------------------------------------------------------------------------- 1 | #ifndef __VERSION_H 2 | #define __VERSION_H 3 | 4 | __BEGIN_DECLS 5 | void version_init(void); 6 | void version_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xep/xep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | 20 | #include "chatstates.h" 21 | #include "composing.h" 22 | #include "delay.h" 23 | #include "disco.h" 24 | #include "muc.h" 25 | #include "oob.h" 26 | #include "ping.h" 27 | #include "registration.h" 28 | #include "vcard.h" 29 | #include "version.h" 30 | 31 | void 32 | xep_init(void) 33 | { 34 | disco_init(); /* init sevice discovery first */ 35 | chatstates_init(); 36 | composing_init(); 37 | delay_init(); 38 | muc_init(); 39 | oob_init(); 40 | ping_init(); 41 | registration_init(); 42 | vcard_init(); 43 | version_init(); 44 | } 45 | 46 | void 47 | xep_deinit(void) 48 | { 49 | disco_deinit(); 50 | chatstates_deinit(); 51 | composing_deinit(); 52 | delay_deinit(); 53 | muc_deinit(); 54 | oob_deinit(); 55 | ping_deinit(); 56 | registration_deinit(); 57 | vcard_deinit(); 58 | version_deinit(); 59 | } 60 | -------------------------------------------------------------------------------- /src/core/xep/xep.h: -------------------------------------------------------------------------------- 1 | #ifndef __XEP_H 2 | #define __XEP_H 3 | 4 | __BEGIN_DECLS 5 | void xep_init(void); 6 | void xep_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xmpp-commands.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_COMMANDS_H 2 | #define __XMPP_COMMANDS_H 3 | 4 | #include "commands.h" 5 | 6 | enum { 7 | XMPP_COMMAND_AWAY, 8 | XMPP_COMMAND_QUOTE, 9 | XMPP_COMMAND_ROSTER, 10 | XMPP_COMMAND_WHOIS, 11 | XMPP_COMMAND_PRESENCE 12 | }; 13 | extern const char *xmpp_commands[]; 14 | 15 | enum { 16 | XMPP_COMMAND_ROSTER_PARAM_FULL, 17 | XMPP_COMMAND_ROSTER_PARAM_ADD, 18 | XMPP_COMMAND_ROSTER_PARAM_REMOVE, 19 | XMPP_COMMAND_ROSTER_PARAM_NAME, 20 | XMPP_COMMAND_ROSTER_PARAM_GROUP, 21 | }; 22 | extern const char *xmpp_command_roster[]; 23 | 24 | enum { 25 | XMPP_COMMAND_ROSTER_PARAM_ACCEPT, 26 | XMPP_COMMAND_ROSTER_PARAM_DENY, 27 | XMPP_COMMAND_ROSTER_PARAM_SUBSCRIBE, 28 | XMPP_COMMAND_ROSTER_PARAM_UNSUBSCRIBE, 29 | }; 30 | extern const char *xmpp_command_presence[]; 31 | 32 | #define command_bind_xmpp(cmd, section, signal) \ 33 | command_bind_proto(cmd, XMPP_PROTOCOL, section, signal) 34 | 35 | #define command_bind_xmpp_first(cmd, section, signal) \ 36 | command_bind_proto_first(cmd, XMPP_PROTOCOL, section, signal) 37 | 38 | #define command_bind_xmpp_last(cmd, section, signal) \ 39 | command_bind_proto_last(cmd, XMPP_PROTOCOL, section, signal) 40 | 41 | /* Simply returns if server isn't for XMPP protocol. Prints ERR_NOT_CONNECTED 42 | * error if there's no server or server isn't connected yet */ 43 | #define CMD_XMPP_SERVER(server) \ 44 | G_STMT_START { \ 45 | if (((server) != NULL) && !IS_XMPP_SERVER(server)) { \ 46 | return; \ 47 | } \ 48 | if (((server) == NULL) || !(server)->connected) { \ 49 | cmd_return_error(CMDERR_NOT_CONNECTED); \ 50 | } \ 51 | } G_STMT_END 52 | 53 | __BEGIN_DECLS 54 | char *xmpp_get_dest(const char *, XMPP_SERVER_REC *, WI_ITEM_REC *); 55 | 56 | void xmpp_commands_init(void); 57 | void xmpp_commands_deinit(void); 58 | __END_DECLS 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/core/xmpp-core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "signals.h" 20 | #include "channels.h" 21 | #include "channels-setup.h" 22 | #include "chat-protocols.h" 23 | #include "chatnets.h" 24 | #include "servers-setup.h" 25 | #include "settings.h" 26 | 27 | #include "xmpp-commands.h" 28 | #include "xmpp-queries.h" 29 | #include "xmpp-servers.h" 30 | #include "xmpp-servers-reconnect.h" 31 | #include "xmpp-settings.h" 32 | #include "protocol.h" 33 | #include "rosters.h" 34 | #include "stanzas.h" 35 | #include "xep/xep.h" 36 | 37 | static CHATNET_REC * 38 | create_chatnet(void) 39 | { 40 | return g_new0(CHATNET_REC, 1); 41 | } 42 | 43 | static SERVER_SETUP_REC * 44 | create_server_setup(void) 45 | { 46 | return g_new0(SERVER_SETUP_REC, 1); 47 | } 48 | 49 | static SERVER_CONNECT_REC * 50 | create_server_connect(void) 51 | { 52 | XMPP_SERVER_CONNECT_REC *conn; 53 | 54 | conn = g_new0(XMPP_SERVER_CONNECT_REC, 1); 55 | conn->channels_list = NULL; 56 | conn->real_jid = NULL; 57 | conn->prompted_password = NULL; 58 | return (SERVER_CONNECT_REC *)conn; 59 | } 60 | 61 | static CHANNEL_SETUP_REC * 62 | create_channel_setup(void) 63 | { 64 | return g_new0(CHANNEL_SETUP_REC, 1); 65 | } 66 | 67 | static void 68 | destroy_server_connect(XMPP_SERVER_CONNECT_REC *conn) 69 | { 70 | g_free_not_null(conn->real_jid); 71 | g_free_not_null(conn->prompted_password); 72 | } 73 | 74 | static CHANNEL_REC * 75 | channel_create(SERVER_REC *server, const char *name, const char *visible_name, 76 | int automatic) 77 | { 78 | return g_new0(CHANNEL_REC, 1); 79 | } 80 | 81 | void 82 | xmpp_core_init(void) 83 | { 84 | CHAT_PROTOCOL_REC *rec; 85 | 86 | rec = g_new0(CHAT_PROTOCOL_REC, 1); 87 | rec->name = XMPP_PROTOCOL_NAME; 88 | rec->fullname = "XMPP, Extensible messaging and presence protocol"; 89 | rec->chatnet = "xmppnet"; 90 | rec->case_insensitive = FALSE; 91 | rec->create_chatnet = create_chatnet; 92 | rec->create_server_setup = create_server_setup; 93 | rec->create_server_connect = create_server_connect; 94 | rec->create_channel_setup = create_channel_setup; 95 | rec->destroy_server_connect = 96 | (void (*)(SERVER_CONNECT_REC *))destroy_server_connect; 97 | rec->server_init_connect = xmpp_server_init_connect; 98 | rec->server_connect = (void (*)(SERVER_REC *))xmpp_server_connect; 99 | rec->channel_create = channel_create; 100 | rec->query_create = xmpp_query_create; 101 | chat_protocol_register(rec); 102 | g_free(rec); 103 | 104 | xmpp_commands_init(); 105 | xmpp_servers_init(); 106 | xmpp_servers_reconnect_init(); 107 | xmpp_settings_init(); 108 | protocol_init(); 109 | rosters_init(); 110 | stanzas_init(); 111 | xep_init(); 112 | 113 | module_register("xmpp", "core"); 114 | } 115 | 116 | void 117 | xmpp_core_deinit(void) 118 | { 119 | xep_deinit(); 120 | /* deinit servers first to disconnect servers before unloading */ 121 | xmpp_servers_deinit(); 122 | xmpp_commands_deinit(); 123 | xmpp_servers_reconnect_deinit(); 124 | xmpp_settings_deinit(); 125 | protocol_deinit(); 126 | rosters_deinit(); 127 | stanzas_deinit(); 128 | 129 | signal_emit("chat protocol deinit", 1, chat_protocol_find("XMPP")); 130 | chat_protocol_unregister("XMPP"); 131 | } 132 | 133 | #ifdef IRSSI_ABI_VERSION 134 | void 135 | xmpp_core_abicheck(int * version) 136 | { 137 | *version = IRSSI_ABI_VERSION; 138 | } 139 | #endif 140 | -------------------------------------------------------------------------------- /src/core/xmpp-queries.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "channels.h" 22 | #include "nicklist.h" 23 | #include "signals.h" 24 | 25 | #include "xmpp-queries.h" 26 | #include "rosters-tools.h" 27 | #include "tools.h" 28 | 29 | QUERY_REC * 30 | xmpp_query_create(const char *server_tag, const char *data, int automatic) 31 | { 32 | XMPP_QUERY_REC *rec, *rec_tmp; 33 | XMPP_SERVER_REC *server; 34 | CHANNEL_REC *channel; 35 | NICK_REC *nick; 36 | const char *channel_name; 37 | 38 | g_return_val_if_fail(server_tag != NULL, NULL); 39 | g_return_val_if_fail(data != NULL, NULL); 40 | if ((server = XMPP_SERVER(server_find_tag(server_tag))) == NULL) 41 | return NULL; 42 | rec = g_new0(XMPP_QUERY_REC, 1); 43 | rec->chat_type = XMPP_PROTOCOL; 44 | /* query created from a channel */ 45 | channel_name = NULL; 46 | signal_emit("xmpp windows get active channel", 1, &channel_name); 47 | if (channel_name != NULL) { 48 | channel = channel_find(SERVER(server), channel_name); 49 | if (channel != NULL) { 50 | nick = nicklist_find(channel, data); 51 | if (nick != NULL) 52 | rec->name = g_strdup(nick->host); 53 | } 54 | } 55 | if (rec->name == NULL) 56 | rec->name = rosters_resolve_name(server, data); 57 | if (rec->name != NULL) { 58 | /* test if the query already exist */ 59 | if ((rec_tmp = xmpp_query_find(server, rec->name)) != NULL) { 60 | g_free(rec->name); 61 | g_free(rec); 62 | signal_emit("xmpp query raise", 2, server, rec_tmp); 63 | return NULL; 64 | } 65 | } else 66 | rec->name = g_strdup(data); 67 | rec->server_tag = g_strdup(server_tag); 68 | query_init((QUERY_REC *)rec, automatic); 69 | rec->composing_time = 0; 70 | rec->composing_visible = FALSE; 71 | return (QUERY_REC *)rec; 72 | } 73 | -------------------------------------------------------------------------------- /src/core/xmpp-queries.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_QUERIES_H 2 | #define __XMPP_QUERIES_H 3 | 4 | #include "queries.h" 5 | #include "xmpp-servers.h" 6 | 7 | /* Returns XMPP_QUERY_REC if it's XMPP query, NULL if it isn't. */ 8 | #define XMPP_QUERY(query) \ 9 | PROTO_CHECK_CAST(QUERY(query), XMPP_QUERY_REC, chat_type, "XMPP") 10 | 11 | #define IS_XMPP_QUERY(query) \ 12 | (XMPP_QUERY(query) ? TRUE : FALSE) 13 | 14 | #define xmpp_query_find(server, name) \ 15 | XMPP_QUERY(query_find(SERVER(server), name)) 16 | 17 | #define STRUCT_SERVER_REC XMPP_SERVER_REC 18 | struct _XMPP_QUERY_REC { 19 | #include "query-rec.h" 20 | 21 | time_t composing_time; 22 | gboolean composing_visible; 23 | }; 24 | 25 | __BEGIN_DECLS 26 | QUERY_REC *xmpp_query_create(const char *, const char *, int); 27 | __END_DECLS 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/core/xmpp-servers-reconnect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "signals.h" 20 | 21 | #include "xmpp-servers.h" 22 | 23 | static void 24 | sig_server_connect_copy(SERVER_CONNECT_REC **dest, XMPP_SERVER_CONNECT_REC *src) 25 | { 26 | XMPP_SERVER_CONNECT_REC *conn; 27 | 28 | g_return_if_fail(dest != NULL); 29 | if (!IS_XMPP_SERVER_CONNECT(src)) 30 | return; 31 | conn = g_new0(XMPP_SERVER_CONNECT_REC, 1); 32 | conn->chat_type = XMPP_PROTOCOL; 33 | conn->show = src->show; 34 | conn->priority = src->priority; 35 | conn->prompted_password = g_strdup(src->prompted_password); 36 | g_free(src->nick); 37 | src->nick = src->real_jid; 38 | src->real_jid = NULL; 39 | *dest = (SERVER_CONNECT_REC *)conn; 40 | } 41 | 42 | static void 43 | sig_save_status(XMPP_SERVER_CONNECT_REC *conn, XMPP_SERVER_REC *server) 44 | { 45 | if (!IS_XMPP_SERVER_CONNECT(conn) || !IS_XMPP_SERVER(server) 46 | || !server->connected) 47 | return; 48 | conn->show = server->show; 49 | conn->priority = server->priority; 50 | } 51 | 52 | static void 53 | sig_connected(XMPP_SERVER_REC *server) 54 | { 55 | if (!IS_XMPP_SERVER(server) || !server->connrec->reconnection) 56 | return; 57 | signal_emit("xmpp set presence", 4, server, server->connrec->show, 58 | server->connrec->away_reason, server->connrec->priority); 59 | g_free_and_null(server->connrec->away_reason); 60 | } 61 | 62 | void 63 | xmpp_servers_reconnect_init(void) 64 | { 65 | signal_add_first("server connect copy", sig_server_connect_copy); 66 | signal_add("server reconnect save status", sig_save_status); 67 | signal_add_last("server connected", sig_connected); 68 | } 69 | 70 | void 71 | xmpp_servers_reconnect_deinit(void) 72 | { 73 | signal_remove("server connect copy", sig_server_connect_copy); 74 | signal_remove("server reconnect save status", sig_save_status); 75 | signal_remove("server connected", sig_connected); 76 | } 77 | -------------------------------------------------------------------------------- /src/core/xmpp-servers-reconnect.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_SERVERS_RECONNECT_H 2 | #define __XMPP_SERVERS_RECONNECT_H 3 | 4 | __BEGIN_DECLS 5 | void xmpp_servers_reconnect_init(void); 6 | void xmpp_servers_reconnect_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xmpp-servers.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_SERVERS_H 2 | #define __XMPP_SERVERS_H 3 | 4 | #include "chat-protocols.h" 5 | #include "servers.h" 6 | 7 | #include "loudmouth/loudmouth.h" 8 | #include "loudmouth-tools.h" 9 | 10 | #define XMPP_PROXY_HTTP "http" 11 | 12 | /* returns XMPP_SERVER_REC if it's XMPP server, NULL if it isn't */ 13 | #define XMPP_SERVER(server) \ 14 | PROTO_CHECK_CAST(SERVER(server), XMPP_SERVER_REC, chat_type, "XMPP") 15 | 16 | #define XMPP_SERVER_CONNECT(conn) \ 17 | PROTO_CHECK_CAST(SERVER_CONNECT(conn), XMPP_SERVER_CONNECT_REC, \ 18 | chat_type, "XMPP") 19 | 20 | #define IS_XMPP_SERVER(server) \ 21 | (XMPP_SERVER(server) ? TRUE : FALSE) 22 | 23 | #define IS_XMPP_SERVER_CONNECT(conn) \ 24 | (XMPP_SERVER_CONNECT(conn) ? TRUE : FALSE) 25 | 26 | struct _XMPP_SERVER_CONNECT_REC { 27 | #include "server-connect-rec.h" 28 | 29 | GSList *channels_list; 30 | int show; 31 | int priority; 32 | char *real_jid; 33 | char *prompted_password; 34 | }; 35 | 36 | #define STRUCT_SERVER_CONNECT_REC XMPP_SERVER_CONNECT_REC 37 | struct _XMPP_SERVER_REC { 38 | #include "server-rec.h" 39 | 40 | char *jid; 41 | char *user; 42 | char *domain; 43 | char *resource; 44 | 45 | int show; 46 | int priority; 47 | char *ping_id; 48 | GSList *server_features; 49 | GSList *my_resources; 50 | GSList *roster; 51 | 52 | int timeout_tag; 53 | LmConnection *lmconn; 54 | GSList *msg_handlers; 55 | }; 56 | 57 | __BEGIN_DECLS 58 | SERVER_REC *xmpp_server_init_connect(SERVER_CONNECT_REC *); 59 | void xmpp_server_connect(XMPP_SERVER_REC *); 60 | 61 | void xmpp_servers_init(void); 62 | void xmpp_servers_deinit(void); 63 | __END_DECLS 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/core/xmpp-settings.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "settings.h" 22 | #include "signals.h" 23 | 24 | #include "xmpp-servers.h" 25 | #include "rosters.h" 26 | 27 | void 28 | read_settings(void) 29 | { 30 | GSList *tmp; 31 | XMPP_SERVER_REC *server; 32 | 33 | for (tmp = servers; tmp != NULL; tmp = tmp->next) { 34 | if ((server = XMPP_SERVER(tmp->data)) == NULL) 35 | continue; 36 | /* update priority */ 37 | if (server->show == XMPP_PRESENCE_AWAY) { 38 | if (server->priority != settings_get_int("xmpp_priority_away")) 39 | signal_emit("xmpp set presence", 4, server, 40 | server->show, server->away_reason, 41 | settings_get_int("xmpp_priority_away")); 42 | } else { 43 | if (server->priority != settings_get_int("xmpp_priority")) 44 | signal_emit("xmpp set presence", 4, server, 45 | server->show, server->away_reason, 46 | settings_get_int("xmpp_priority")); 47 | } 48 | /* update nick */ 49 | if (settings_get_bool("xmpp_set_nick_as_username")) { 50 | if (strcmp(server->nick, server->user) != 0) { 51 | g_free(server->nick); 52 | server->nick = g_strdup(server->user); 53 | } 54 | } else { 55 | if (strcmp(server->nick, server->jid) != 0) { 56 | g_free(server->nick); 57 | server->nick = g_strdup(server->jid); 58 | } 59 | } 60 | } 61 | 62 | #if 0 63 | const char *str; 64 | 65 | /* check validity */ 66 | str = settings_get_str("xmpp_proxy_type"); 67 | /* TODO print error message */ 68 | if (settings_get_bool("xmpp_use_proxy") 69 | && (str == NULL || g_ascii_strcasecmp(str, XMPP_PROXY_HTTP) != 0)) 70 | ; 71 | str = settings_get_str("xmpp_default_away_mode"); 72 | if (str == NULL 73 | || g_ascii_strcasecmp(str, xmpp_presence_show[XMPP_PRESENCE_AWAY]) != 0 74 | || g_ascii_strcasecmp(str, xmpp_presence_show[XMPP_PRESENCE_CHAT]) != 0 75 | || g_ascii_strcasecmp(str, xmpp_presence_show[XMPP_PRESENCE_DND]) != 0 76 | || g_ascii_strcasecmp(str, xmpp_presence_show[XMPP_PRESENCE_XA]) != 0 77 | || g_ascii_strcasecmp(str, xmpp_presence_show[XMPP_PRESENCE_ONLINE]) != 0) 78 | ; 79 | #endif 80 | } 81 | 82 | void 83 | xmpp_settings_init(void) 84 | { 85 | signal_add("setup changed", (SIGNAL_FUNC)read_settings); 86 | } 87 | 88 | void 89 | xmpp_settings_deinit(void) 90 | { 91 | signal_remove("setup changed", (SIGNAL_FUNC)read_settings); 92 | } 93 | -------------------------------------------------------------------------------- /src/core/xmpp-settings.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_SETTINGS_H 2 | #define __XMPP_SETTINGS_H 3 | 4 | __BEGIN_DECLS 5 | void xmpp_settings_init(void); 6 | void xmpp_settings_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/core/xmpp.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_H 2 | #define __XMPP_H 3 | 4 | typedef struct _XMPP_SERVER_CONNECT_REC XMPP_SERVER_CONNECT_REC; 5 | typedef struct _XMPP_SERVER_REC XMPP_SERVER_REC; 6 | typedef struct _XMPP_QUERY_REC XMPP_QUERY_REC; 7 | typedef struct _XMPP_NICK_REC XMPP_NICK_REC; 8 | typedef struct _MUC_REC MUC_REC; 9 | 10 | #define XMPP_PROTOCOL_NAME "XMPP" 11 | #define XMPP_PROTOCOL (chat_protocol_lookup(XMPP_PROTOCOL_NAME)) 12 | 13 | #define IRSSI_XMPP_PACKAGE "irssi-xmpp" 14 | #define IRSSI_XMPP_VERSION "0.54" 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/fe-common/Makefile: -------------------------------------------------------------------------------- 1 | LIB= fe_xmpp 2 | SRCS= fe-xmpp-messages.c \ 3 | fe-xmpp-queries.c \ 4 | fe-xmpp-status.c \ 5 | fe-xmpp-windows.c \ 6 | fe-rosters.c \ 7 | fe-stanzas.c \ 8 | fe-xmpp-core.c \ 9 | module-formats.c \ 10 | xmpp-completion.c \ 11 | xmpp-formats.c \ 12 | xep/fe-composing.c \ 13 | xep/fe-delay.c \ 14 | xep/fe-muc.c \ 15 | xep/fe-ping.c \ 16 | xep/fe-registration.c \ 17 | xep/fe-vcard.c \ 18 | xep/fe-version.c \ 19 | xep/fe-xep.c 20 | 21 | 22 | LIB_INCS = -I../../src/fe-common 23 | LIB_LIBS = `pkg-config --libs glib-2.0` 24 | 25 | include ../rules.mk 26 | -------------------------------------------------------------------------------- /src/fe-common/fe-rosters.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_ROSTERS_H 2 | #define __FE_ROSTERS_H 3 | 4 | __BEGIN_DECLS 5 | void fe_rosters_init(void); 6 | void fe_rosters_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/fe-stanzas.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "levels.h" 22 | #include "module-formats.h" 23 | #include "printtext.h" 24 | #include "settings.h" 25 | #include "signals.h" 26 | #include "window-items.h" 27 | 28 | #include "xmpp-servers.h" 29 | 30 | static WINDOW_REC * 31 | get_console(XMPP_SERVER_REC *server) 32 | { 33 | WINDOW_REC *window; 34 | char *name; 35 | 36 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 37 | name = g_strconcat("(raw:", (server->connrec->chatnet == NULL || 38 | *server->connrec->chatnet == '\0') ? server->jid : 39 | server->connrec->chatnet, ")", (void *)NULL); 40 | if ((window = window_find_name(name)) == NULL) { 41 | window = window_create(NULL, TRUE); 42 | window_set_name(window, name); 43 | window_change_server(window, server); 44 | } 45 | g_free(name); 46 | return window; 47 | } 48 | 49 | static void 50 | sig_xml_in(XMPP_SERVER_REC *server, const char *msg) 51 | { 52 | WINDOW_REC *window; 53 | char *len; 54 | 55 | if (!settings_get_bool("xmpp_xml_console")) 56 | return; 57 | g_return_if_fail(IS_XMPP_SERVER(server)); 58 | g_return_if_fail(msg != NULL); 59 | if ((window = get_console(server)) != NULL) { 60 | len = g_strdup_printf("%lu", (unsigned long)strlen(msg)); 61 | printformat_module_window(MODULE_NAME, window, MSGLEVEL_CRAP, 62 | XMPPTXT_RAW_IN_HEADER, len); 63 | g_free(len); 64 | printformat_module_window(MODULE_NAME, window, MSGLEVEL_CRAP, 65 | XMPPTXT_RAW_MESSAGE, msg); 66 | } 67 | } 68 | 69 | static void 70 | sig_xml_out(XMPP_SERVER_REC *server, const char *msg) 71 | { 72 | WINDOW_REC *window; 73 | char *len; 74 | 75 | if (!settings_get_bool("xmpp_xml_console")) 76 | return; 77 | g_return_if_fail(IS_XMPP_SERVER(server)); 78 | g_return_if_fail(msg != NULL); 79 | if ((window = get_console(server)) != NULL) { 80 | len = g_strdup_printf("%lu", (unsigned long)strlen(msg)); 81 | printformat_module_window(MODULE_NAME, window, MSGLEVEL_CRAP, 82 | XMPPTXT_RAW_OUT_HEADER, len); 83 | g_free(len); 84 | printformat_module_window(MODULE_NAME, window, MSGLEVEL_CRAP, 85 | XMPPTXT_RAW_MESSAGE, msg); 86 | } 87 | } 88 | 89 | void 90 | fe_stanzas_init(void) 91 | { 92 | signal_add("xmpp xml in", (SIGNAL_FUNC)sig_xml_in); 93 | signal_add("xmpp xml out", (SIGNAL_FUNC)sig_xml_out); 94 | 95 | settings_add_bool("xmpp_lookandfeel", "xmpp_xml_console", FALSE); 96 | } 97 | 98 | void 99 | fe_stanzas_deinit(void) 100 | { 101 | signal_remove("xmpp xml in", (SIGNAL_FUNC)sig_xml_in); 102 | signal_remove("xmpp xml out", (SIGNAL_FUNC)sig_xml_out); 103 | } 104 | -------------------------------------------------------------------------------- /src/fe-common/fe-stanzas.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_STANZAS_H 2 | #define __FE_STANZAS_H 3 | 4 | __BEGIN_DECLS 5 | void fe_stanzas_init(void); 6 | void fe_stanzas_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "core.h" 20 | #include "levels.h" 21 | #include "module-formats.h" 22 | #include "printtext.h" 23 | #include "servers-setup.h" 24 | #include "settings.h" 25 | #include "signals.h" 26 | #include "themes.h" 27 | 28 | #include "fe-xmpp-messages.h" 29 | #include "fe-xmpp-queries.h" 30 | #include "fe-xmpp-status.h" 31 | #include "fe-xmpp-windows.h" 32 | #include "fe-rosters.h" 33 | #include "fe-stanzas.h" 34 | #include "xmpp-completion.h" 35 | #include "xmpp-formats.h" 36 | #include "xep/fe-xep.h" 37 | 38 | static void 39 | sig_server_status(SERVER_REC *server, const char *msg) 40 | { 41 | printformat_module(MODULE_NAME, server, NULL, MSGLEVEL_CLIENTNOTICE, 42 | XMPPTXT_DEFAULT_EVENT, NULL, msg, NULL); 43 | } 44 | 45 | static void 46 | sig_server_add_fill(SERVER_SETUP_REC *rec, GHashTable *optlist) 47 | { 48 | char *value; 49 | 50 | if ((value = g_hash_table_lookup(optlist, "xmppnet")) != NULL) { 51 | g_free_and_null(rec->chatnet); 52 | if (*value != '\0') 53 | rec->chatnet = g_strdup(value); 54 | } 55 | } 56 | 57 | void 58 | fe_xmpp_init(void) 59 | { 60 | theme_register(fecommon_xmpp_formats); 61 | 62 | signal_add("xmpp server status", sig_server_status); 63 | signal_add("server add fill", sig_server_add_fill); 64 | 65 | fe_xmpp_messages_init(); 66 | fe_xmpp_queries_init(); 67 | fe_xmpp_status_init(); 68 | fe_xmpp_windows_init(); 69 | fe_rosters_init(); 70 | fe_stanzas_init(); 71 | xmpp_completion_init(); 72 | xmpp_formats_init(); 73 | fe_xep_init(); 74 | 75 | module_register("xmpp", "fe"); 76 | 77 | /* load irssi-xmpp's fe-text submodule */ 78 | if (irssi_gui == IRSSI_GUI_TEXT) { 79 | char *cmd_line = g_strconcat(settings_get_str("cmdchars"), 80 | "load xmpp text", (void *)NULL); 81 | signal_emit("send command", 1, cmd_line); 82 | g_free(cmd_line); 83 | } 84 | } 85 | 86 | void 87 | fe_xmpp_deinit(void) 88 | { 89 | signal_remove("xmpp server status", sig_server_status); 90 | signal_remove("server add fill", sig_server_add_fill); 91 | 92 | fe_xmpp_messages_deinit(); 93 | fe_xmpp_queries_deinit(); 94 | fe_xmpp_status_deinit(); 95 | fe_xmpp_windows_deinit(); 96 | fe_rosters_deinit(); 97 | fe_stanzas_deinit(); 98 | xmpp_completion_deinit(); 99 | xmpp_formats_deinit(); 100 | fe_xep_deinit(); 101 | 102 | theme_unregister(); 103 | } 104 | 105 | #ifdef IRSSI_ABI_VERSION 106 | void 107 | fe_xmpp_abicheck(int * version) 108 | { 109 | *version = IRSSI_ABI_VERSION; 110 | } 111 | #endif 112 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-messages.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_XMPP_MESSAGES_H 2 | #define __FE_XMPP_MESSAGES_H 3 | 4 | __BEGIN_DECLS 5 | void fe_xmpp_messages_init(void); 6 | void fe_xmpp_messages_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-queries.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "levels.h" 20 | #include "module-formats.h" 21 | #include "printtext.h" 22 | #include "signals.h" 23 | #include "window-items.h" 24 | 25 | #include "xmpp-queries.h" 26 | #include "rosters-tools.h" 27 | #include "fe-xmpp-status.h" 28 | 29 | int query_type; 30 | int chatnet_type; 31 | 32 | static void 33 | sig_presence_changed(XMPP_SERVER_REC *server, const char *full_jid, 34 | int show, const char *status) 35 | { 36 | XMPP_QUERY_REC *rec; 37 | XMPP_ROSTER_USER_REC *user; 38 | const char *msg; 39 | char *name; 40 | 41 | g_return_if_fail(server != NULL); 42 | g_return_if_fail(full_jid != NULL); 43 | g_return_if_fail(0 <= show && show < XMPP_PRESENCE_SHOW_LEN); 44 | if ((rec = xmpp_query_find(server, full_jid)) == NULL) 45 | return; 46 | msg = fe_xmpp_presence_show[show]; 47 | user = rosters_find_user(server->roster, full_jid, NULL, NULL); 48 | name = user != NULL && user->name != NULL ? 49 | format_get_text(MODULE_NAME, NULL, server, NULL, 50 | XMPPTXT_FORMAT_NAME, user->name, full_jid) : 51 | format_get_text(MODULE_NAME, NULL, server, NULL, 52 | XMPPTXT_FORMAT_JID, full_jid); 53 | if (status != NULL) 54 | printformat_module(MODULE_NAME, server, full_jid, MSGLEVEL_CRAP | MSGLEVEL_MODES, 55 | XMPPTXT_PRESENCE_CHANGE_REASON, name, msg, status); 56 | else 57 | printformat_module(MODULE_NAME, server, full_jid, MSGLEVEL_CRAP | MSGLEVEL_MODES, 58 | XMPPTXT_PRESENCE_CHANGE, name, msg); 59 | } 60 | 61 | static void 62 | sig_query_raise(XMPP_SERVER_REC *server, QUERY_REC *query) 63 | { 64 | WINDOW_REC *window; 65 | 66 | g_return_if_fail(query != NULL); 67 | window = window_item_window(query); 68 | if (window != active_win) 69 | window_set_active(window); 70 | window_item_set_active(active_win, (WI_ITEM_REC *)query); 71 | } 72 | 73 | static void 74 | sig_query_created(XMPP_QUERY_REC *query, int automatic) 75 | { 76 | XMPP_ROSTER_USER_REC *user; 77 | 78 | if (!IS_XMPP_QUERY(query)) 79 | return; 80 | user = rosters_find_user(query->server->roster, query->name, NULL, 81 | NULL); 82 | if (user == NULL || user->name == NULL) 83 | return; 84 | printformat_module(MODULE_NAME, query->server, query->name, 85 | MSGLEVEL_CRAP, XMPPTXT_QUERY_AKA, user->jid, user->name); 86 | } 87 | 88 | static void 89 | sig_window_bound_query(SERVER_REC *gserver) 90 | { 91 | XMPP_SERVER_REC *server; 92 | g_return_if_fail(gserver != NULL); 93 | 94 | if ((server = XMPP_SERVER(gserver)) == NULL) 95 | return; 96 | 97 | #if defined(IRSSI_ABI_VERSION) && IRSSI_ABI_VERSION >= 20 98 | GSList *tmp, *tmp2, *bounds; 99 | for (tmp = windows; tmp != NULL; tmp = tmp->next) { 100 | WINDOW_REC *win = tmp->data; 101 | bounds = g_slist_copy(win->bound_items); 102 | 103 | for (tmp2 = bounds; tmp2 != NULL; tmp2 = tmp2->next) { 104 | WINDOW_BIND_REC *bound = tmp2->data; 105 | 106 | if (bound->type == query_type) { 107 | if (server->chat_type == chatnet_type && 108 | g_strcmp0(server->tag, bound->servertag) == 0) { 109 | xmpp_query_create(bound->servertag, bound->name, TRUE); 110 | } 111 | } 112 | } 113 | 114 | g_slist_free(bounds); 115 | } 116 | #endif 117 | } 118 | 119 | void 120 | fe_xmpp_queries_init(void) 121 | { 122 | query_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); 123 | chatnet_type = XMPP_PROTOCOL; 124 | 125 | signal_add("xmpp query raise", sig_query_raise); 126 | signal_add("xmpp presence changed", sig_presence_changed); 127 | signal_add("server connected", sig_window_bound_query); 128 | signal_add_last("query created", sig_query_created); 129 | } 130 | 131 | void 132 | fe_xmpp_queries_deinit(void) 133 | { 134 | signal_remove("xmpp query raise", sig_query_raise); 135 | signal_remove("xmpp presence changed", sig_presence_changed); 136 | signal_remove("server connected", sig_window_bound_query); 137 | signal_remove("query created", sig_query_created); 138 | } 139 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-queries.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_XMPP_QUERIES_H 2 | #define __FE_XMPP_QUERIES_H 3 | 4 | __BEGIN_DECLS 5 | void fe_xmpp_queries_init(void); 6 | void fe_xmpp_queries_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-status.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "levels.h" 22 | #include "module-formats.h" 23 | #include "printtext.h" 24 | #include "settings.h" 25 | #include "signals.h" 26 | #include "window-items.h" 27 | 28 | #include "xmpp-servers.h" 29 | #include "rosters-tools.h" 30 | 31 | const char *fe_xmpp_presence_show[] = { 32 | "Unavailable", 33 | "Error", 34 | "Extended Away", 35 | "Do Not Disturb", 36 | "Away", 37 | "Available", 38 | "Free for Chat", 39 | "Online", 40 | NULL 41 | }; 42 | 43 | const int fe_xmpp_presence_show_format[] = { 44 | XMPPTXT_PRESENCE_UNAVAILABLE, 45 | XMPPTXT_PRESENCE_ERROR, 46 | XMPPTXT_PRESENCE_XA, 47 | XMPPTXT_PRESENCE_DND, 48 | XMPPTXT_PRESENCE_AWAY, 49 | XMPPTXT_PRESENCE_AVAILABLE, 50 | XMPPTXT_PRESENCE_CHAT, 51 | XMPPTXT_PRESENCE_ONLINE, 52 | 0, 53 | }; 54 | 55 | static char * 56 | get_window_name(XMPP_SERVER_REC *server) 57 | { 58 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 59 | return g_strconcat("(", (server->connrec->chatnet == NULL || 60 | *server->connrec->chatnet == '\0') ? server->jid : 61 | server->connrec->chatnet, ")", (void *)NULL); 62 | } 63 | 64 | char * 65 | fe_xmpp_status_get_window_name(XMPP_SERVER_REC *server) 66 | { 67 | WINDOW_REC *window; 68 | char *name; 69 | 70 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 71 | if ((name = get_window_name(server)) == NULL) 72 | return NULL; 73 | window = window_find_name(name); 74 | g_free(name); 75 | return (window != NULL) ? window->name : NULL; 76 | } 77 | 78 | WINDOW_REC * 79 | fe_xmpp_status_get_window(XMPP_SERVER_REC *server) 80 | { 81 | WINDOW_REC *window; 82 | char *name; 83 | 84 | g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); 85 | name = get_window_name(server); 86 | if ((window = window_find_name(name)) == NULL) { 87 | window = window_create(NULL, TRUE); 88 | window_set_name(window, name); 89 | window_change_server(window, server); 90 | } 91 | g_free(name); 92 | return window; 93 | } 94 | 95 | static void 96 | sig_presence_changed(XMPP_SERVER_REC *server, const char *full_jid, 97 | int show, const char *status) 98 | { 99 | XMPP_ROSTER_USER_REC *user; 100 | WINDOW_REC *window; 101 | const char *msg; 102 | char *name; 103 | 104 | g_return_if_fail(IS_XMPP_SERVER(server)); 105 | g_return_if_fail(full_jid != NULL); 106 | g_return_if_fail(0 <= show && show < XMPP_PRESENCE_SHOW_LEN); 107 | window = fe_xmpp_status_get_window(server); 108 | msg = fe_xmpp_presence_show[show]; 109 | user = rosters_find_user(server->roster, full_jid, NULL, NULL); 110 | name = user != NULL && user->name != NULL ? 111 | format_get_text(MODULE_NAME, NULL, server, NULL, 112 | XMPPTXT_FORMAT_NAME, user->name, full_jid) : 113 | format_get_text(MODULE_NAME, NULL, server, NULL, 114 | XMPPTXT_FORMAT_JID, full_jid); 115 | if (status != NULL) 116 | printformat_module_window(MODULE_NAME, window, MSGLEVEL_CRAP | MSGLEVEL_MODES, 117 | XMPPTXT_PRESENCE_CHANGE_REASON, name, msg, status); 118 | else 119 | printformat_module_window(MODULE_NAME, window, MSGLEVEL_CRAP | MSGLEVEL_MODES, 120 | XMPPTXT_PRESENCE_CHANGE, name, msg); 121 | g_free(name); 122 | } 123 | 124 | static void 125 | sig_setup_changed(void) 126 | { 127 | signal_remove("xmpp presence changed", sig_presence_changed); 128 | if (settings_get_bool("xmpp_status_window")) 129 | signal_add("xmpp presence changed", sig_presence_changed); 130 | } 131 | 132 | static void 133 | sig_server_connecting(XMPP_SERVER_REC *server) 134 | { 135 | if (!IS_XMPP_SERVER(server)) 136 | return; 137 | if (settings_get_bool("xmpp_status_window")) 138 | fe_xmpp_status_get_window(server); 139 | } 140 | 141 | void 142 | fe_xmpp_status_init(void) 143 | { 144 | signal_add("server connecting", (SIGNAL_FUNC)sig_server_connecting); 145 | signal_add("setup changed", (SIGNAL_FUNC)sig_setup_changed); 146 | 147 | settings_add_bool("xmpp_lookandfeel", "xmpp_status_window", FALSE); 148 | 149 | if (settings_get_bool("xmpp_status_window")) 150 | signal_add("xmpp presence changed", sig_presence_changed); 151 | } 152 | 153 | void 154 | fe_xmpp_status_deinit(void) 155 | { 156 | signal_remove("server connecting", sig_server_connecting); 157 | signal_remove("setup changed", sig_setup_changed); 158 | signal_remove("xmpp presence changed", sig_presence_changed); 159 | } 160 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-status.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_XMPP_STATUS_H 2 | #define __FE_XMPP_STATUS_H 3 | 4 | extern const char *fe_xmpp_presence_show[]; 5 | extern const int fe_xmpp_presence_show_format[]; 6 | 7 | __BEGIN_DECLS 8 | char *fe_xmpp_status_get_window_name(XMPP_SERVER_REC *); 9 | WINDOW_REC *fe_xmpp_status_get_window(XMPP_SERVER_REC *); 10 | 11 | void fe_xmpp_status_init(void); 12 | void fe_xmpp_status_deinit(void); 13 | __END_DECLS 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-windows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "channels.h" 20 | #include "signals.h" 21 | #include "window-items.h" 22 | 23 | #include "xmpp-servers.h" 24 | 25 | /* 26 | * Hack to get the name of the current XMPP channel which is necessary 27 | * to open a query with a nick in the channel 28 | * (because its jid is like: channel@host/nick) 29 | */ 30 | 31 | static void 32 | sig_get_active_channel(const char **name) 33 | { 34 | *name = IS_XMPP_SERVER(active_win->active_server) 35 | && IS_CHANNEL(active_win->active) ? 36 | ((CHANNEL_REC *)active_win->active)->name : NULL; 37 | } 38 | 39 | void 40 | fe_xmpp_windows_init(void) 41 | { 42 | signal_add("xmpp windows get active channel", sig_get_active_channel); 43 | } 44 | 45 | void 46 | fe_xmpp_windows_deinit(void) 47 | { 48 | signal_remove("xmpp windows get active channel", 49 | sig_get_active_channel); 50 | } 51 | -------------------------------------------------------------------------------- /src/fe-common/fe-xmpp-windows.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_XMPP_WINDOWS_H 2 | #define __FE_XMPP_WINDOWS_H 3 | 4 | __BEGIN_DECLS 5 | void fe_xmpp_windows_init(void); 6 | void fe_xmpp_windows_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/module-formats.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "formats.h" 20 | 21 | FORMAT_REC fecommon_xmpp_formats[] = { 22 | { MODULE_NAME, "XMPP", 0, { 0 } }, 23 | 24 | /* ---- */ 25 | { NULL, "Format", 0, { 0 } }, 26 | 27 | { "format_name", "{nick $0} {nickhost $1}", 2, { 0, 0 } }, 28 | { "format_jid", "{nick $0}", 1, { 0 } }, 29 | { "format_resource", "{comment $0{hilight $1}($2)$3}", 4, { 0, 0, 0, 0 } }, 30 | { "format_resource_show", "($0)", 1, { 0 } }, 31 | { "format_resource_status", ": $0", 1, { 0 } }, 32 | { "format_subscription", "(subscription: $0)", 1, { 0 } }, 33 | 34 | /* ---- */ 35 | { NULL, "Presence", 0, { 0 } }, 36 | 37 | { "presence_unavailable", "%K(◦) $[14]0 ->%n", 1, { 0 } }, 38 | { "presence_error", "%r(!) $[14]0 ->%n", 1, { 0 } }, 39 | { "presence_xa", "%r(x) $[14]0 ->%n", 1, { 0 } }, 40 | { "presence_dnd", "%r(x) $[14]0 ->%n", 1, { 0 } }, 41 | { "presence_away", "%y(-) $[14]0 ->%n", 1, { 0 } }, 42 | { "presence_available", "%_%g(+) $[14]0%_ ->%n", 1, { 0 } }, 43 | { "presence_chat", "%_%g(+) $[14]0%_ ->%n", 1, { 0 } }, 44 | { "presence_online", "%_%g(+) $[14]0%_ ->%n", 1, { 0 } }, 45 | 46 | /* ---- */ 47 | { NULL, "Roster", 0, { 0 } }, 48 | 49 | { "roster_group", " {hilight $0}:", 1, { 0 } }, 50 | { "roster_contact", " ({hilight $0}) $1 $2 $3", 4, { 0, 0, 0, 0 } }, 51 | { "begin_of_roster", "ROSTER: {nick $0} $1 $2", 3, { 0, 0, 0 } }, 52 | { "end_of_roster", "End of ROSTER", 0, { 0 } }, 53 | { "not_in_roster", "{nick $0}: not in the roster", 1, { 0 } }, 54 | 55 | /* ---- */ 56 | { NULL, "Subscription", 0, { 0 } }, 57 | 58 | { "subscribe", "$0: wants to subscribe to your presence {comment $1} (accept or deny?)", 2, { 0, 0 } }, 59 | { "subscribed", "$0: wants you to see their presence", 1, { 0 } }, 60 | { "unsubscribe", "$0: doesn't want to see your presence anymore", 1 , { 0 } }, 61 | { "unsubscribed", "$0: doesn't want you to see their presence anymore", 1 , { 0 } }, 62 | 63 | /* ---- */ 64 | { NULL, "Message", 0, { 0 } }, 65 | 66 | { "message_room", "$0", 1, { 0 } }, 67 | { "message_event", "$0: $1", 2, { 0, 0 } }, 68 | { "message_not_delivered", "$0: cannot deliver message {comment $1}", 2, { 0, 0 } }, 69 | { "message_timestamp", "[{timestamp $0}] $1", 2, { 0, 0 } }, 70 | 71 | /* ---- */ 72 | { NULL, "Queries", 0, { 0 } }, 73 | 74 | { "query_aka", "{nick $0}: Also known as {nick $1}", 2, { 0, 0 } }, 75 | 76 | /* ---- */ 77 | { NULL, "Channel", 0, { 0 } }, 78 | 79 | { "joinerror", "Cannot join to room {channel $0} {comment $1}", 2, { 0, 0 } }, 80 | { "destroyerror", "Cannot destroy room {channel $0} {comment $1}", 2, { 0, 0 } }, 81 | 82 | /* ---- */ 83 | { NULL, "Presence", 0, { 0 } }, 84 | 85 | { "presence_change", "$0: is now {hilight $1}", 2, { 0, 0 } }, 86 | { "presence_change_reason", "$0: is now {hilight $1} {comment $2}", 3, { 0, 0, 0 } }, 87 | 88 | /* ---- */ 89 | { NULL, "VCard", 0, { 0 } }, 90 | 91 | { "vcard", "{nick $0} {nickhost $1}", 2, { 0, 0 } }, 92 | { "vcard_value", " $0: $1", 2, { 0, 0 } }, 93 | { "vcard_subvalue", " $0: $1", 2, { 0, 0 } }, 94 | { "end_of_vcard", "End of VCARD", 0, { 0 } }, 95 | 96 | /* ---- */ 97 | { NULL, "Misc", 0, { 0 } }, 98 | 99 | { "raw_in_header", "RECV[$0]:", 1, { 0 } }, 100 | { "raw_out_header", "SEND[$0]:", 1, { 0 } }, 101 | { "raw_message", "$0", 1, { 0 } }, 102 | { "default_event", "$1 $2", 3, { 0, 0, 0 } }, 103 | { "default_error", "ERROR $1 $2", 3, { 0, 0, 0 } }, 104 | 105 | { NULL, "Registration", 0, { 0 } }, 106 | 107 | { "xmpp_registration_started", "Registering {nick $0@$1}...", 2, { 0, 0 } }, 108 | { "xmpp_registration_succeed", "Registration of {nick $0@$1} succeeded", 2, { 0, 0 } }, 109 | { "xmpp_registration_failed", "Registration of {nick $0@$1} failed {comment $2}", 3, { 0, 0, 0 } }, 110 | 111 | { NULL, NULL, 0, { 0 } } 112 | }; 113 | -------------------------------------------------------------------------------- /src/fe-common/module-formats.h: -------------------------------------------------------------------------------- 1 | #include "formats.h" 2 | 3 | enum { 4 | XMPPTXT_MODULE_NAME, 5 | 6 | XMPPTXT_FILL_1, 7 | 8 | XMPPTXT_FORMAT_NAME, 9 | XMPPTXT_FORMAT_JID, 10 | XMPPTXT_FORMAT_RESOURCE, 11 | XMPPTXT_FORMAT_RESOURCE_SHOW, 12 | XMPPTXT_FORMAT_RESOURCE_STATUS, 13 | XMPPTXT_FORMAT_SUBSCRIPTION, 14 | 15 | XMPPTXT_FILL_2, 16 | 17 | XMPPTXT_PRESENCE_UNAVAILABLE, 18 | XMPPTXT_PRESENCE_ERROR, 19 | XMPPTXT_PRESENCE_XA, 20 | XMPPTXT_PRESENCE_DND, 21 | XMPPTXT_PRESENCE_AWAY, 22 | XMPPTXT_PRESENCE_AVAILABLE, 23 | XMPPTXT_PRESENCE_CHAT, 24 | XMPPTXT_PRESENCE_ONLINE, 25 | 26 | XMPPTXT_FILL_3, 27 | 28 | XMPPTXT_ROSTER_GROUP, 29 | XMPPTXT_ROSTER_CONTACT, 30 | XMPPTXT_BEGIN_OF_ROSTER, 31 | XMPPTXT_END_OF_ROSTER, 32 | XMPPTXT_NOT_IN_ROSTER, 33 | 34 | XMPPTXT_FILL_4, 35 | 36 | XMPPTXT_SUBSCRIBE, 37 | XMPPTXT_SUBSCRIBED, 38 | XMPPTXT_UNSUBSCRIBE, 39 | XMPPTXT_UNSUBSCRIBED, 40 | 41 | XMPPTXT_FILL_5, 42 | 43 | XMPPTXT_MESSAGE_ROOM, 44 | XMPPTXT_MESSAGE_EVENT, 45 | XMPPTXT_MESSAGE_NOT_DELIVERED, 46 | XMPPTXT_MESSAGE_TIMESTAMP, 47 | 48 | XMPPTXT_FILL_6, 49 | 50 | XMPPTXT_QUERY_AKA, 51 | 52 | XMPPTXT_FILL_7, 53 | 54 | XMPPTXT_CHANNEL_JOINERROR, 55 | XMPPTXT_CHANNEL_DESTROYERROR, 56 | 57 | XMPPTXT_FILL_8, 58 | 59 | XMPPTXT_PRESENCE_CHANGE, 60 | XMPPTXT_PRESENCE_CHANGE_REASON, 61 | 62 | XMPPTXT_FILL_9, 63 | 64 | XMPPTXT_VCARD, 65 | XMPPTXT_VCARD_VALUE, 66 | XMPPTXT_VCARD_SUBVALUE, 67 | XMPPTXT_END_OF_VCARD, 68 | 69 | XMPPTXT_FILL_10, 70 | 71 | XMPPTXT_RAW_IN_HEADER, 72 | XMPPTXT_RAW_OUT_HEADER, 73 | XMPPTXT_RAW_MESSAGE, 74 | XMPPTXT_DEFAULT_EVENT, 75 | XMPPTXT_DEFAULT_ERROR, 76 | 77 | XMPPTXT_FILL_11, 78 | 79 | XMPPTXT_REGISTRATION_STARTED, 80 | XMPPTXT_REGISTRATION_SUCCEED, 81 | XMPPTXT_REGISTRATION_FAILED, 82 | }; 83 | 84 | extern FORMAT_REC fecommon_xmpp_formats[]; 85 | -------------------------------------------------------------------------------- /src/fe-common/module.h: -------------------------------------------------------------------------------- 1 | #define MODULE_NAME "fe-common/xmpp" 2 | 3 | #define CORE_MODULE_NAME "fe-common/core" 4 | #define IRC_MODULE_NAME "fe-common/irc" 5 | 6 | #include "irssi-config.h" 7 | #include "common.h" 8 | #include "xmpp.h" 9 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-composing.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "settings.h" 22 | #include "signals.h" 23 | #include "special-vars.h" 24 | #include "window-items.h" 25 | 26 | #include "xmpp-servers.h" 27 | #include "xmpp-queries.h" 28 | #include "tools.h" 29 | 30 | #define KEY_TAB 9 31 | #define KEY_RETURN 10 32 | #define KEY_ESCAPE 27 33 | #define KEYS_PAGE 91 34 | #define KEYS_OTHER 126 35 | #define KEY_BACKSPACE 127 36 | 37 | #define COMPOSING_TIMEOUT 5 38 | 39 | static gboolean keylog_active; 40 | static int last_key; 41 | 42 | #define IS_ALIVE_SERVER(server) \ 43 | ((server) != NULL \ 44 | && g_slist_find(servers, (server)) != NULL \ 45 | && (server)->connected) 46 | 47 | static gboolean 48 | stop_composing(gpointer *user_data) 49 | { 50 | XMPP_QUERY_REC *query = XMPP_QUERY(user_data); 51 | 52 | if (query == NULL || query->composing_time == 0 53 | || !IS_ALIVE_SERVER(query->server)) 54 | return FALSE; 55 | /* still composing */ 56 | if ((time(NULL) - query->composing_time) < COMPOSING_TIMEOUT) 57 | return TRUE; 58 | signal_emit("xmpp composing stop", 2, query->server, query->name); 59 | query->composing_time = 0; 60 | return FALSE; 61 | } 62 | 63 | static void 64 | sig_gui_key_pressed(int key) 65 | { 66 | XMPP_QUERY_REC *query; 67 | time_t current_time; 68 | char *str = NULL; 69 | 70 | if (!settings_get_bool("xmpp_send_composing") && keylog_active) 71 | return; 72 | query = XMPP_QUERY(active_win->active); 73 | if (query == NULL || !IS_XMPP_SERVER(query->server)) 74 | return; 75 | /* ignore command or empty line */ 76 | str = parse_special_string("$L", active_win->active_server, 77 | active_win->active, "", NULL, 0); 78 | if (str != NULL && 79 | (*str == *settings_get_str("cmdchars") || *str == '\0')) 80 | goto out; 81 | if (key != KEY_TAB && key != KEY_RETURN && last_key != KEY_ESCAPE 82 | && key != KEY_ESCAPE && last_key != KEYS_PAGE && key != KEYS_PAGE 83 | && key != KEYS_OTHER && key != KEY_BACKSPACE) { 84 | current_time = time(NULL); 85 | /* start composing */ 86 | if (query->composing_time == 0) { 87 | query->composing_time = current_time; 88 | g_timeout_add(COMPOSING_TIMEOUT * 1000, 89 | (GSourceFunc)stop_composing, query); 90 | signal_emit("xmpp composing start", 2, 91 | query->server, query->name); 92 | /* still composing */ 93 | } else if ((current_time - query->composing_time) 94 | < (COMPOSING_TIMEOUT - 1)) 95 | query->composing_time = current_time; 96 | } 97 | 98 | out: 99 | /* message sent */ 100 | if (key == KEY_RETURN) 101 | query->composing_time = 0; 102 | last_key = key; 103 | g_free(str); 104 | } 105 | 106 | static void 107 | keyloger_enabled(gboolean enable) 108 | { 109 | if (enable && !keylog_active) { 110 | signal_add_last("gui key pressed", sig_gui_key_pressed); 111 | keylog_active = TRUE; 112 | } else if (!enable && keylog_active) { 113 | signal_remove("gui key pressed", sig_gui_key_pressed); 114 | keylog_active = FALSE; 115 | } 116 | } 117 | 118 | 119 | static void 120 | sig_window_changed(WINDOW_REC *new_window, WINDOW_REC *old_window) 121 | { 122 | XMPP_SERVER_REC *server; 123 | XMPP_QUERY_REC *query; 124 | 125 | if (!settings_get_bool("xmpp_send_composing") 126 | || (server = XMPP_SERVER(active_win->active_server)) == NULL) { 127 | keyloger_enabled(FALSE); 128 | return; 129 | } 130 | query = XMPP_QUERY(active_win->active); 131 | if (query == NULL || !xmpp_have_resource(query->name)) 132 | keyloger_enabled(FALSE); 133 | else 134 | keyloger_enabled(TRUE); 135 | } 136 | 137 | static void 138 | sig_query_destroyed(QUERY_REC *query_destroyed) 139 | { 140 | XMPP_QUERY_REC *query; 141 | 142 | query = XMPP_QUERY(query_destroyed); 143 | if (query != NULL && query->composing_time != 0 144 | && IS_ALIVE_SERVER(query->server)) 145 | signal_emit("xmpp composing stop", 2, query->server, 146 | query->name); 147 | } 148 | 149 | static void 150 | sig_disconnected(XMPP_SERVER_REC *server) 151 | { 152 | GSList *tmp; 153 | XMPP_QUERY_REC *query; 154 | 155 | if (!IS_XMPP_SERVER(server)) 156 | return; 157 | for (tmp = queries; tmp != NULL; tmp = tmp->next) { 158 | query = XMPP_QUERY(tmp->data); 159 | if (query == NULL) 160 | continue; 161 | if (query->server == server) 162 | g_source_remove_by_user_data(query); 163 | } 164 | } 165 | 166 | void 167 | fe_composing_init(void) 168 | { 169 | signal_add_last("window changed", sig_window_changed); 170 | signal_add("query destroyed", sig_query_destroyed); 171 | signal_add("server disconnected", sig_disconnected); 172 | 173 | settings_add_bool("xmpp", "xmpp_send_composing", TRUE); 174 | keylog_active = FALSE; 175 | last_key = 0; 176 | } 177 | 178 | void 179 | fe_composing_deinit(void) 180 | { 181 | signal_remove("window changed", sig_window_changed); 182 | signal_remove("query destroyed", sig_query_destroyed); 183 | signal_remove("server disconnected", sig_disconnected); 184 | 185 | keyloger_enabled(FALSE); 186 | } 187 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-composing.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_COMPOSING_H 2 | #define __FE_COMPOSING_H 3 | 4 | __BEGIN_DECLS 5 | void fe_composing_init(void); 6 | void fe_composing_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-delay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "levels.h" 20 | #include "module-formats.h" 21 | #include "printtext.h" 22 | #include "settings.h" 23 | #include "signals.h" 24 | #include "window-items.h" 25 | #include "fe-messages.h" 26 | #include "fe-queries.h" 27 | #include "fe-common/core/module-formats.h" 28 | #include "fe-common/core/fe-messages.h" 29 | #include "fe-common/irc/module-formats.h" 30 | 31 | #include "xmpp-servers.h" 32 | #include "rosters-tools.h" 33 | #include "xep/muc.h" 34 | 35 | static void 36 | sig_message_delay(SERVER_REC *server, const char *msg, const char *nick, 37 | const char *target, time_t *t, gpointer gpointer_type) 38 | { 39 | void *item; 40 | char *text, *freemsg = NULL; 41 | char stamp[BUFSIZ]; 42 | int level, type; 43 | 44 | g_return_if_fail(server != NULL); 45 | g_return_if_fail(msg != NULL); 46 | g_return_if_fail(nick != NULL); 47 | g_return_if_fail(target != NULL); 48 | 49 | type = GPOINTER_TO_INT(gpointer_type); 50 | level = MSGLEVEL_NO_ACT | MSGLEVEL_NOHILIGHT 51 | | (type == SEND_TARGET_CHANNEL ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); 52 | item = type == SEND_TARGET_CHANNEL ? 53 | (void *)get_muc((XMPP_SERVER_REC *)server, target) : 54 | query_find(server, nick); 55 | 56 | if (settings_get_bool("emphasis")) 57 | msg = freemsg = expand_emphasis(item, msg); 58 | 59 | /* MUC */ 60 | if (type == SEND_TARGET_CHANNEL) { 61 | CHANNEL_REC *chanrec = item; 62 | int print_channel; 63 | char *nickmode; 64 | 65 | print_channel = chanrec == NULL || 66 | !window_item_is_active((WI_ITEM_REC *)chanrec); 67 | if (!print_channel 68 | && settings_get_bool("print_active_channel") 69 | && window_item_window((WI_ITEM_REC *)chanrec)->items->next 70 | != NULL) 71 | print_channel = TRUE; 72 | nickmode = channel_get_nickmode(chanrec, nick); 73 | 74 | text = !print_channel ? 75 | format_get_text(CORE_MODULE_NAME, NULL, server, 76 | target, TXT_PUBMSG, nick, msg, nickmode) : 77 | format_get_text(CORE_MODULE_NAME, NULL, server, 78 | target, TXT_PUBMSG_CHANNEL, nick, target, msg, 79 | nickmode); 80 | 81 | g_free(nickmode); 82 | 83 | /* General */ 84 | } else 85 | text = format_get_text(CORE_MODULE_NAME, NULL, server, 86 | target, item == NULL ? TXT_MSG_PRIVATE : 87 | TXT_MSG_PRIVATE_QUERY, nick, nick, msg); 88 | 89 | if (strftime(stamp, sizeof(stamp)-1, 90 | settings_get_str("xmpp_timestamp_format"), localtime(t)) == 0) 91 | stamp[sizeof(stamp)-1] = '\0'; 92 | 93 | printformat_module(MODULE_NAME, server, target, 94 | level, XMPPTXT_MESSAGE_TIMESTAMP, 95 | stamp, text); 96 | 97 | g_free_not_null(freemsg); 98 | g_free(text); 99 | } 100 | 101 | static void 102 | sig_message_delay_action(SERVER_REC *server, const char *msg, const char *nick, 103 | const char *target, time_t *t, gpointer gpointer_type) 104 | { 105 | void *item; 106 | char *text, *freemsg = NULL; 107 | char stamp[BUFSIZ]; 108 | int level, type; 109 | 110 | g_return_if_fail(server != NULL); 111 | g_return_if_fail(msg != NULL); 112 | g_return_if_fail(nick != NULL); 113 | g_return_if_fail(target != NULL); 114 | 115 | type = GPOINTER_TO_INT(gpointer_type); 116 | level = MSGLEVEL_ACTIONS | MSGLEVEL_NO_ACT | MSGLEVEL_NOHILIGHT 117 | | (type == SEND_TARGET_CHANNEL ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); 118 | item = type == SEND_TARGET_CHANNEL ? 119 | (void *)get_muc((XMPP_SERVER_REC *)server, target) : 120 | query_find(server, nick); 121 | 122 | if (settings_get_bool("emphasis")) 123 | msg = freemsg = expand_emphasis(item, msg); 124 | 125 | /* MUC */ 126 | if (type == SEND_TARGET_CHANNEL) { 127 | if (item && window_item_is_active(item)) 128 | text = format_get_text(IRC_MODULE_NAME, NULL, server, 129 | target, IRCTXT_ACTION_PUBLIC, nick, msg); 130 | else 131 | text = format_get_text(IRC_MODULE_NAME, NULL, server, 132 | target, IRCTXT_ACTION_PUBLIC_CHANNEL, nick, 133 | target, msg); 134 | 135 | /* General */ 136 | } else 137 | text = format_get_text(IRC_MODULE_NAME, NULL, server, 138 | nick, (item == NULL) ? IRCTXT_ACTION_PRIVATE : 139 | IRCTXT_ACTION_PRIVATE_QUERY, nick, nick, msg); 140 | 141 | if (strftime(stamp, sizeof(stamp)-1, 142 | settings_get_str("xmpp_timestamp_format"), localtime(t)) == 0) 143 | stamp[sizeof(stamp)-1] = '\0'; 144 | 145 | printformat_module(MODULE_NAME, server, target, level, 146 | XMPPTXT_MESSAGE_TIMESTAMP, stamp, text); 147 | 148 | g_free(freemsg); 149 | } 150 | 151 | void 152 | fe_delay_init(void) 153 | { 154 | settings_add_str("xmpp_lookandfeel", "xmpp_timestamp_format", 155 | "%Y-%m-%d %H:%M"); 156 | signal_add("message xmpp delay", sig_message_delay); 157 | signal_add("message xmpp delay action", sig_message_delay_action); 158 | } 159 | 160 | void 161 | fe_delay_deinit(void) 162 | { 163 | signal_remove("message xmpp delay", sig_message_delay); 164 | signal_remove("message xmpp delay action", sig_message_delay_action); 165 | } 166 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-delay.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_DELAY_H 2 | #define __FE_DELAY_H 3 | 4 | __BEGIN_DECLS 5 | void fe_delay_init(void); 6 | void fe_delay_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-muc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "ignore.h" 20 | #include "levels.h" 21 | #include "module-formats.h" 22 | #include "printtext.h" 23 | #include "signals.h" 24 | #include "window-items.h" 25 | #include "fe-common/core/module-formats.h" 26 | #include "fe-common/irc/module-formats.h" 27 | 28 | #include "xmpp-servers.h" 29 | #include "xmpp-commands.h" 30 | #include "rosters-tools.h" 31 | #include "xep/muc.h" 32 | #include "xep/muc-nicklist.h" 33 | #include "xep/muc-affiliation.h" 34 | #include "xep/muc-role.h" 35 | 36 | static void 37 | sig_invite(XMPP_SERVER_REC *server, const char *from, const char *channame) 38 | { 39 | const char *name; 40 | 41 | name = rosters_get_name(server, from); 42 | if (name == NULL) 43 | name = from; 44 | printformat_module(CORE_MODULE_NAME, server, from, MSGLEVEL_INVITES, 45 | TXT_INVITE, name, channame, from); 46 | } 47 | 48 | static void 49 | sig_joinerror(MUC_REC *channel, gpointer error) 50 | { 51 | char *reason; 52 | 53 | g_return_if_fail(IS_MUC(channel)); 54 | switch(GPOINTER_TO_INT(error)) { 55 | case MUC_ERROR_PASSWORD_INVALID_OR_MISSING: 56 | reason = "Password required"; 57 | break; 58 | case MUC_ERROR_USER_BANNED: 59 | reason = "Banned from the room"; 60 | break; 61 | case MUC_ERROR_ROOM_NOT_FOUND: 62 | reason = "The room does not exist"; 63 | break; 64 | case MUC_ERROR_ROOM_CREATION_RESTRICTED: 65 | reason = "Room creation is restricted"; 66 | break; 67 | case MUC_ERROR_USE_RESERVED_ROOM_NICK: 68 | reason = "Your desired nick is reserved (Retrying with your alternate nick...)"; 69 | break; 70 | case MUC_ERROR_NOT_ON_MEMBERS_LIST: 71 | reason = "You are not on the member list"; 72 | break; 73 | case MUC_ERROR_NICK_IN_USE: 74 | reason = "Your desired nick is already in use (Retrying with your alternate nick...)"; 75 | break; 76 | case MUC_ERROR_MAXIMUM_USERS_REACHED: 77 | reason = "Maximum number of users has been reached"; 78 | break; 79 | default: 80 | reason = "Unknown reason"; 81 | } 82 | printformat_module(MODULE_NAME, channel->server, NULL, 83 | MSGLEVEL_CRAP, XMPPTXT_CHANNEL_JOINERROR, 84 | channel->name, reason); 85 | } 86 | 87 | static void 88 | sig_destroyerror(MUC_REC *channel, const char *reason) 89 | { 90 | printformat_module(MODULE_NAME, channel->server, NULL, 91 | MSGLEVEL_CRAP, XMPPTXT_CHANNEL_DESTROYERROR, 92 | channel->name, reason); 93 | } 94 | 95 | static void 96 | sig_nick(MUC_REC *channel, NICK_REC *nick, const char *oldnick) 97 | { 98 | g_return_if_fail(IS_MUC(channel)); 99 | g_return_if_fail(nick != NULL); 100 | g_return_if_fail(oldnick != NULL); 101 | if (ignore_check(SERVER(channel->server), oldnick, nick->host, 102 | channel->nick, nick->nick, MSGLEVEL_NICKS)) 103 | return; 104 | printformat_module(CORE_MODULE_NAME, channel->server, channel->name, 105 | MSGLEVEL_NICKS, TXT_NICK_CHANGED, oldnick, nick->nick, 106 | channel->name, nick->host); 107 | } 108 | 109 | static void 110 | sig_own_nick(MUC_REC *channel, NICK_REC *nick, const char *oldnick) 111 | { 112 | g_return_if_fail(IS_MUC(channel)); 113 | g_return_if_fail(nick != NULL); 114 | g_return_if_fail(oldnick != NULL); 115 | 116 | if (channel->ownnick != nick) 117 | return; 118 | printformat_module(CORE_MODULE_NAME, channel->server, channel->name, 119 | MSGLEVEL_NICKS | MSGLEVEL_NO_ACT, TXT_YOUR_NICK_CHANGED, oldnick, 120 | nick->nick, channel->name, nick->host); 121 | } 122 | 123 | void 124 | sig_nick_in_use(MUC_REC *channel, const char *nick) 125 | { 126 | g_return_if_fail(IS_MUC(channel)); 127 | g_return_if_fail(nick != NULL); 128 | if (!channel->joined) 129 | return; 130 | printformat_module(IRC_MODULE_NAME, channel->server, channel->name, 131 | MSGLEVEL_CRAP, IRCTXT_NICK_IN_USE, nick); 132 | } 133 | 134 | static void 135 | sig_mode(MUC_REC *channel, const char *nickname, int affiliation, 136 | int role) 137 | { 138 | XMPP_NICK_REC *nick; 139 | char *mode, *affiliation_str, *role_str; 140 | 141 | g_return_if_fail(IS_MUC(channel)); 142 | g_return_if_fail(nickname != NULL); 143 | if ((nick = xmpp_nicklist_find(channel, nickname)) == NULL) 144 | return; 145 | switch (affiliation) { 146 | case XMPP_AFFILIATION_OWNER: 147 | affiliation_str = "O"; 148 | break; 149 | case XMPP_AFFILIATION_ADMIN: 150 | affiliation_str = "A"; 151 | break; 152 | case XMPP_AFFILIATION_MEMBER: 153 | affiliation_str = "M"; 154 | break; 155 | case XMPP_AFFILIATION_OUTCAST: 156 | affiliation_str = "U"; 157 | break; 158 | default: 159 | affiliation_str = ""; 160 | } 161 | switch (role) { 162 | case XMPP_ROLE_MODERATOR: 163 | role_str = "m"; 164 | break; 165 | case XMPP_ROLE_PARTICIPANT: 166 | role_str = "p"; 167 | break; 168 | case XMPP_ROLE_VISITOR: 169 | role_str = "v"; 170 | break; 171 | default: 172 | role_str = ""; 173 | } 174 | if (*affiliation_str == '\0' && *role_str == '\0') 175 | return; 176 | mode = g_strconcat("+", affiliation_str, role_str, " ", nickname, 177 | (void *)NULL); 178 | if (ignore_check(SERVER(channel->server), nickname, nick->host, 179 | channel->name, mode, MSGLEVEL_MODES)) 180 | goto out; 181 | printformat_module(IRC_MODULE_NAME, channel->server, channel->name, 182 | MSGLEVEL_MODES, IRCTXT_CHANMODE_CHANGE, channel->name, mode, 183 | channel->name); 184 | out: g_free(mode); 185 | } 186 | 187 | static void 188 | sig_affiliation(MUC_REC *channel, const char *jid, const char *nickname, int affiliation) 189 | { 190 | char *mode, *affiliation_str; 191 | 192 | g_return_if_fail(IS_MUC(channel)); 193 | 194 | switch (affiliation) { 195 | case XMPP_AFFILIATION_OWNER: 196 | affiliation_str = "O"; 197 | break; 198 | case XMPP_AFFILIATION_ADMIN: 199 | affiliation_str = "A"; 200 | break; 201 | case XMPP_AFFILIATION_MEMBER: 202 | affiliation_str = "M"; 203 | break; 204 | case XMPP_AFFILIATION_OUTCAST: 205 | affiliation_str = "U"; 206 | break; 207 | default: 208 | affiliation_str = ""; 209 | } 210 | if (*affiliation_str == '\0') 211 | return; 212 | mode = g_strconcat("+", affiliation_str, " ", jid, 213 | (void *)NULL); 214 | printformat_module(IRC_MODULE_NAME, channel->server, channel->name, 215 | MSGLEVEL_MODES, IRCTXT_CHANMODE_CHANGE, channel->name, mode, 216 | channel->name); 217 | g_free(mode); 218 | } 219 | 220 | struct cycle_data { 221 | XMPP_SERVER_REC *server; 222 | char *joindata; 223 | }; 224 | 225 | static int 226 | cycle_join(struct cycle_data *cd) 227 | { 228 | if (IS_XMPP_SERVER(cd->server)) 229 | muc_join(cd->server, cd->joindata, FALSE); 230 | g_free(cd->joindata); 231 | free(cd); 232 | return FALSE; 233 | } 234 | 235 | /* SYNTAX: CYCLE [] */ 236 | static void 237 | cmd_cycle(const char *data, SERVER_REC *server, WI_ITEM_REC *item) 238 | { 239 | MUC_REC *channel; 240 | char *channame, *reason, *joindata; 241 | struct cycle_data *cd; 242 | void *free_arg; 243 | 244 | g_return_if_fail(data != NULL); 245 | CMD_XMPP_SERVER(server); 246 | if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | 247 | PARAM_FLAG_GETREST, item, &channame, &reason)) 248 | return; 249 | if (*channame == '\0') 250 | cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); 251 | if ((channel = muc_find(server, channame)) == NULL) 252 | cmd_param_error(CMDERR_NOT_JOINED); 253 | joindata = channel->get_join_data(CHANNEL(channel)); 254 | window_bind_add(window_item_window(channel), 255 | channel->server->tag, channel->name); 256 | muc_part(channel, reason); 257 | if ((cd = malloc(sizeof(struct cycle_data))) != NULL) { 258 | cd->server = XMPP_SERVER(server); 259 | cd->joindata = joindata; 260 | g_timeout_add(1000, (GSourceFunc)cycle_join, cd); 261 | } else { 262 | muc_join(XMPP_SERVER(server), joindata, FALSE); 263 | free(joindata); 264 | } 265 | cmd_params_free(free_arg); 266 | signal_stop(); 267 | } 268 | 269 | void 270 | fe_muc_init(void) 271 | { 272 | signal_add("xmpp invite", sig_invite); 273 | signal_add("xmpp muc joinerror", sig_joinerror); 274 | signal_add("xmpp muc destroyerror", sig_destroyerror); 275 | signal_add("message xmpp muc nick", sig_nick); 276 | signal_add("message xmpp muc own_nick", sig_own_nick); 277 | signal_add("message xmpp muc nick in use", sig_nick_in_use); 278 | signal_add("message xmpp muc mode", sig_mode); 279 | signal_add("message xmpp muc affiliation", sig_affiliation); 280 | signal_add_first("command cycle", cmd_cycle); 281 | } 282 | 283 | void 284 | fe_muc_deinit(void) 285 | { 286 | signal_remove("xmpp invite", sig_invite); 287 | signal_remove("xmpp muc joinerror", sig_joinerror); 288 | signal_remove("xmpp muc destroyerror", sig_destroyerror); 289 | signal_remove("message xmpp muc nick", sig_nick); 290 | signal_remove("message xmpp muc own_nick", sig_own_nick); 291 | signal_remove("message xmpp muc nick in use", sig_nick_in_use); 292 | signal_remove("message xmpp muc mode", sig_mode); 293 | signal_remove("command cycle", cmd_cycle); 294 | } 295 | 296 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-muc.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_MUC_H 2 | #define __FE_MUC_H 3 | 4 | __BEGIN_DECLS 5 | void fe_muc_init(void); 6 | void fe_muc_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-ping.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "levels.h" 20 | #include "printtext.h" 21 | #include "signals.h" 22 | #include "fe-common/irc/module-formats.h" 23 | 24 | #include "xmpp-servers.h" 25 | #include "rosters-tools.h" 26 | #include "../module-formats.h" 27 | 28 | static void 29 | sig_ping(XMPP_SERVER_REC *server, const char *jid, long usecs) 30 | { 31 | printformat_module(IRC_MODULE_NAME, server, jid, MSGLEVEL_CRAP, 32 | IRCTXT_CTCP_PING_REPLY, jid, usecs/1000, usecs%1000); 33 | } 34 | 35 | void 36 | fe_ping_init(void) 37 | { 38 | signal_add("xmpp ping", sig_ping); 39 | } 40 | 41 | void 42 | fe_ping_deinit(void) 43 | { 44 | signal_remove("xmpp ping", sig_ping); 45 | } 46 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-ping.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_PING_H 2 | #define __FE_PING_H 3 | 4 | __BEGIN_DECLS 5 | void fe_ping_init(void); 6 | void fe_ping_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-registration.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "ignore.h" 20 | #include "levels.h" 21 | #include "module-formats.h" 22 | #include "printtext.h" 23 | #include "signals.h" 24 | #include "fe-common/core/module-formats.h" 25 | #include "fe-common/irc/module-formats.h" 26 | 27 | #include "xmpp-servers.h" 28 | #include "xep/registration.h" 29 | 30 | static void 31 | sig_failed(const char *username, const char *domain, gpointer error) 32 | { 33 | char *reason, *str = NULL; 34 | 35 | switch(GPOINTER_TO_INT(error)) { 36 | case REGISTRATION_ERROR_UNAUTHORIZED: 37 | case REGISTRATION_ERROR_UNAUTHORIZED_REG: 38 | reason = "Registration unauthorized"; 39 | break; 40 | case REGISTRATION_ERROR_UNIMPLEMENTED: 41 | case REGISTRATION_ERROR_UNAVAILABLE: 42 | reason = "Service unavailable"; 43 | break; 44 | case REGISTRATION_ERROR_CONFLICT: 45 | reason = "Account already exists"; 46 | break; 47 | case REGISTRATION_ERROR_TIMEOUT: 48 | case REGISTRATION_ERROR_TIMEOUT_SERVER: 49 | reason = "Connection times out"; 50 | break; 51 | case REGISTRATION_ERROR_CLOSED: 52 | reason = "Connection was closed"; 53 | break; 54 | case REGISTRATION_ERROR_CONNECTION: 55 | reason = "Cannot open connection"; 56 | break; 57 | case REGISTRATION_ERROR_INFO: 58 | reason = "Cannot send registration information"; 59 | break; 60 | case REGISTRATION_ERROR_UNKNOWN: 61 | reason = "Cannot register account (unknown reason)"; 62 | break; 63 | default: 64 | reason = str = g_strdup_printf("Cannot register account (%d)", 65 | GPOINTER_TO_INT(error)); 66 | } 67 | printformat_module(MODULE_NAME, NULL, NULL, 68 | MSGLEVEL_CRAP, XMPPTXT_REGISTRATION_FAILED, username, domain, 69 | reason); 70 | g_free(str); 71 | } 72 | 73 | static void 74 | sig_succeed(const char *username, const char *domain) 75 | { 76 | printformat_module(MODULE_NAME, NULL, NULL, 77 | MSGLEVEL_CRAP, XMPPTXT_REGISTRATION_SUCCEED, username, domain); 78 | } 79 | 80 | static void 81 | sig_started(const char *username, const char *domain) 82 | { 83 | printformat_module(MODULE_NAME, NULL, NULL, 84 | MSGLEVEL_CRAP, XMPPTXT_REGISTRATION_STARTED, username, domain); 85 | } 86 | 87 | void 88 | fe_registration_init(void) 89 | { 90 | signal_add("xmpp registration failed", sig_failed); 91 | signal_add("xmpp registration succeed", sig_succeed); 92 | signal_add("xmpp registration started", sig_started); 93 | } 94 | 95 | void 96 | fe_registration_deinit(void) 97 | { 98 | signal_remove("xmpp registration failed", sig_failed); 99 | signal_remove("xmpp registration succeed", sig_succeed); 100 | signal_remove("xmpp registration started", sig_started); 101 | } 102 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-registration.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_REGISTRATION_H 2 | #define __FE_REGISTRATION_H 3 | 4 | __BEGIN_DECLS 5 | void fe_registration_init(void); 6 | void fe_registration_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-vcard.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "levels.h" 20 | #include "printtext.h" 21 | #include "signals.h" 22 | 23 | #include "xmpp-servers.h" 24 | #include "rosters-tools.h" 25 | #include "tools.h" 26 | #include "../module-formats.h" 27 | 28 | struct vcard_user_data { 29 | XMPP_SERVER_REC *server; 30 | const char *jid; 31 | }; 32 | 33 | static void 34 | func_vcard_value(const char *key, const char *value, struct vcard_user_data *ud) 35 | { 36 | printformat_module(MODULE_NAME, ud->server, ud->jid, MSGLEVEL_CRAP, 37 | XMPPTXT_VCARD_VALUE, key, value); 38 | } 39 | 40 | #if 0 41 | 42 | static void 43 | func_vcard_subvalue(const char *key, const char *value, 44 | struct vcard_user_data *ud) 45 | { 46 | printformat_module(MODULE_NAME, ud->server, ud->jid, MSGLEVEL_CRAP, 47 | XMPPTXT_VCARD_SUBVALUE, key, value); 48 | } 49 | 50 | #endif 51 | 52 | static void 53 | sig_vcard(XMPP_SERVER_REC *server, const char *jid, GHashTable *ht) 54 | { 55 | XMPP_ROSTER_USER_REC *user; 56 | struct vcard_user_data ud; 57 | char *name; 58 | 59 | user = rosters_find_user(server->roster, jid, NULL, NULL); 60 | name = user != NULL && user->name != NULL ? 61 | g_strdup(user->name) : xmpp_strip_resource(jid); 62 | printformat_module(MODULE_NAME, server, jid, MSGLEVEL_CRAP, 63 | XMPPTXT_VCARD, name, jid); 64 | g_free(name); 65 | ud.server = server; 66 | ud.jid = jid; 67 | g_hash_table_foreach(ht, 68 | (void (*)(gpointer, gpointer, gpointer))func_vcard_value, &ud); 69 | printformat_module(MODULE_NAME, server, jid, MSGLEVEL_CRAP, 70 | XMPPTXT_END_OF_VCARD); 71 | } 72 | 73 | void 74 | fe_vcard_init(void) 75 | { 76 | signal_add("xmpp vcard", sig_vcard); 77 | } 78 | 79 | void 80 | fe_vcard_deinit(void) 81 | { 82 | signal_remove("xmpp vcard", sig_vcard); 83 | } 84 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-vcard.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_VCARD_H 2 | #define __FE_VCARD_H 3 | 4 | __BEGIN_DECLS 5 | void fe_vcard_init(void); 6 | void fe_vcard_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "levels.h" 20 | #include "printtext.h" 21 | #include "signals.h" 22 | 23 | #include "xmpp-servers.h" 24 | #include "rosters-tools.h" 25 | #include "../module-formats.h" 26 | 27 | static void 28 | sig_version(XMPP_SERVER_REC *server, const char *jid, const char *client, 29 | const char *version, const char *os) 30 | { 31 | XMPP_ROSTER_USER_REC *user; 32 | char *name, *str; 33 | 34 | g_return_if_fail(jid != NULL); 35 | if (client == NULL && version == NULL && os == NULL) 36 | return; 37 | str = g_strconcat("is running ", 38 | client != NULL ? client : "", 39 | client != NULL && version != NULL ? " " : "", 40 | version != NULL ? version : "", 41 | (client != NULL || version != NULL) && os != NULL ? " - " : "", 42 | os != NULL ? "on " : "", 43 | os != NULL ? os : "", (void *)NULL); 44 | user = rosters_find_user(server->roster, jid, NULL, NULL); 45 | name = user != NULL && user->name != NULL ? 46 | format_get_text(MODULE_NAME, NULL, server, NULL, 47 | XMPPTXT_FORMAT_NAME, user->name, jid) : 48 | format_get_text(MODULE_NAME, NULL, server, NULL, 49 | XMPPTXT_FORMAT_JID, jid); 50 | printformat_module(MODULE_NAME, server, jid, MSGLEVEL_CRAP, 51 | XMPPTXT_MESSAGE_EVENT, name, str); 52 | g_free(name); 53 | g_free(str); 54 | } 55 | 56 | void 57 | fe_version_init(void) 58 | { 59 | signal_add("xmpp version", sig_version); 60 | } 61 | 62 | void 63 | fe_version_deinit(void) 64 | { 65 | signal_remove("xmpp version", sig_version); 66 | } 67 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-version.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_VERSION_H 2 | #define __FE_VERSION_H 3 | 4 | __BEGIN_DECLS 5 | void fe_version_init(void); 6 | void fe_version_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-xep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007,2008,2009 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | 20 | #include "fe-composing.h" 21 | #include "fe-delay.h" 22 | #include "fe-muc.h" 23 | #include "fe-ping.h" 24 | #include "fe-registration.h" 25 | #include "fe-vcard.h" 26 | #include "fe-version.h" 27 | 28 | void 29 | fe_xep_init(void) 30 | { 31 | fe_composing_init(); 32 | fe_delay_init(); 33 | fe_muc_init(); 34 | fe_ping_init(); 35 | fe_registration_init(); 36 | fe_vcard_init(); 37 | fe_version_init(); 38 | } 39 | 40 | void 41 | fe_xep_deinit(void) 42 | { 43 | fe_composing_deinit(); 44 | fe_delay_deinit(); 45 | fe_muc_deinit(); 46 | fe_ping_deinit(); 47 | fe_registration_deinit(); 48 | fe_vcard_deinit(); 49 | fe_version_deinit(); 50 | } 51 | -------------------------------------------------------------------------------- /src/fe-common/xep/fe-xep.h: -------------------------------------------------------------------------------- 1 | #ifndef __FE_XEP_H 2 | #define __FE_XEP_H 3 | 4 | __BEGIN_DECLS 5 | void fe_xep_init(void); 6 | void fe_xep_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xmpp-completion.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_COMPLETION_H 2 | #define __XMPP_COMPLETION_H 3 | 4 | __BEGIN_DECLS 5 | void xmpp_completion_init(void); 6 | void xmpp_completion_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-common/xmpp-formats.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "formats.h" 20 | #include "signals.h" 21 | 22 | static void 23 | sig_strip_codes(const char *in, const char **out) 24 | { 25 | if (out != NULL) 26 | *out = strip_codes(in); 27 | } 28 | 29 | void 30 | xmpp_formats_init(void) 31 | { 32 | signal_add("xmpp formats strip codes", sig_strip_codes); 33 | } 34 | 35 | void 36 | xmpp_formats_deinit(void) 37 | { 38 | signal_remove("xmpp formats strip codes", sig_strip_codes); 39 | } 40 | -------------------------------------------------------------------------------- /src/fe-common/xmpp-formats.h: -------------------------------------------------------------------------------- 1 | #ifndef __XMPP_FORMATS_H 2 | #define __XMPP_FORMATS_H 3 | 4 | __BEGIN_DECLS 5 | void xmpp_formats_init(void); 6 | void xmpp_formats_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-text/Makefile: -------------------------------------------------------------------------------- 1 | LIB= text_xmpp 2 | SRCS= text-xmpp-core.c \ 3 | xep/text-composing.c \ 4 | xep/text-muc.c \ 5 | xep/text-xep.c 6 | 7 | LIB_INCS = -I../../src/fe-text/include/irssi/src/fe-text 8 | LIB_LIBS = `pkg-config --libs glib-2.0` 9 | 10 | include ../rules.mk 11 | -------------------------------------------------------------------------------- /src/fe-text/module.h: -------------------------------------------------------------------------------- 1 | #define MODULE_NAME "xmpp/text" 2 | 3 | #include "irssi-config.h" 4 | #include "common.h" 5 | #include "xmpp.h" 6 | -------------------------------------------------------------------------------- /src/fe-text/text-xmpp-core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "modules.h" 20 | 21 | #include "xep/text-xep.h" 22 | 23 | void 24 | text_xmpp_init(void) 25 | { 26 | text_xep_init(); 27 | 28 | module_register("xmpp", "text"); 29 | } 30 | 31 | void 32 | text_xmpp_deinit(void) 33 | { 34 | text_xep_deinit(); 35 | } 36 | 37 | #ifdef IRSSI_ABI_VERSION 38 | void 39 | text_xmpp_abicheck(int * version) 40 | { 41 | *version = IRSSI_ABI_VERSION; 42 | } 43 | #endif 44 | -------------------------------------------------------------------------------- /src/fe-text/xep/text-composing.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include "module.h" 21 | #include "module-formats.h" 22 | #include "signals.h" 23 | #include "statusbar-item.h" 24 | #include "window-items.h" 25 | 26 | #include "xmpp-servers.h" 27 | #include "xmpp-queries.h" 28 | 29 | static void 30 | item_xmpp_composing(struct SBAR_ITEM_REC *item, int get_size_only) 31 | { 32 | XMPP_SERVER_REC *server; 33 | XMPP_QUERY_REC *query; 34 | char *str = NULL; 35 | 36 | server = XMPP_SERVER(active_win->active_server); 37 | if (server == NULL || !IS_XMPP_SERVER(server)) 38 | goto out; 39 | query = XMPP_QUERY(active_win->active); 40 | if (query == NULL) 41 | goto out; 42 | if (query->composing_visible) 43 | str = "{sb composing}"; 44 | 45 | out: 46 | if (str == NULL) { 47 | if (get_size_only) 48 | statusbar_item_set_size(item, 0, 0); 49 | return; 50 | } 51 | statusbar_item_default_handler(item, get_size_only, 52 | str, "", FALSE); 53 | } 54 | 55 | static void 56 | xmpp_composing_update(void) 57 | { 58 | statusbar_items_redraw("xmpp_composing"); 59 | } 60 | 61 | static void 62 | event_message_sent(XMPP_SERVER_REC *server, const char *message, 63 | const char *full_jid, const char *ignore) 64 | { 65 | XMPP_QUERY_REC *query; 66 | 67 | if (!IS_XMPP_SERVER(server)) 68 | return; 69 | query = xmpp_query_find(server, full_jid); 70 | if (query != NULL) 71 | query->composing_visible = FALSE; 72 | xmpp_composing_update(); 73 | } 74 | 75 | void 76 | text_composing_init(void) 77 | { 78 | statusbar_item_register("xmpp_composing", NULL, item_xmpp_composing); 79 | 80 | signal_add("window changed", xmpp_composing_update); 81 | signal_add_last("xmpp composing show", xmpp_composing_update); 82 | signal_add_last("xmpp composing hide", xmpp_composing_update); 83 | signal_add("message private", event_message_sent); 84 | signal_add("message xmpp action", event_message_sent); 85 | } 86 | 87 | void 88 | text_composing_deinit(void) 89 | { 90 | statusbar_item_unregister("xmpp_composing"); 91 | 92 | signal_remove("window changed", xmpp_composing_update); 93 | signal_remove("xmpp composing show", xmpp_composing_update); 94 | signal_remove("xmpp composing hide", xmpp_composing_update); 95 | signal_remove("message private", event_message_sent); 96 | signal_remove("message xmpp action", event_message_sent); 97 | } 98 | -------------------------------------------------------------------------------- /src/fe-text/xep/text-composing.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEXT_COMPOSING_H 2 | #define __TEXT_COMPOSING_H 3 | 4 | __BEGIN_DECLS 5 | void text_composing_init(void); 6 | void text_composing_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-text/xep/text-muc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | #include "settings.h" 20 | #include "signals.h" 21 | #include "statusbar-item.h" 22 | #include "window-items.h" 23 | 24 | #include "xmpp-servers.h" 25 | #include "xep/muc.h" 26 | 27 | static void 28 | update_nick_statusbar(XMPP_SERVER_REC *server, MUC_REC *channel, 29 | gboolean redraw) 30 | { 31 | char *newnick; 32 | 33 | newnick = (channel != NULL && IS_MUC(channel)) ? channel->nick 34 | : (settings_get_bool("xmpp_set_nick_as_username") ? 35 | server->user : server->jid); 36 | if (newnick == NULL) 37 | return; 38 | if (strcmp(server->nick, newnick) == 0) 39 | return; 40 | g_free(server->nick); 41 | server->nick = g_strdup(newnick); 42 | if (redraw) 43 | statusbar_items_redraw("user"); 44 | } 45 | 46 | static void 47 | sig_window_changed(WINDOW_REC *window, WINDOW_REC *oldwindow) 48 | { 49 | XMPP_SERVER_REC *server; 50 | 51 | g_return_if_fail(window != NULL); 52 | if ((server = XMPP_SERVER(window->active_server)) == NULL) 53 | return; 54 | update_nick_statusbar(server, MUC(window->active), FALSE); 55 | } 56 | 57 | static void 58 | sig_window_destroyed(WINDOW_REC *window) 59 | { 60 | XMPP_SERVER_REC *server; 61 | MUC_REC *channel; 62 | 63 | g_return_if_fail(window != NULL); 64 | if ((server = XMPP_SERVER(window->active_server)) == NULL) 65 | return; 66 | channel = MUC(window->active); 67 | if (channel != NULL || !IS_MUC(active_win->active)) 68 | update_nick_statusbar(server, NULL, TRUE); 69 | } 70 | 71 | static void 72 | sig_nick_changed(MUC_REC *channel) 73 | { 74 | g_return_if_fail(channel != NULL); 75 | 76 | if (!IS_MUC(channel)) 77 | return; 78 | if (MUC(active_win->active) == channel) 79 | update_nick_statusbar(channel->server, channel, TRUE); 80 | } 81 | 82 | static void 83 | sig_channel_joined(MUC_REC *channel) 84 | { 85 | g_return_if_fail(channel != NULL); 86 | 87 | if (!IS_MUC(channel)) 88 | return; 89 | if (MUC(active_win->active) == channel) 90 | update_nick_statusbar(channel->server, channel, TRUE); 91 | } 92 | 93 | static void 94 | sig_channel_destroyed(MUC_REC *channel) 95 | { 96 | g_return_if_fail(channel != NULL); 97 | 98 | if (!IS_MUC(channel)) 99 | return; 100 | if (MUC(active_win->active) == channel) 101 | update_nick_statusbar(channel->server, NULL, TRUE); 102 | } 103 | 104 | void 105 | text_muc_init(void) 106 | { 107 | signal_add("window changed", sig_window_changed); 108 | signal_add("window destroyed", sig_window_destroyed); 109 | signal_add("message xmpp channel own_nick", sig_nick_changed); 110 | signal_add("channel joined", sig_channel_joined); 111 | signal_add("channel destroyed", sig_channel_destroyed); 112 | } 113 | 114 | void 115 | text_muc_deinit(void) 116 | { 117 | signal_remove("window changed", sig_window_changed); 118 | signal_remove("window destroyed", sig_window_destroyed); 119 | signal_remove("message xmpp channel own_nick", sig_nick_changed); 120 | signal_remove("channel joined", sig_channel_joined); 121 | signal_remove("channel destroyed", sig_channel_destroyed); 122 | } 123 | -------------------------------------------------------------------------------- /src/fe-text/xep/text-muc.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEXT_MUC_H 2 | #define __TEXT_MUC_H 3 | 4 | __BEGIN_DECLS 5 | void text_muc_init(void); 6 | void text_muc_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/fe-text/xep/text-xep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 Colin DIDIER 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "module.h" 19 | 20 | #include "text-composing.h" 21 | #include "text-muc.h" 22 | 23 | void 24 | text_xep_init(void) 25 | { 26 | text_composing_init(); 27 | text_muc_init(); 28 | } 29 | 30 | void 31 | text_xep_deinit(void) 32 | { 33 | text_composing_deinit(); 34 | text_muc_deinit(); 35 | } 36 | -------------------------------------------------------------------------------- /src/fe-text/xep/text-xep.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEXT_XEP_H 2 | #define __TEXT_XEP_H 3 | 4 | __BEGIN_DECLS 5 | void text_xep_init(void); 6 | void text_xep_deinit(void); 7 | __END_DECLS 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/rules.mk: -------------------------------------------------------------------------------- 1 | include ../../config.mk 2 | 3 | OBJS = ${SRCS:.c=.o} 4 | 5 | LIBSO=lib${LIB}.so 6 | 7 | all: ${LIBSO} 8 | 9 | .c.o: 10 | ${CC} ${CPPFLAGS} ${CFLAGS} ${INCS} -o $@ -c $< 11 | 12 | ${LIBSO}: ${OBJS} 13 | ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LIBS} 14 | 15 | clean: 16 | rm -f ${LIBSO} ${OBJS} 17 | 18 | install: all 19 | @echo installing the module ${LIBSO} to ${DESTDIR}${IRSSI_LIB}/modules 20 | install -d ${DESTDIR}${IRSSI_LIB}/modules 21 | install ${LIBSO} ${DESTDIR}${IRSSI_LIB}/modules 22 | 23 | uninstall: 24 | @echo deinstalling the module ${LIBSO} from ${DESTDIR}${IRSSI_LIB}/modules 25 | rm -f ${DESTDIR}${IRSSI_LIB}/modules/${LIBSO} 26 | 27 | user-install: 28 | env DESTDIR= IRSSI_LIB=~/.irssi ${MAKE} install 29 | 30 | user-uninstall: 31 | env DESTDIR= IRSSI_LIB=~/.irssi ${MAKE} uninstall 32 | 33 | .PHONY: clean install uninstall user-install user-uninstall 34 | --------------------------------------------------------------------------------