ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/servtree.C
Revision: 1.10
Committed: Sat Sep 22 14:27:30 2007 UTC (16 years, 7 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +2 -3 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /**
2 * servtree.C: Services binary tree manipulation. (add_service, del_service, et al.)
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2006 Atheme Development Group
11 */
12
13 static char const rcsid[] = "$Id: servtree.C,v 1.9 2007-09-16 18:54:45 pippijn Exp $";
14
15 #include "atheme.h"
16 #include <libermyth.h>
17 #include "servers.h"
18 #include <boost/foreach.hpp>
19
20 service_map services;
21
22 static void
23 dummy_handler (sourceinfo_t *si, int parc, char **parv)
24 {
25 }
26
27 void
28 servtree_init (void)
29 {
30 #if 0
31 service_heap = BlockHeapCreate (sizeof (service_t), 12);
32 #endif
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 const * const name, char const * const user, char const * const host, char const * const 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 = new service_t;
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 sptr->chanmsg = false;
82
83 if (me.connected)
84 {
85 u = user_find_named (name);
86 if (u != NULL)
87 {
88 phandler->skill (me.name, u->nick, "Nick taken by service");
89 user_delete (u);
90 }
91 }
92
93 sptr->me = user_add (name, user, host, NULL, NULL, ircd->uses_uid ? sptr->uid : NULL, real, me.me, NOW);
94 sptr->me->flags |= UF_IRCOP;
95
96 if (me.connected)
97 {
98 phandler->introduce_nick (sptr->me);
99 /* if the snoop channel already exists, join it now */
100 if (config_options.chan != NULL && channel_find (config_options.chan) != NULL)
101 join (config_options.chan, name);
102 }
103
104 services[sptr->name] = sptr;
105
106 return sptr;
107 }
108
109 void
110 del_service (service_t *sptr)
111 {
112 services.erase (sptr->name);
113
114 phandler->quit_sts (sptr->me, "Service unloaded.");
115 user_delete (sptr->me);
116 sptr->me = NULL;
117 sptr->handler = NULL;
118 sfree (sptr->disp); /* service_name() does a salloc() */
119 sfree (sptr->name);
120 sfree (sptr->user);
121 sfree (sptr->host);
122 sfree (sptr->real);
123 sfree (sptr->uid);
124
125 delete sptr;
126 }
127
128 service_t *
129 find_service (char const * const name)
130 {
131 service_t *sptr;
132 service_map::iterator sit;
133 user_t *u;
134 char *p;
135 char name2[NICKLEN];
136
137 p = strchr (name, '@');
138 if (p != NULL)
139 {
140 /* Make sure it's for us, not for a jupe -- jilles */
141 if (irccasecmp (p + 1, me.name))
142 return NULL;
143 strlcpy (name2, name, sizeof name2);
144 p = strchr (name2, '@');
145 if (p != NULL)
146 *p = '\0';
147 sit = services.find (name2);
148 if (sit != services.end ())
149 return sit->second;
150 foreach (service_pair &sp, services)
151 {
152 sptr = sp.second;
153 if (sptr->me != NULL && !strcasecmp (name2, sptr->user))
154 return sptr;
155 }
156 }
157 else
158 {
159 sit = services.find (name);
160 if (sit != services.end ())
161 return sit->second;
162
163 if (ircd->uses_uid)
164 {
165 /* yuck yuck -- but quite efficient -- jilles */
166 u = user_find (name);
167 if (u != NULL && u->server == me.me)
168 return (sit = services.find (u->nick)) == services.end () ? NULL : sit->second;
169 }
170 }
171
172 return NULL;
173 }
174
175 char *
176 service_name (char const * const name)
177 {
178 char *buf = salloc<char> (BUFSIZE);
179
180 snprintf (buf, BUFSIZE, "%s%s%s", name, (config_options.secure) ? "@" : "", (config_options.secure) ? me.name : "");
181
182 return buf;
183 }