aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ini.c
blob: aa291bb272ce8f02cb64cc4cc51ed5b0a675c47c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  /********************************************************************\
  * BitlBee -- An IRC to other IM-networks gateway                     *
  *                                                                    *
  * Copyright 2002-2008 Wilmer van der Gaast and others                *
  \********************************************************************/

/* INI file reading code						*/

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License with
  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  Suite 330, Boston, MA  02111-1307  USA
*/
#define BITLBEE_CORE
#include "bitlbee.h"

ini_t *ini_open( char *file )
{
	int fd;
	ini_t *ini = NULL;
	struct stat fi;
	
	if( ( fd = open( file, O_RDONLY ) ) != -1 &&
	    fstat( fd, &fi ) == 0 &&
	    fi.st_size <= 16384 &&
	    ( ini = g_malloc( sizeof( ini_t ) + fi.st_size + 1 ) ) &&
	    read( fd, ini->file, fi.st_size ) == fi.st_size )
	{
		memset( ini, 0, sizeof( ini_t ) );
		ini->size = fi.st_size;
		ini->file[ini->size] = 0;
		ini->cur = ini->file;
		ini->c_section = "";
		
		close( fd );
		
		return ini;
	}

	if( fd >= 0 )
		close( fd );
	
	ini_close( ini );

	return NULL;
}

/* Strips leading and trailing whitespace and returns a pointer to the first
   non-ws character of the given string. */
static char *ini_strip_whitespace( char *in )
{
	char *e;

	while( isspace( *in ) )
		in++;

	e = in + strlen( in ) - 1;
	while( e > in && isspace( *e ) )
		e--;
	e[1] = 0;
	
	return in;
}

int ini_read( ini_t *file )
{
	char *s;
	
	while( file->cur && file->cur < file->file + file->size )
	{
		char *e, *next;
		
		file->line++;

		/* Find the end of line */
		if( ( e = strchr( file->cur, '\n' ) ) != NULL )
		{
			*e = 0;
			next = e + 1;
		}
		else
		{
			/* No more lines. */
			e = file->cur + strlen( file->cur );
			next = NULL;
		}
		
		/* Comment? */
		if( ( s = strchr( file->cur, '#' ) ) != NULL )
			*s = 0;
		
		file->cur = ini_strip_whitespace( file->cur );
		
		if( *file->cur == '[' )
		{
			file->cur++;
			if( ( s = strchr( file->cur, ']' ) ) != NULL )
			{
				*s = 0;
				file->c_section = file->cur;
			}
		}
		else if( ( s = strchr( file->cur, '=' ) ) != NULL )
		{
			*s = 0;
			file->key = ini_strip_whitespace( file->cur );
			file->value = ini_strip_whitespace( s + 1 );
			
			if( ( s = strchr( file->key, '.' ) ) != NULL )
			{
				*s = 0;
				file->section = file->key;
				file->key = s + 1;
			}
			else
			{
				file->section = file->c_section;
			}
			
			file->cur = next;
			return 1;
		}
		/* else: noise/comment/etc, let's just ignore it. */

		file->cur = next;
	}
	
	return 0;
}

void ini_close( ini_t *file )
{
	g_free( file );
}
8 *aimbs_getraw(aim_bstream_t *bs, int len); char *aimbs_getstr(aim_bstream_t *bs, int len); int aimbs_putraw(aim_bstream_t *bs, const guint8 *v, int len); int aimbs_putbs(aim_bstream_t *bs, aim_bstream_t *srcbs, int len); int aim_get_command_rendezvous(aim_session_t *sess, aim_conn_t *conn); int aim_tx_sendframe(aim_session_t *sess, aim_frame_t *cur); flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *); aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, guint8 framing, guint8 chan, int datalen); void aim_frame_destroy(aim_frame_t *); int aim_tx_enqueue(aim_session_t *, aim_frame_t *); int aim_tx_printqueue(aim_session_t *); void aim_tx_cleanqueue(aim_session_t *, aim_conn_t *); aim_rxcallback_t aim_callhandler(aim_session_t *sess, aim_conn_t *conn, u_short family, u_short type); /* * Generic SNAC structure. Rarely if ever used. */ typedef struct aim_snac_s { aim_snacid_t id; guint16 family; guint16 type; guint16 flags; void *data; time_t issuetime; struct aim_snac_s *next; } aim_snac_t; void aim_initsnachash(aim_session_t *sess); aim_snacid_t aim_cachesnac(aim_session_t *sess, const guint16 family, const guint16 type, const guint16 flags, const void *data, const int datalen); aim_snac_t *aim_remsnac(aim_session_t *, aim_snacid_t id); void aim_cleansnacs(aim_session_t *, int maxage); int aim_putsnac(aim_bstream_t *, guint16 family, guint16 type, guint16 flags, aim_snacid_t id); aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src); void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src); int aim_oft_buildheader(unsigned char *,struct aim_fileheader_t *); int aim_parse_unknown(aim_session_t *, aim_frame_t *, ...); /* Stored in ->priv of the service request SNAC for chats. */ struct chatsnacinfo { guint16 exchange; char name[128]; guint16 instance; }; /* these are used by aim_*_clientready */ #define AIM_TOOL_JAVA 0x0001 #define AIM_TOOL_MAC 0x0002 #define AIM_TOOL_WIN16 0x0003 #define AIM_TOOL_WIN32 0x0004 #define AIM_TOOL_MAC68K 0x0005 #define AIM_TOOL_MACPPC 0x0006 #define AIM_TOOL_NEWWIN 0x0010 struct aim_tool_version { guint16 group; guint16 version; guint16 tool; guint16 toolversion; }; /* * In SNACland, the terms 'family' and 'group' are synonymous -- the former * is my term, the latter is AOL's. */ struct snacgroup { guint16 group; struct snacgroup *next; }; struct snacpair { guint16 group; guint16 subtype; struct snacpair *next; }; struct rateclass { guint16 classid; guint32 windowsize; guint32 clear; guint32 alert; guint32 limit; guint32 disconnect; guint32 current; guint32 max; guint8 unknown[5]; /* only present in versions >= 3 */ struct snacpair *members; struct rateclass *next; }; /* * This is inside every connection. But it is a void * to anything * outside of libfaim. It should remain that way. It's called data * abstraction. Maybe you've heard of it. (Probably not if you're a * libfaim user.) * */ typedef struct aim_conn_inside_s { struct snacgroup *groups; struct rateclass *rates; } aim_conn_inside_t; void aim_conn_addgroup(aim_conn_t *conn, guint16 group); guint32 aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len); int aim_putcap(aim_bstream_t *bs, guint32 caps); int aim_cachecookie(aim_session_t *sess, aim_msgcookie_t *cookie); aim_msgcookie_t *aim_uncachecookie(aim_session_t *sess, guint8 *cookie, int type); aim_msgcookie_t *aim_mkcookie(guint8 *, int, void *); aim_msgcookie_t *aim_checkcookie(aim_session_t *sess, const unsigned char *, const int); int aim_freecookie(aim_session_t *sess, aim_msgcookie_t *cookie); int aim_cookie_free(aim_session_t *sess, aim_msgcookie_t *cookie); int aim_extractuserinfo(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *); int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info); int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo); int aim_request_directim(aim_session_t *sess, const char *destsn, guint8 *ip, guint16 port, guint8 *ckret); int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, guint16 numfiles, guint32 totsize, guint8 *ip, guint16 port, guint8 *ckret); void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn); void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn); void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn); /* These are all handled internally now. */ int aim_setversions(aim_session_t *sess, aim_conn_t *conn); int aim_reqrates(aim_session_t *, aim_conn_t *); int aim_rates_addparam(aim_session_t *, aim_conn_t *); int aim_rates_delparam(aim_session_t *, aim_conn_t *); #endif /* __AIM_INTERNAL_H__ */