]> jfr.im git - irc/thales.git/blob - src/main.c
added support for NOQUIT
[irc/thales.git] / src / main.c
1 /* GNU Thales - IRC to Relational Database Gateway
2 * Copyright (C) 2002 Lucas Nussbaum <lucas@lucas-nussbaum.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 /* GNU Thales - main file */
19
20 #include "thales.h"
21 #include "conf.h"
22 #include "log.h"
23 #include "send.h"
24 #include "sockutil.h"
25 #include "compat.h"
26 #include "memory.h"
27 #include "process.h"
28 #include "db.h"
29
30 /* Global variables */
31
32 int debug = 0; /* -d , debug mode = don't fork + log to stderr */
33
34 int verbose = 0; /* -v, verbose output */
35
36 /* Socket for talking to server */
37 int servsock = -1;
38 char *quitmsg;
39
40 char inbuf[BUFSIZE];
41
42 /* At what time were we started? */
43 time_t start_time;
44
45 extern char *PIDFilename;
46 extern char *RemoteServer;
47 extern int RemotePort;
48 extern char *LocalHost;
49 extern int LocalPort;
50 extern char *RemotePassword;
51 extern char *ServerName;
52 extern char *ServerDesc;
53
54 /* display usage */
55 void usage()
56 {
57 printf("\n Syntax : thales\n");
58 printf(" -v : enable verbose mode\n");
59 printf(" -d : enable debugging mode\n");
60 printf(" -V : display version and exit\n");
61 exit(1);
62 }
63
64 /* Create our PID file and write the PID to it. */
65 void write_pidfile(void)
66 {
67 FILE *pidfile;
68
69 pidfile = fopen(PIDFilename, "w");
70 if (pidfile)
71 {
72 fprintf(pidfile, "%d\n", (int) getpid());
73 fclose(pidfile);
74 }
75 else
76 {
77 mylog_perror("Warning: cannot write to PID file %s", PIDFilename);
78 }
79 }
80
81 /* Main routine */
82 int main(int argc, char **argv)
83 {
84 char ch;
85 int i;
86 char *ch1, *ch2;
87 /* record start time */
88 start_time = time(NULL);
89 /* Parse command line options */
90 while ((ch = getopt(argc, argv, "dvV")) != -1)
91 {
92 switch (ch)
93 {
94 case 'd':
95 debug = 1;
96 verbose = 1;
97 break;
98 case 'v':
99 verbose = 1;
100 break;
101 case 'V':
102 printf("GNU Thales v.%s\n", VERSION);
103 exit(0);
104 break;
105 default:
106 usage();
107 }
108 }
109
110 /* Read configuration file; exit if there are problems. */
111 if (!read_config())
112 exit(-1);
113
114 /* Open logfile, and complain if we didn't. */
115 if (open_log() < 0)
116 {
117 fprintf(stderr, "Warning: unable to open log file : %s\n",
118 strerror(errno));
119 exit(1);
120 }
121
122 /* Detach ourselves if requested. */
123 if (!debug)
124 {
125 if ((i = fork()) < 0)
126 {
127 perror("fork()");
128 return -1;
129 }
130 else if (i != 0)
131 {
132 exit(0);
133 }
134 if (isatty(0) && isatty(1) && isatty(2))
135 {
136 close(0);
137 close(1);
138 close(2);
139 }
140 }
141 write_pidfile();
142
143 /* Announce ourselves to the logfile. */
144 mylog("GNU Thales %s starting up with %s support%s", VERSION,
145 #if defined(IRCD_UNREAL)
146 "unreal",
147 #elif defined(IRCD_HYBRID)
148 "hybrid",
149 #elif defined (IRCD_BAHAMUT)
150 "bahamut",
151 #elif defined (IRCD_IRCDRU)
152 "ircdru",
153 #elif defined (IRCD_ULTIMATE)
154 "ultimate30",
155 #elif defined (IRCD_ULTI28)
156 "ultimate28",
157 #else
158 "unknown (!)",
159 #endif
160 verbose ? (debug ? " (options: debug)" : " (options: verbose") :
161 "");
162 /* I should init databases here */
163 db_connect();
164 ch1 = db_escape(ServerName);
165 ch2 = db_escape(ServerDesc);
166 db_query("INSERT INTO " TBL_SERV
167 " (server, comment, connecttime) values('%s', '%s', NOW())",
168 ch1, ch2);
169 db_addserver(ch1, db_insertid());
170 free(ch1);
171 free(ch2);
172 /* connect to RemoteServer */
173 servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort);
174 if (servsock < 0)
175 {
176 fatal_perror("Can't connect to server");
177 exit(-1);
178 }
179 #if defined(IRCD_UNREAL)
180 send_cmd(NULL, "PROTOCTL NICKv2 SJOIN SJOIN2 SJ3");
181 send_cmd(NULL, "CAPAB NOQUIT");
182 #endif
183 #if defined(IRCD_HYBRID)
184 send_cmd(NULL, "PASS %s :TS", RemotePassword);
185 send_cmd(NULL, "CAPAB :HOPS TBURST");
186 #elif defined (IRCD_BAHAMUT)
187 send_cmd(NULL, "PASS %s :TS", RemotePassword);
188 send_cmd(NULL, "CAPAB TS3 SSJOIN NICKIP NOQUIT");
189 #elif defined (IRCD_IRCDRU)
190 send_cmd(NULL, "PASS %s :TS", RemotePassword);
191 send_cmd(NULL, "CAPAB TS3 SSJOIN 8BNCI NICKIP");
192
193 #elif defined (IRCD_ULTIMATE)
194 send_cmd(NULL, "PASS %s :TS", RemotePassword);
195 send_cmd(NULL, "CAPAB TS5 SSJ5 NICKIP");
196 #elif defined(IRCD_ULTI28) /* special case to prevent future errors */
197 send_cmd(NULL, "PASS %s", RemotePassword);
198 #else
199 send_cmd(NULL, "PASS %s", RemotePassword);
200 #endif
201
202 #if defined(IRCD_IRCDRU)
203 send_cmd(NULL, "SERVER %s 1 8 :%s", ServerName, ServerDesc);
204 #else
205 send_cmd(NULL, "SERVER %s 1 :%s", ServerName, ServerDesc);
206 #endif
207
208 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU)
209 send_cmd(NULL, "SVINFO 3 1 0 :%ld", time(NULL));
210 #elif defined(IRCD_ULTIMATE)
211 send_cmd(NULL, "SVINFO 5 3 0 :%ld", time(NULL));
212 #endif
213 #if defined(IRCD_UNREAL)
214 send_cmd(NULL, ":%s EOS", ServerName);
215 #endif
216 sgets2(inbuf, sizeof(inbuf), servsock);
217 if (strnicmp(inbuf, "ERROR", 5) == 0)
218 {
219 /* Close server socket first to stop wallops, since the other
220 * server doesn't want to listen to us anyway */
221 disconn(servsock);
222 servsock = -1;
223 fatal("Remote server returned: %s", inbuf);
224 }
225 /* We have a line left over from earlier, process it now */
226 process();
227 while (1)
228 {
229 i = (int) (long) sgets2(inbuf, sizeof(inbuf), servsock);
230 if (i > 0)
231 {
232 process();
233 }
234 else if (i == 0)
235 {
236 int errno_save = errno;
237 quitmsg = (char *) scalloc(BUFSIZE, 1);
238 if (quitmsg)
239 {
240 snprintf(quitmsg, BUFSIZE, "Read error from server: %s",
241 strerror(errno_save));
242 }
243 else
244 {
245 quitmsg = "Read error from server";
246 }
247 send_cmd(ServerName, "SQUIT %s :%s", ServerName, quitmsg);
248 disconn(servsock);
249 close_log();
250 return 0;
251 }
252 }
253 }