├── .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 |
--------------------------------------------------------------------------------