ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/servtree.C
Revision: 1.2
Committed: Sat Jul 21 01:29:12 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
- moved to new documentation system
- fixed small build error

File Contents

# Content
1 /*
2 * Copyright © 2005-2006 Atheme Development Group
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Services binary tree manipulation. (add_service, del_service, et al.)
6 */
7
8 static char const rcsid[] = "$Id";
9
10 #include "atheme.h"
11
12 dictionary_tree_t *services;
13 static BlockHeap *service_heap;
14
15 service_t *fcmd_agent = NULL;
16
17 static void
18 dummy_handler (sourceinfo_t *si, int parc, char **parv)
19 {
20 }
21
22 void
23 servtree_init (void)
24 {
25 service_heap = BlockHeapCreate (sizeof (service_t), 12);
26 services = dictionary_create ("services", HASH_SMALL, strcasecmp);
27
28 if (!service_heap)
29 {
30 slog (LG_INFO, "servtree_init(): Block allocator failed.");
31 exit (EXIT_FAILURE);
32 }
33 }
34
35 static void
36 me_me_init (void)
37 {
38 if (me.numeric)
39 init_uid ();
40 me.me = server_add (me.name, 0, NULL, me.numeric ? me.numeric : NULL, me.desc);
41 }
42
43 service_t *
44 add_service (char *name, char *user, char *host, char *real, void (*handler) (sourceinfo_t *si, int parc, char *parv[]), cmdvec &cmdtree)
45 {
46 service_t *sptr;
47 user_t *u;
48
49 if (me.me == NULL)
50 me_me_init ();
51
52 if (name == NULL)
53 {
54 slog (LG_INFO, "add_service(): Bad error! We were given a NULL pointer for service name!");
55 return NULL;
56 }
57
58 if ((sptr = find_service (name)))
59 {
60 slog (LG_DEBUG, "add_service(): Service `%s' already exists.", name);
61 return NULL;
62 }
63
64 sptr = static_cast<service_t *> (BlockHeapAlloc (service_heap));
65
66 sptr->name = sstrdup (name);
67 sptr->user = sstrdup (user);
68 sptr->host = sstrdup (host);
69 sptr->real = sstrdup (real);
70
71 /* Display name, either <Service> or <Service>@<Server> */
72 sptr->disp = service_name (name);
73
74 if (me.numeric && *me.numeric)
75 sptr->uid = sstrdup (uid_get ());
76
77 sptr->handler = handler;
78 sptr->notice_handler = dummy_handler;
79
80 sptr->cmdtree = &cmdtree;
81
82 if (me.connected)
83 {
84 u = user_find_named (name);
85 if (u != NULL)
86 {
87 skill (me.name, u->nick, "Nick taken by service");
88 user_delete (u);
89 }
90 }
91
92 sptr->me = user_add (name, user, host, NULL, NULL, ircd->uses_uid ? sptr->uid : NULL, real, me.me, NOW);
93 sptr->me->flags |= UF_IRCOP;
94
95 if (me.connected)
96 {
97 introduce_nick (sptr->me);
98 /* if the snoop channel already exists, join it now */
99 if (config_options.chan != NULL && channel_find (config_options.chan) != NULL)
100 join (config_options.chan, name);
101 }
102
103 dictionary_add (services, sptr->name, sptr);
104
105 return sptr;
106 }
107
108 void
109 del_service (service_t *sptr)
110 {
111 dictionary_delete (services, sptr->name);
112
113 quit_sts (sptr->me, "Service unloaded.");
114 user_delete (sptr->me);
115 sptr->me = NULL;
116 sptr->handler = NULL;
117 free (sptr->disp); /* service_name() does a malloc() */
118 free (sptr->name);
119 free (sptr->user);
120 free (sptr->host);
121 free (sptr->real);
122 free (sptr->uid);
123
124 BlockHeapFree (service_heap, sptr);
125 }
126
127 service_t *
128 find_service (char *name)
129 {
130 service_t *sptr;
131 user_t *u;
132 char *p;
133 char name2[NICKLEN];
134 dictionary_iteration_state_t state;
135
136 if (name[0] == '#')
137 return fcmd_agent;
138
139 p = strchr (name, '@');
140 if (p != NULL)
141 {
142 /* Make sure it's for us, not for a jupe -- jilles */
143 if (irccasecmp (p + 1, me.name))
144 return NULL;
145 strlcpy (name2, name, sizeof name2);
146 p = strchr (name2, '@');
147 if (p != NULL)
148 *p = '\0';
149 sptr = static_cast<service_t *> (dictionary_retrieve (services, name2));
150 if (sptr != NULL)
151 return sptr;
152 DICTIONARY_FOREACH (sptr, service_t, &state, services)
153 {
154 if (sptr->me != NULL && !strcasecmp (name2, sptr->user))
155 return sptr;
156 }
157 }
158 else
159 {
160 sptr = static_cast<service_t *> (dictionary_retrieve (services, name));
161 if (sptr != NULL)
162 return sptr;
163
164 if (ircd->uses_uid)
165 {
166 /* yuck yuck -- but quite efficient -- jilles */
167 u = user_find (name);
168 if (u != NULL && u->server == me.me)
169 return static_cast<service_t *> (dictionary_retrieve (services, u->nick));
170 }
171 }
172
173 return NULL;
174 }
175
176 char *
177 service_name (char *name)
178 {
179 char *buf = static_cast<char *> (smalloc (BUFSIZE));
180
181 snprintf (buf, BUFSIZE, "%s%s%s", name, (config_options.secure) ? "@" : "", (config_options.secure) ? me.name : "");
182
183 return buf;
184 }
185
186 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
187 * vim:ts=8
188 * vim:sw=8
189 * vim:noexpandtab
190 */