1 /*
2  * nmuser.h
3  *
4  * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA	02111-1301	USA
18  *
19  */
20 
21 #ifndef __NM_USER_H__
22 #define __NM_USER_H__
23 
24 #include <glib.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 typedef guint32 NMERR_T;
29 typedef int NMSTATUS_T;
30 
31 typedef struct _NMUser NMUser;
32 
33 typedef enum
34 {
35 	NMREQUEST_TYPE_LOGIN = 0,
36 	NMREQUEST_TYPE_LOGOUT,
37 	NMREQUEST_TYPE_SETSTATUS,
38 	NMREQUEST_TYPE_GETDETAILS,
39 	NMREQUEST_TYPE_CREATECONF,
40 	NMREQUEST_TYPE_SENDMESSAGE,
41 	NMREQUEST_TYPE_JOINCONF,
42 	NMREQUEST_TYPE_LEAVECONF,
43 	NMREQUEST_TYPE_REJECTCONF,
44 	NMREQUEST_TYPE_SENDTYPING,
45 	NMREQUEST_TYPE_CREATECONTACT,
46 	NMREQUEST_TYPE_DELETECONTACT
47 
48 } NMRequestType;
49 
50 #include "debug.h"
51 #include "nmmessage.h"
52 #include "nmconference.h"
53 #include "nmcontact.h"
54 #include "nmuserrecord.h"
55 #include "nmfield.h"
56 #include "nmevent.h"
57 
58 /* Callback typedefs */
59 typedef void (*nm_response_cb) (NMUser * user, NMERR_T ret_code,
60 								gpointer resp_data, gpointer user_data);
61 
62 typedef void (*nm_event_cb) (NMUser * user, NMEvent * event);
63 
64 #include "nmrequest.h"
65 #include "nmconn.h"
66 
67 /* This represents user that we are currently logged in as */
68 struct _NMUser
69 {
70 
71 	char *name;
72 
73 	NMSTATUS_T status;
74 
75 	/* A copy of the login response fields */
76 	NMField *fields;
77 
78 	/* The user record for this user */
79 	NMUserRecord *user_record;
80 
81 	/* Our connection information */
82 	NMConn *conn;
83 
84 	/* Our public IP address */
85 	char *address;
86 
87 	/* This is the contact list */
88 	NMFolder *root_folder;
89 
90 	/* All contacts that we know about hashed by dn */
91 	GHashTable *contacts;
92 
93 	/* All user records hashed by dn */
94 	GHashTable *user_records;
95 
96 	/* DN lookup */
97 	GHashTable *display_id_to_dn;
98 
99 	/* One on one conversations indexed by recipient's dn */
100 	GSList *conferences;
101 
102 	guint32 conference_count;
103 
104 	/* Called when we receive an event */
105 	nm_event_cb evt_callback;
106 
107 	/* Privacy settings */
108 	gboolean privacy_locked;
109 	gboolean default_deny;
110 	GSList *allow_list;
111 	GSList *deny_list;
112 
113 	/* Pending requests. If we need to go to the server to more info
114 	 * before processing a request we will queue it up and process when
115 	 * we get a response
116 	 */
117 	GSList *pending_requests;
118 
119 	/* Pending events. Same as above except for events. */
120 	GSList *pending_events;
121 
122 	/* Generic pointer to data needed by the client
123 	 * using the API
124 	 */
125 	gpointer client_data;
126 
127 	/* Have the privacy lists been synched yet */
128 	gboolean privacy_synched;
129 
130 	/* Has the contact list been synched */
131 	gboolean clist_synched;
132 };
133 
134 #define	NM_STATUS_UNKNOWN			0
135 #define	NM_STATUS_OFFLINE			1
136 #define NM_STATUS_AVAILABLE			2
137 #define	NM_STATUS_BUSY				3
138 #define	NM_STATUS_AWAY				4
139 #define	NM_STATUS_AWAY_IDLE			5
140 #define	NM_STATUS_INVALID			6
141 
142 #define NMERR_BASE							0x2000L
143 #define NM_OK								0L
144 #define NMERR_BAD_PARM						(NMERR_BASE + 0x0001)
145 #define NMERR_TCP_WRITE						(NMERR_BASE + 0x0002)
146 #define NMERR_TCP_READ						(NMERR_BASE + 0x0003)
147 #define NMERR_PROTOCOL						(NMERR_BASE + 0x0004)
148 #define NMERR_SERVER_REDIRECT				(NMERR_BASE + 0x0005)
149 #define NMERR_CONFERENCE_NOT_FOUND 			(NMERR_BASE + 0x0006)
150 #define NMERR_CONFERENCE_NOT_INSTANTIATED 	(NMERR_BASE + 0x0007)
151 #define NMERR_FOLDER_EXISTS					(NMERR_BASE + 0x0008)
152 
153 /* Errors that are returned from the server */
154 #define NMERR_SERVER_BASE			 	0xD100L
155 #define NMERR_ACCESS_DENIED			 	(NMERR_SERVER_BASE + 0x0006)
156 #define NMERR_NOT_SUPPORTED          	(NMERR_SERVER_BASE + 0x000A)
157 #define NMERR_PASSWORD_EXPIRED       	(NMERR_SERVER_BASE + 0x000B)
158 #define NMERR_PASSWORD_INVALID       	(NMERR_SERVER_BASE + 0x000C)
159 #define NMERR_USER_NOT_FOUND         	(NMERR_SERVER_BASE + 0x000D)
160 #define NMERR_USER_DISABLED          	(NMERR_SERVER_BASE + 0x0010)
161 #define NMERR_DIRECTORY_FAILURE      	(NMERR_SERVER_BASE + 0x0011)
162 #define NMERR_HOST_NOT_FOUND		 	(NMERR_SERVER_BASE + 0x0019)
163 #define NMERR_ADMIN_LOCKED           	(NMERR_SERVER_BASE + 0x001C)
164 #define NMERR_DUPLICATE_PARTICIPANT  	(NMERR_SERVER_BASE + 0x001F)
165 #define NMERR_SERVER_BUSY            	(NMERR_SERVER_BASE + 0x0023)
166 #define NMERR_OBJECT_NOT_FOUND       	(NMERR_SERVER_BASE + 0x0024)
167 #define NMERR_DIRECTORY_UPDATE       	(NMERR_SERVER_BASE + 0x0025)
168 #define NMERR_DUPLICATE_FOLDER       	(NMERR_SERVER_BASE + 0x0026)
169 #define NMERR_DUPLICATE_CONTACT      	(NMERR_SERVER_BASE + 0x0027)
170 #define NMERR_USER_NOT_ALLOWED       	(NMERR_SERVER_BASE + 0x0028)
171 #define NMERR_TOO_MANY_CONTACTS      	(NMERR_SERVER_BASE + 0x0029)
172 #define NMERR_CONFERENCE_NOT_FOUND_2   	(NMERR_SERVER_BASE + 0x002B)
173 #define NMERR_TOO_MANY_FOLDERS       	(NMERR_SERVER_BASE + 0x002C)
174 #define NMERR_SERVER_PROTOCOL        	(NMERR_SERVER_BASE + 0x0030)
175 #define NMERR_CONVERSATION_INVITE		(NMERR_SERVER_BASE + 0x0035)
176 #define NMERR_USER_BLOCKED	         	(NMERR_SERVER_BASE + 0x0039)
177 #define NMERR_MASTER_ARCHIVE_MISSING 	(NMERR_SERVER_BASE + 0x003A)
178 #define NMERR_PASSWORD_EXPIRED_2     	(NMERR_SERVER_BASE + 0x0042)
179 #define NMERR_CREDENTIALS_MISSING   	(NMERR_SERVER_BASE + 0x0046)
180 #define NMERR_AUTHENTICATION_FAILED		(NMERR_SERVER_BASE + 0x0049)
181 #define NMERR_EVAL_CONNECTION_LIMIT		(NMERR_SERVER_BASE + 0x004A)
182 
183 /**
184  *	Initialize the user that we are going to login to the system as.
185  *
186  *	@param	name			The userid of the user
187  *	@param	server			IP Address of server
188  *	@param	port			Port to connect to on the server
189  *  @param 	data			Client data to associate with the user
190  *	@param	event_callback	Function to call when we receive an event
191  *
192  *	@return The initialized user object. Must be freed by calling
193  *			nm_deinitialize_user
194  */
195 NMUser *nm_initialize_user(const char *name, const char *server, int port,
196 						   gpointer data, nm_event_cb event_callback);
197 
198 
199 /**
200  *	Free up resources associated with the user object.
201  *
202  *  @param	user	The user to deinitialize
203  */
204 void nm_deinitialize_user(NMUser * user);
205 
206 /**
207  *	Send a login request to the server.
208  *
209  *	The response data sent to the callback will be NULL.
210  *
211  *  @param	user		The User to login -- must be initialized
212  *	@param	pwd			The password of the user
213  *  @param  my_addr		The address of the client machine
214  *  @param	user_agent	String describing the client (eg. "Purple/0.76 (Linux; 2.4.20)")
215  *	@param	callback	Function to call when we get the response from the server
216  *  @param 	data		User defined data to be passed to the callback function
217  *
218  *
219  *	@return	NM_OK if login is sent successfully, error otherwise.
220  */
221 NMERR_T nm_send_login(NMUser * user, const char *pwd, const char *my_addr,
222 					  const char *user_agent, nm_response_cb callback,
223 					  gpointer data);
224 
225 /**
226  *	Send a set status request to the server.
227  *
228  *	The response data sent to the callback will be NULL.
229  *
230  *  @param	user		The logged in User
231  *	@param	dn			The DN of the user (if known, or NULL if not known)
232  *	@param	address		IP Address of server
233  *	@param	callback	Function to call when we get the response from the server
234  *
235  *
236  *	@return	NM_OK if successfully sent, error otherwise
237  */
238 NMERR_T nm_send_set_status(NMUser * user, int status, const char *text,
239 						   const char *auto_resp, nm_response_cb callback,
240 						   gpointer data);
241 
242 /**
243  *	Send a create conference to the server.
244  *
245  *	The response data sent to the callback will be NULL.
246  *
247  *  @param	user			 The logged in User
248  *	@param	conference		 Conference to create
249  *	@param	add_participants Add participant list on create?
250  *	@param	callback		 Function to call when we get the response from the server
251  *	@param	data			 User defined data to be passed to the callback function
252  *
253  *	@return	NM_OK if successfully sent, error otherwise
254  */
255 NMERR_T nm_send_create_conference(NMUser * user, NMConference * conference,
256 								  nm_response_cb callback, gpointer data);
257 
258 /**
259  *	Tell server we have left the conference.
260  *
261  *	The response data sent to the callback will be NULL.
262  *
263  *  @param	user		The logged in User
264  *	@param	conference	Conference the user is leaving
265  *	@param	callback	Function to call when we get the response from the server
266  *	@param	data		User defined data to be passed to the callback function
267  *
268  *	@return	NM_OK if successfully sent, error otherwise
269  */
270 NMERR_T nm_send_leave_conference(NMUser * user, NMConference * conference,
271 								 nm_response_cb callback, gpointer data);
272 
273 /**
274  *	Send a join conference request to the server.
275  *
276  *	The response data sent to the callback will be NULL.
277  *
278  *  @param	user		The logged in User
279  *	@param	conference	Conference the user is joining
280  *	@param	callback	Function to call when we get the response from the server
281  *	@param	data		User defined data to be passed to the callback function
282  *
283  *
284  *	@return	NM_OK if successfully sent, error otherwise
285  */
286 NMERR_T nm_send_join_conference(NMUser * user, NMConference * conference,
287 								nm_response_cb callback, gpointer data);
288 
289 /**
290  *	Send a conference reject request to the server.
291  *
292  *	The response data sent to the callback will be NULL.
293  *
294  *  @param	user		The logged in User
295  *	@param	conference	Conference the user is rejecting
296  *	@param	callback	Function to call when we get the response from the server
297  *	@param	data		User defined data to be passed to the callback function
298  *
299  *
300  *	@return	NM_OK if successfully sent, error otherwise
301  */
302 NMERR_T nm_send_reject_conference(NMUser * user, NMConference * conference,
303 								  nm_response_cb callback, gpointer data);
304 
305 
306 /**
307  *	Send a conference invitation to the server.
308  *
309  *	The response data sent to the callback will be NULL.
310  *
311  *  @param	user		The logged in User
312  *	@param	conference	Conference the user is rejecting
313  *  @param  user_record The user to invite
314  *  @param  message		The invite message if there is one, NULL otherwise
315  *	@param	callback	Function to call when we get the response from the server
316  *	@param	data		User defined data to be passed to the callback function
317  *
318  *
319  *	@return	NM_OK if successfully sent, error otherwise
320  */
321 NMERR_T nm_send_conference_invite(NMUser *user, NMConference *conference, NMUserRecord *user_record,
322 								  const char *message, nm_response_cb callback, gpointer data);
323 
324 /**
325  *	Get details for a more than one user from the server.
326  *
327  *	The response data sent to the callback will be an NMUserRecord which should be
328  *  freed with nm_release_user_record
329  *
330  *  @param	user		The logged in User
331  *	@param	names		Link list of user id's or dn's
332  *	@param	callback	Function to call when we get the response from the server
333  *	@param	data		User defined data to be passed to the callback function
334  *
335  *	@return	NM_OK if successfully sent, error otherwise
336  */
337 NMERR_T nm_send_multiple_get_details(NMUser * user, GSList *names,
338 									 nm_response_cb callback, gpointer data);
339 
340 /**
341  *	Get details for a user from the server.
342  *
343  *	The response data sent to the callback will be an NMUserRecord which should be
344  *  freed with nm_release_user_record
345  *
346  *  @param	user		The logged in User
347  *	@param	name		Userid or DN of the user to look up
348  *	@param	callback	Function to call when we get the response from the server
349  *	@param	data		User defined data to be passed to the callback function
350  *
351  *	@return	NM_OK if successfully sent, error otherwise
352  */
353 NMERR_T nm_send_get_details(NMUser * user, const char *name,
354 							nm_response_cb callback, gpointer data);
355 
356 /**
357  *	Send a message.
358  *
359  *  The response data sent to the callback will be NULL.
360  *
361  *  @param	user		The logged in User
362  *	@param	message		The message to send.
363  *	@param	callback	Function to call when we get the response from the server
364  *
365  *	@return	NM_OK if successfully sent, error otherwise
366  */
367 NMERR_T nm_send_message(NMUser * user, NMMessage * message,
368 						nm_response_cb callback);
369 
370 /**
371  *	Sends a typing event to the server.
372  *
373  *  The response data sent to the callback will be NULL.
374  *
375  *  @param	user		The logged in User
376  *	@param	conf		The conference that corresponds to the typing event
377  *	@param	typing		TRUE if the user is typing
378  *						FALSE if the user has stopped typing
379  *	@param	callback	Function to call when we get the response from the server
380  *
381  *	@return	NM_OK if successfully sent, error otherwise
382  */
383 NMERR_T nm_send_typing(NMUser * user, NMConference * conf,
384 					   gboolean typing, nm_response_cb callback);
385 
386 /**
387  *	Send a create contact request to the server.
388  *
389  *  The given folder should already exist on the server. If not,
390  *  the call will fail.
391  *
392  *  The response data sent to the callback will be a NMContact which should
393  *  be released with nm_release_contact
394  *
395  *  @param	user		The logged in User
396  *	@param	folder		The folder that the contact should be created in
397  *	@param	contact		The contact to add
398  *	@param	callback	Function to call when we get the response from the server
399  *	@param	data		User defined data
400  *
401  *	@return	NM_OK if successfully sent, error otherwise
402  */
403 NMERR_T nm_send_create_contact(NMUser * user, NMFolder * folder,
404 							   NMContact * contact, nm_response_cb callback,
405 							   gpointer data);
406 
407 /**
408  *	Send a remove contact request to the server.
409  *
410  *  The response data sent to the callback will be NULL.
411  *
412  *  @param	user		The logged in User
413  *	@param	folder		The folder to remove contact from
414  *	@param	contact		The contact to remove
415  *	@param	callback	Function to call when we get the response from the server
416  *  @param	data		User defined data
417  *
418  *	@return	NM_OK if successfully sent, error otherwise
419  */
420 NMERR_T nm_send_remove_contact(NMUser * user, NMFolder * folder,
421 							   NMContact * contact, nm_response_cb callback,
422 							   gpointer data);
423 
424 /**
425  *	Send a create folder request to the server.
426  *
427  *  The response data sent to the callback will be a NMFolder which should be
428  *  released with nm_release_folder
429  *
430  *  @param	user		The logged in User
431  *	@param	name		The name of the folder to create
432  *	@param	callback	Function to call when we get the response from the server
433  *  @param	data		User defined data
434  *
435  *	@return	NM_OK if successfully sent, error otherwise
436  */
437 NMERR_T nm_send_create_folder(NMUser * user, const char *name,
438 							  nm_response_cb callback, gpointer data);
439 
440 /**
441  *	Send a delete folder request to the server.
442  *
443  *  The response data sent to the callback will be NULL.
444  *
445  *  @param	user		The logged in User
446  *	@param	folder		The name of the folder to remove
447  *	@param	callback	Function to call when we get the response from the server
448  *  @param	data		User defined data
449  *
450  *	@return	NM_OK if successfully sent, error otherwise
451  */
452 NMERR_T nm_send_remove_folder(NMUser * user, NMFolder * folder,
453 							  nm_response_cb callback, gpointer data);
454 
455 /**
456  *	Send a rename contact request to the server.
457  *
458  *	The response data sent to the callback will be NULL.
459  *
460  *  @param	user		The logged in User
461  *	@param	contact		The contact to rename
462  *  @param	new_name	The new display name for the contact
463  *	@param	callback	Function to call when we get the response from the server
464  *  @param	data		User defined data
465  *
466  *	@return	NM_OK if successfully sent, error otherwise
467  */
468 NMERR_T nm_send_rename_contact(NMUser * user, NMContact * contact,
469 							   const char *new_name, nm_response_cb callback,
470 							   gpointer data);
471 
472 /**
473  *	Send a rename folder request to the server.
474  *
475  *	The response data sent to the callback will be NULL.
476  *
477  *  @param	user		The logged in User
478  *	@param	folder		The folder to rename
479  *  @param	new_name	The new name of the folder
480  *	@param	callback	Function to call when we get the response from the server
481  *  @param	data		User defined data
482  *
483  *	@return	NM_OK if successfully sent, error otherwise
484  */
485 NMERR_T nm_send_rename_folder(NMUser * user, NMFolder * folder,
486 							  const char *new_name, nm_response_cb callback,
487 							  gpointer data);
488 
489 /**
490  *	Send a move contact request to the server.
491  *
492  *	The response data sent to the callback will be NULL.
493  *
494  *  @param	user		The logged in User
495  *	@param	contact		The contact to move
496  *  @param	folder	    The folder to move the contact to
497  *	@param	callback	Function to call when we get the response from the server
498  *  @param	data		User defined data
499  *
500  *	@return	NM_OK if successfully sent, error otherwise
501  */
502 NMERR_T nm_send_move_contact(NMUser * user, NMContact * contact,
503 							 NMFolder * folder, nm_response_cb callback,
504 							 gpointer data);
505 
506 /**
507  *	Send a get status request to the server.
508  *
509  * 	The response data sent to the callback will be a NMUserRecord.
510  *
511  *  @param	user		The logged in User
512  *	@param	contact		The contact to move
513  *  @param	folder	    The folder to move the contact to
514  *	@param	callback	Function to call when we get the response from the server
515  *  @param	data		User defined data
516  *
517  *	@return	NM_OK if successfully sent, error otherwise
518  */
519 NMERR_T nm_send_get_status(NMUser * user, NMUserRecord * user_record,
520 						   nm_response_cb callback, gpointer data);
521 
522 /**
523  *	Send a request to add an item to the allow or deny list.
524  *
525  *  @param	user		The logged in User
526  *	@param	who			The userid or DN of the user to add to list
527  *  @param	allow_list	TRUE if adding to allow list, FALSE if adding to deny list
528  *	@param	callback	Function to call when we get the response from the server
529  *  @param	data		User defined data
530  *
531  *	@return	NM_OK if successfully sent, error otherwise
532  */
533 NMERR_T
534 nm_send_create_privacy_item(NMUser *user, const char *who, gboolean is_allowed,
535 							nm_response_cb callback, gpointer data);
536 
537 /**
538  *	Send a request to remove an item from the allow or deny list.
539  *
540  *  @param	user		The logged in User
541  *	@param	who			The userid or DN of the user to add to list
542  *  @param	allow_list	TRUE if removing from allow list, FALSE if removing from deny list
543  *	@param	callback	Function to call when we get the response from the server
544  *  @param	data		User defined data
545  *
546  *	@return	NM_OK if successfully sent, error otherwise
547  */
548 NMERR_T
549 nm_send_remove_privacy_item(NMUser *user, const char *dn, gboolean allow_list,
550 							nm_response_cb callback, gpointer data);
551 
552 /**
553  *	Send a request to change the default privacy setting to deny all or allow all
554  *
555  *  @param	user			The logged in User
556  *	@param	default_deny	TRUE if default should be changed to deny all
557  *	@param	callback		Function to call when we get the response from the server
558  *  @param	data			User defined data
559  *
560  *	@return	NM_OK if successfully sent, error otherwise
561  */
562 NMERR_T
563 nm_send_set_privacy_default(NMUser *user, gboolean default_deny,
564 							nm_response_cb callback, gpointer data);
565 
566 /**
567  *	Send a ping to the server
568  *
569  *  @param	user			The logged in User
570  *	@param	callback		Function to call when we get the response from the server
571  *  @param	data			User defined data
572  *
573  *	@return	NM_OK if successfully sent, error otherwise
574  */
575 NMERR_T
576 nm_send_keepalive(NMUser *user, nm_response_cb callback, gpointer data);
577 
578 /**
579  *	Reads a response/event from the server and processes it.
580  *
581  *  @param	user	The logged in User
582  */
583 NMERR_T nm_process_new_data(NMUser * user);
584 
585 /**
586  *	Return the root folder of the contact list
587  *
588  *  @param	user	The logged in User
589  *
590  *	@return	Root folder
591  */
592 NMFolder *nm_get_root_folder(NMUser * user);
593 
594 /**
595  *	Create the contact list based on the login fields
596  *
597  *  @param	user	The logged in User
598  *
599  */
600 NMERR_T nm_create_contact_list(NMUser * user);
601 
602 void nm_destroy_contact_list(NMUser * user);
603 
604 void nm_user_add_contact(NMUser * user, NMContact * contact);
605 
606 void nm_user_add_user_record(NMUser * user, NMUserRecord * user_record);
607 
608 NMContact *nm_find_contact(NMUser * user, const char *dn);
609 
610 GList *nm_find_contacts(NMUser * user, const char *dn);
611 
612 NMUserRecord *nm_find_user_record(NMUser * user, const char *dn);
613 
614 NMFolder *nm_find_folder(NMUser * user, const char *name);
615 
616 NMFolder *nm_find_folder_by_id(NMUser * user, int object_id);
617 
618 NMConference *nm_find_conversation(NMUser * user, const char *who);
619 
620 void nm_conference_list_add(NMUser * user, NMConference * conf);
621 
622 void nm_conference_list_remove(NMUser * user, NMConference * conf);
623 
624 void nm_conference_list_free(NMUser * user);
625 
626 NMConference *nm_conference_list_find(NMUser * user, const char *guid);
627 
628 const char *nm_lookup_dn(NMUser * user, const char *display_id);
629 
630 nm_event_cb nm_user_get_event_callback(NMUser * user);
631 
632 NMConn *nm_user_get_conn(NMUser * user);
633 
634 gboolean nm_user_is_privacy_locked(NMUser *user);
635 
636 /** Some utility functions **/
637 
638 /**
639  * Check to see if the conference GUIDs are equivalent.
640  *
641  * @param guid1	First guid to compare
642  * @param guid2 Second guid to compare
643  *
644  * @return 		TRUE if conference GUIDs are equivalent, FALSE otherwise.
645  *
646  */
647 gboolean nm_are_guids_equal(const char *guid1, const char *guid2);
648 
649 /**
650  * Compare UTF8 strings for equality only (case insensitive)
651  *
652  * @param guid1	First string to compare
653  * @param guid2 Second string to compare
654  *
655  * @return 		TRUE if strings are equal, FALSE otherwise
656  *
657  */
658 gboolean nm_utf8_str_equal(gconstpointer str1, gconstpointer str2);
659 
660 /**
661  * Convert a fully typed LDAP DN to dotted, untype notation
662  * e.g. cn=mike,o=novell -> mike.novell
663  *
664  * @param typed	Fully typed dn
665  *
666  * @return 		Dotted equivalent of typed (must be freed).
667  *
668  */
669 char *nm_typed_to_dotted(const char *typed);
670 
671 /**
672  *      Return a string representation of the error code.
673  *
674  *      @param  error           NMERR_T to convert to string
675  *
676  *      @return String representation.
677  */
678 const char *nm_error_to_string (NMERR_T err);
679 
680 #endif
681