ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.5
Committed: Thu Aug 30 06:57:25 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.4: +5 -8 lines
Log Message:
- chanlist to std::map

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * uplink.C: Uplink management.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.5 static char const rcsid[] = "$Id: uplink.C,v 1.4 2007-08-28 17:08:12 pippijn Exp $";
9    
10     #include <boost/foreach.hpp>
11 pippijn 1.1
12     #include "atheme.h"
13     #include "datastream.h"
14     #include "uplink.h"
15    
16     list_t uplinks;
17     uplink_t *curr_uplink;
18    
19     static void uplink_close (connection_t *cptr);
20    
21     void
22     init_uplinks (void)
23     {
24 pippijn 1.4 #if 0
25 pippijn 1.1 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
26 pippijn 1.4 #endif
27 pippijn 1.1 }
28    
29     uplink_t *
30     uplink_add (char *name, char *host, char *password, char *vhost, int port)
31     {
32     uplink_t *u;
33     node_t *n;
34    
35     slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port);
36    
37     if ((u = uplink_find (name)))
38     {
39     if (u->flags & UPF_ILLEGAL)
40     {
41     u->flags &= ~UPF_ILLEGAL;
42 pippijn 1.4 sfree (u->name);
43     sfree (u->host);
44     sfree (u->pass);
45     sfree (u->vhost);
46 pippijn 1.1 }
47     else
48     {
49     slog (LG_INFO, "Duplicate uplink %s.", name);
50     return NULL;
51     }
52     }
53     else
54     {
55 pippijn 1.4 u = new uplink_t;
56 pippijn 1.1 n = node_create ();
57     u->node = n;
58     node_add (u, n, &uplinks);
59     cnt.uplink++;
60     }
61    
62     u->name = sstrdup (name);
63     u->host = sstrdup (host);
64     u->pass = sstrdup (password);
65     if (vhost)
66     u->vhost = sstrdup (vhost);
67     else
68     u->vhost = sstrdup ("0.0.0.0");
69     u->port = port;
70    
71     return u;
72     }
73    
74     void
75     uplink_delete (uplink_t *u)
76     {
77     node_t *n = node_find (u, &uplinks);
78    
79 pippijn 1.4 sfree (u->name);
80     sfree (u->host);
81     sfree (u->pass);
82     sfree (u->vhost);
83 pippijn 1.1
84     node_del (n, &uplinks);
85     node_free (n);
86    
87 pippijn 1.4 delete u;
88 pippijn 1.1 cnt.uplink--;
89     }
90    
91     uplink_t *
92     uplink_find (char *name)
93     {
94     node_t *n;
95    
96     LIST_FOREACH (n, uplinks.head)
97     {
98     uplink_t *u = static_cast<uplink_t *> (n->data);
99    
100     if (!strcasecmp (u->name, name))
101     return u;
102     }
103    
104     return NULL;
105     }
106    
107     void
108     uplink_connect (void)
109     {
110     uplink_t *u;
111    
112     if (curr_uplink == NULL)
113     {
114     if (uplinks.head == NULL)
115     {
116     slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file.");
117     exit (EXIT_FAILURE);
118     }
119     curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
120     slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port);
121     }
122     else if (curr_uplink->node->next)
123     {
124     u = static_cast<uplink_t *> (curr_uplink->node->next->data);
125    
126     curr_uplink = u;
127     slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
128     }
129     else
130     {
131     curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
132     slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
133     }
134    
135     u = curr_uplink;
136    
137     curr_uplink->conn = connection_open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
138     if (curr_uplink->conn != NULL)
139     curr_uplink->conn->close_handler = uplink_close;
140     else
141     event_add_once ("reconn", reconn, NULL, me.recontime);
142     }
143    
144     /*
145     * uplink_close()
146     *
147     * inputs:
148     * connection pointer of current uplink
149     * triggered by callback close_handler
150     *
151     * outputs:
152     * none
153     *
154     * side effects:
155     * reconnection is scheduled
156     * uplink marked dead
157     * uplink deleted if it had been removed from configuration
158     */
159     static void
160     uplink_close (connection_t *cptr)
161     {
162     event_add_once ("reconn", reconn, NULL, me.recontime);
163    
164     me.connected = false;
165    
166     if (curr_uplink->flags & UPF_ILLEGAL)
167     {
168     slog (LG_INFO, "uplink_close(): %s was removed from configuration, deleting", curr_uplink->name);
169     uplink_delete (curr_uplink);
170     if (uplinks.head == NULL)
171     {
172     slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting.");
173     exit (EXIT_FAILURE);
174     }
175     curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
176     }
177     curr_uplink->conn = NULL;
178    
179     slog (LG_DEBUG, "uplink_close(): ----------------------- clearing -----------------------");
180    
181     /* we have to kill everything.
182     * we do not clear users here because when you delete a server,
183     * it deletes its users
184     */
185     if (me.actual != NULL)
186     server_delete (me.actual);
187     me.actual = NULL;
188     /* remove all the channels left */
189 pippijn 1.5 foreach (channel_pair &cp, chanlist)
190     channel_delete (cp.second);
191 pippijn 1.1 /* this leaves me.me and all users on it (i.e. services) */
192    
193     slog (LG_DEBUG, "uplink_close(): ------------------------- done -------------------------");
194     }