ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/servtree.C
Revision: 1.10
Committed: Sat Sep 22 14:27:30 2007 UTC (16 years, 9 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

# User Rev Content
1 pippijn 1.9 /**
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 pippijn 1.4 * Copyright © 2005-2006 Atheme Development Group
11 pippijn 1.1 */
12    
13 pippijn 1.10 static char const rcsid[] = "$Id: servtree.C,v 1.9 2007-09-16 18:54:45 pippijn Exp $";
14 pippijn 1.1
15     #include "atheme.h"
16 pippijn 1.10 #include <libermyth.h>
17 pippijn 1.8 #include "servers.h"
18 pippijn 1.4 #include <boost/foreach.hpp>
19 pippijn 1.1
20 pippijn 1.4 service_map services;
21 pippijn 1.1
22     static void
23     dummy_handler (sourceinfo_t *si, int parc, char **parv)
24     {
25     }
26    
27     void
28     servtree_init (void)
29     {
30 pippijn 1.4 #if 0
31 pippijn 1.1 service_heap = BlockHeapCreate (sizeof (service_t), 12);
32 pippijn 1.4 #endif
33 pippijn 1.1 }
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 pippijn 1.4 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 pippijn 1.1 {
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 pippijn 1.4 sptr = new service_t;
65 pippijn 1.1
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 pippijn 1.7 sptr->chanmsg = false;
82 pippijn 1.1
83     if (me.connected)
84     {
85     u = user_find_named (name);
86     if (u != NULL)
87     {
88 pippijn 1.4 phandler->skill (me.name, u->nick, "Nick taken by service");
89 pippijn 1.1 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 pippijn 1.4 phandler->introduce_nick (sptr->me);
99 pippijn 1.1 /* 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 pippijn 1.4 services[sptr->name] = sptr;
105 pippijn 1.1
106     return sptr;
107     }
108    
109     void
110     del_service (service_t *sptr)
111     {
112 pippijn 1.4 services.erase (sptr->name);
113 pippijn 1.1
114 pippijn 1.4 phandler->quit_sts (sptr->me, "Service unloaded.");
115 pippijn 1.1 user_delete (sptr->me);
116     sptr->me = NULL;
117     sptr->handler = NULL;
118 pippijn 1.5 sfree (sptr->disp); /* service_name() does a salloc() */
119 pippijn 1.4 sfree (sptr->name);
120     sfree (sptr->user);
121     sfree (sptr->host);
122     sfree (sptr->real);
123     sfree (sptr->uid);
124 pippijn 1.1
125 pippijn 1.4 delete sptr;
126 pippijn 1.1 }
127    
128     service_t *
129 pippijn 1.4 find_service (char const * const name)
130 pippijn 1.1 {
131     service_t *sptr;
132 pippijn 1.4 service_map::iterator sit;
133 pippijn 1.1 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 pippijn 1.4 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 pippijn 1.1 }
157     else
158     {
159 pippijn 1.4 sit = services.find (name);
160     if (sit != services.end ())
161     return sit->second;
162 pippijn 1.1
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 pippijn 1.4 return (sit = services.find (u->nick)) == services.end () ? NULL : sit->second;
169 pippijn 1.1 }
170     }
171    
172     return NULL;
173     }
174    
175     char *
176 pippijn 1.4 service_name (char const * const name)
177 pippijn 1.1 {
178 pippijn 1.5 char *buf = salloc<char> (BUFSIZE);
179 pippijn 1.1
180     snprintf (buf, BUFSIZE, "%s%s%s", name, (config_options.secure) ? "@" : "", (config_options.secure) ? me.name : "");
181    
182     return buf;
183     }