ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/servtree.C
Revision: 1.2
Committed: Sat Jul 21 01:29:12 2007 UTC (16 years, 11 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

# User Rev Content
1 pippijn 1.1 /*
2     * Copyright © 2005-2006 Atheme Development Group
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
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     */