ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/servtree.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +37 -47 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

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: servtree.C,v 1.3 2007-07-21 13:23:22 pippijn Exp $";
9
10 #include "atheme.h"
11 #include <boost/foreach.hpp>
12
13 service_map services;
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 #if 0
26 service_heap = BlockHeapCreate (sizeof (service_t), 12);
27 #endif
28 }
29
30 static void
31 me_me_init (void)
32 {
33 if (me.numeric)
34 init_uid ();
35 me.me = server_add (me.name, 0, NULL, me.numeric ? me.numeric : NULL, me.desc);
36 }
37
38 service_t *
39 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)
40 {
41 service_t *sptr;
42 user_t *u;
43
44 if (me.me == NULL)
45 me_me_init ();
46
47 if (name == NULL)
48 {
49 slog (LG_INFO, "add_service(): Bad error! We were given a NULL pointer for service name!");
50 return NULL;
51 }
52
53 if ((sptr = find_service (name)))
54 {
55 slog (LG_DEBUG, "add_service(): Service `%s' already exists.", name);
56 return NULL;
57 }
58
59 sptr = new service_t;
60
61 sptr->name = sstrdup (name);
62 sptr->user = sstrdup (user);
63 sptr->host = sstrdup (host);
64 sptr->real = sstrdup (real);
65
66 /* Display name, either <Service> or <Service>@<Server> */
67 sptr->disp = service_name (name);
68
69 if (me.numeric && *me.numeric)
70 sptr->uid = sstrdup (uid_get ());
71
72 sptr->handler = handler;
73 sptr->notice_handler = dummy_handler;
74
75 sptr->cmdtree = &cmdtree;
76
77 if (me.connected)
78 {
79 u = user_find_named (name);
80 if (u != NULL)
81 {
82 phandler->skill (me.name, u->nick, "Nick taken by service");
83 user_delete (u);
84 }
85 }
86
87 sptr->me = user_add (name, user, host, NULL, NULL, ircd->uses_uid ? sptr->uid : NULL, real, me.me, NOW);
88 sptr->me->flags |= UF_IRCOP;
89
90 if (me.connected)
91 {
92 phandler->introduce_nick (sptr->me);
93 /* if the snoop channel already exists, join it now */
94 if (config_options.chan != NULL && channel_find (config_options.chan) != NULL)
95 join (config_options.chan, name);
96 }
97
98 services[sptr->name] = sptr;
99
100 return sptr;
101 }
102
103 void
104 del_service (service_t *sptr)
105 {
106 services.erase (sptr->name);
107
108 phandler->quit_sts (sptr->me, "Service unloaded.");
109 user_delete (sptr->me);
110 sptr->me = NULL;
111 sptr->handler = NULL;
112 sfree (sptr->disp); /* service_name() does an alloc() */
113 sfree (sptr->name);
114 sfree (sptr->user);
115 sfree (sptr->host);
116 sfree (sptr->real);
117 sfree (sptr->uid);
118
119 delete sptr;
120 }
121
122 service_t *
123 find_service (char const * const name)
124 {
125 service_t *sptr;
126 service_map::iterator sit;
127 user_t *u;
128 char *p;
129 char name2[NICKLEN];
130
131 if (name[0] == '#')
132 return fcmd_agent;
133
134 p = strchr (name, '@');
135 if (p != NULL)
136 {
137 /* Make sure it's for us, not for a jupe -- jilles */
138 if (irccasecmp (p + 1, me.name))
139 return NULL;
140 strlcpy (name2, name, sizeof name2);
141 p = strchr (name2, '@');
142 if (p != NULL)
143 *p = '\0';
144 sit = services.find (name2);
145 if (sit != services.end ())
146 return sit->second;
147 foreach (service_pair &sp, services)
148 {
149 sptr = sp.second;
150 if (sptr->me != NULL && !strcasecmp (name2, sptr->user))
151 return sptr;
152 }
153 }
154 else
155 {
156 sit = services.find (name);
157 if (sit != services.end ())
158 return sit->second;
159
160 if (ircd->uses_uid)
161 {
162 /* yuck yuck -- but quite efficient -- jilles */
163 u = user_find (name);
164 if (u != NULL && u->server == me.me)
165 return (sit = services.find (u->nick)) == services.end () ? NULL : sit->second;
166 }
167 }
168
169 return NULL;
170 }
171
172 char *
173 service_name (char const * const name)
174 {
175 char *buf = alloc<char> (BUFSIZE);
176
177 snprintf (buf, BUFSIZE, "%s%s%s", name, (config_options.secure) ? "@" : "", (config_options.secure) ? me.name : "");
178
179 return buf;
180 }