tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / kern / amiga_main.c
blob6d2e21183556ce81eee71c6e64281678e900b871
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
5 * Copyright (C) 2005 - 2010 The AROS Dev Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
23 #include <conf.h>
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/synch.h>
28 #include <sys/malloc.h>
29 #include <sys/mbuf.h>
30 #include <sys/syslog.h>
31 #include <sys/socket.h>
32 #include <sys/socketvar.h>
34 #include <stdio.h>
35 #include <version.h>
36 /*#include <string.h>*/
38 #include <signal.h> /* from the C compiler's includes */
40 #include <kern/amiga_includes.h>
41 #include <libraries/miamipanel.h>
43 #include <proto/dos.h>
44 //#include <proto/miamipanel.h>
46 #include <kern/amiga_time.h>
47 #include <kern/amiga_log.h>
49 ULONG sana_init(void);
50 void sana_deinit(void);
51 BOOL sana_poll(void);
53 #include <kern/amiga_main_protos.h>
54 #include <kern/amiga_config.h>
55 #include <kern/amiga_gui.h>
56 #include <kern/amiga_netdb.h>
57 #include <kern/amiga_rc.h>
58 #include <kern/amiga_log.h>
59 #include <kern/kern_malloc_protos.h>
60 #include <api/amiga_api.h>
63 * include prototypes for initialization functions
65 #include <kern/uipc_domain_protos.h> /* domaininit() */
68 * The main module of the AMITCP/IP.
72 * Global variable so AMITCP/IP task information can be utilized.
74 struct Task * AROSTCP_Task;
76 extern struct ExecBase * SysBase;
77 extern struct Library * MasterSocketBase;
78 extern WORD nthLibrary;
80 static ULONG sanamask = 0,
81 sig = 0, signalmask = 0, timermask = 0,
82 breakmask = 0;
84 UBYTE *taskname = NULL;
85 /*BPTR db_lock = NULL;*/
86 ULONG EnableDebug = 0;
87 BOOL initialized = FALSE;
89 TEXT interfaces_path[FILENAME_MAX];
90 TEXT netdb_path[FILENAME_MAX];
91 TEXT db_path[FILENAME_MAX];
92 TEXT config_path[FILENAME_MAX];
93 UBYTE logfiledefname[FILENAME_MAX];
94 UBYTE dhclient_path[FILENAME_MAX];
97 TEXT hequiv_path[FILENAME_MAX];
98 TEXT inetdconf_path[FILENAME_MAX];
100 STRPTR version = "$VER: " STACK_RELEASE;
103 main(int argc, char *argv[])
105 BYTE oldpri;
106 STRPTR oldname;
107 int retval;
108 struct Library *TestSocketBase;
110 #ifndef __AROS__
111 SysBase = *(struct ExecBase **)4;
112 #else
113 D(bug("[AROSTCP](amiga_main.c) main()\n"));
114 #endif
116 TestSocketBase = OpenLibrary("bsdsocket.library",0);
117 if (TestSocketBase) {
118 CloseLibrary(TestSocketBase);
119 error_request("Another TCP/IP stack is running, please quit it first.");
120 return 21;
123 #if defined(__AROS__)
124 D(bug("[AROSTCP](amiga_main.c) main: Kernel launching ...\n"));
125 #else
126 D(Printf(STACK_NAME " kernel started\n");)
127 #endif
130 * Disable CTRL-C(D) Break signal.
132 signal(SIGINT, SIG_IGN);
135 * Initialize AROSTCP_Task to point the Task structure of this task.
137 AROSTCP_Task = FindTask(NULL);
138 #if defined(__AROS__)
139 D(bug("[AROSTCP](amiga_main.c) main: AROSTCP_Task @ 0x%p\n",AROSTCP_Task));
140 #endif
141 D(Printf("AROSTCP_Task @ 0x%p\n",AROSTCP_Task);)
144 * Get a lock on the 'db' directory so we don't need an assign.
146 BPTR db_path_lock = BNULL;
148 char tmpconfigpath[1024];
150 #if defined(__AROS__)
151 D(bug("[AROSTCP](amiga_main.c) main: Setting environment default Paths ... \n"));
152 #endif
154 db_path_lock = GetProgramDir();
155 #if defined(__AROS__)
156 db_path_lock = ParentDir(db_path_lock);
157 #endif
159 NameFromLock(db_path_lock, interfaces_path, FILENAME_MAX);
161 #if defined(__AROS__)
162 D(bug("[AROSTCP](amiga_main.c) main: Directory tree root: %s\n", interfaces_path));
163 #endif
164 D(Printf("Directory tree root: %s\n", interfaces_path);)
165 strcpy(netdb_path, interfaces_path);
166 strcpy(db_path, interfaces_path);
167 strcpy(config_path, interfaces_path);
168 strcpy(logfiledefname, "T:"); /* NicJA: Default to storing logs in Temp for launching
169 from read only media */
170 strcpy(dhclient_path, interfaces_path);
171 /*strcpy(hequiv_path, interfaces_path);
172 strcpy(inetdconf_path, interfaces_path);*/
173 AddPart(interfaces_path, _PATH_DB, FILENAME_MAX);
174 AddPart(netdb_path, _PATH_DB, FILENAME_MAX);
175 AddPart(db_path, _PATH_DB, FILENAME_MAX);
176 AddPart(config_path, _PATH_DB, FILENAME_MAX);
177 AddPart(logfiledefname, _PATH_SYSLOG, FILENAME_MAX);
178 AddPart(dhclient_path, _PATH_DHCLIENT, FILENAME_MAX);
179 /*AddPart(hequiv_path, _PATH_HEQUIV, FILENAME_MAX);
180 AddPart(inetdconf_path, _PATH_INETDCONF, FILENAME_MAX);*/
182 /* NicJA : Allow user specified config location (from Env: variable) */
183 if (GetVar("AROSTCP/Config", tmpconfigpath, 1024, GVF_GLOBAL_ONLY) != -1)
185 db_path_lock = BNULL;
186 #if defined(__AROS__)
187 D(bug("[AROSTCP](amiga_main.c) main: Env: Var AROSTCP/Config set.\n"));
188 D(bug("[AROSTCP](amiga_main.c) main: Attempting to use '%s' for config location..\n", tmpconfigpath));
189 #endif
190 if (db_path_lock = Lock(tmpconfigpath, ACCESS_READ))
192 #if defined(__AROS__)
193 D(bug("[AROSTCP](amiga_main.c) main: successfully locked config dir '%s'\n", tmpconfigpath));
194 #endif
195 strcpy(interfaces_path, tmpconfigpath);
196 strcpy(netdb_path, tmpconfigpath);
197 strcpy(db_path, tmpconfigpath);
198 strcpy(config_path, tmpconfigpath);
199 //UnLock(db_path_lock);
201 /* TODO: NicJA - Attempt to create chosen config location */
202 /* TODO: NicJA - and copy defaults if it doesnt currently exist and is possible? */
205 AddPart(interfaces_path, _FILE_SANA2CONFIG, FILENAME_MAX);
206 AddPart(netdb_path, _FILE_NETDB, FILENAME_MAX);
207 AddPart(config_path, _FILE_CONFIG, FILENAME_MAX);
209 #if defined(__AROS__)
210 D(bug("[AROSTCP](amiga_main.c) main: Log file defaulting to '%s'\n", logfiledefname));
211 #endif
213 /* Save pointer to this tasks old name */
214 oldname = AROSTCP_Task->tc_Node.ln_Name;
216 if (init_all()) {
217 #if defined(__AROS__)
218 D(bug("[AROSTCP](amiga_main.c) main: preparing AROSTCP_Task\n"));
219 #endif
220 /* Set our priority */
221 oldpri = SetTaskPri(AROSTCP_Task, 5);
223 /* Set our Task name */
224 if (!taskname) {
225 #ifdef DEBUG
226 if (nthLibrary) {
227 if (taskname = bsd_malloc(16, M_CFGVAR, M_WAITOK)) {
228 strcpy(taskname, "bsdsocket.library");
229 taskname[6] = '.'; taskname[7] = '0' + nthLibrary;
231 } else {
232 #endif
233 taskname = "bsdsocket.library";
234 #ifdef DEBUG
236 #endif
238 if (taskname) AROSTCP_Task->tc_Node.ln_Name = taskname;
240 initialized = TRUE; /* Global initialization flag */
242 #ifdef DEBUG
243 /* Show our task address */
244 printf("%s Task address : %lx\n", taskname, (long) AROSTCP_Task);
245 #endif
247 /* Initialize signal mask for the wait */
248 breakmask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F;
249 signalmask = timermask | breakmask | sanamask;
252 * Now when everything else is successfully initialized,
253 * let the timeouts roll!
255 timer_send();
257 for(;;) {
258 sig = Wait(signalmask); /* Sleep until we are signalled. */
260 do {
261 if (sig & sanamask) {
262 if (!sana_poll()) sig &= ~sanamask;
265 if (sig & timermask) {
266 if (!timer_poll()) sig &= ~timermask;
269 sig |= SetSignal(0L, signalmask) & signalmask;
270 } while (sig & (~breakmask));
272 if (sig & breakmask) {
273 int i;
275 #if defined(__AROS__)
276 D(bug("[AROSTCP](amiga_main.c) main: Task received CTRL-C\n"));
277 #endif
278 /* We received CTRL-C
279 * NETTRACE task keeps one base open, it is not counted. */
280 api_hide(); /* hides the API from users */
282 api_sendbreaktotasks(); /* send brk to all tasks w/ SBase open */
284 /* Try three times with a short delay */
285 for (i = 0; i < 3 && MasterSocketBase->lib_OpenCnt > 1; i++) {
286 Delay(50); /* give tasks time to close socket base */
289 if (MasterSocketBase->lib_OpenCnt > 1) {
290 #if defined(__AROS__)
291 D(bug("[AROSTCP](amiga_main.c) main: Got CTRL-C while %ld %s still open.\n",
292 MasterSocketBase->lib_OpenCnt - 1,
293 (MasterSocketBase->lib_OpenCnt == 2) ? "library" : "libraries"));
294 #endif
296 __log(LOG_ERR, "Got CTRL-C while %ld %s still open.\n",
297 MasterSocketBase->lib_OpenCnt - 1,
298 (MasterSocketBase->lib_OpenCnt == 2) ? "library" : "libraries");
300 api_show(); /* stopping not successful, show API to users */
301 } else {
302 break;
306 retval = 0;
307 } else
308 retval = 20;
310 /* free all resources */
311 deinit_all();
312 initialized = FALSE;
314 SetTaskPri(AROSTCP_Task, oldpri);
315 AROSTCP_Task->tc_Node.ln_Name = oldname;
317 return retval;
321 * Do all initializations
323 BOOL
324 init_all(void)
326 #if defined(__AROS__)
327 D(bug("[AROSTCP](amiga_main.c) init_all()\n"));
328 #endif
330 * Initialize malloc semaphore
332 malloc_init();
333 D(Printf("malloc_init() complete\n");)
336 * initialize concurrency control subsystem
338 spl_init();
339 D(Printf("spl_init() complete\n");)
342 * initialize sleep queues
344 sleep_init();
345 D(Printf("sleep_init() complete\n");)
348 * Read command line arguments and configuration file
350 if (!readconfig())
351 return FALSE;
352 D(Printf("readconfig() complete\n");)
355 * initialize logging system
357 if (!log_init())
358 return FALSE;
359 D(Printf("log_init() complete\n");)
362 * initialize the mbuf subsystem
364 if (!mbinit())
365 return FALSE;
366 D(Printf("mbinit() complete\n");)
369 * initialize timer
371 if ((timermask = timer_init()) == 0L)
372 return FALSE;
373 D(Printf("timer_init() complete\n");)
376 * initialize API
378 if (!api_init())
379 return FALSE;
380 D(Printf("api_init() complete\n");)
383 * initialize SANA-II subsystem
385 if ((sanamask = sana_init()) == 0L)
386 return FALSE;
387 D(Printf("sana_init() complete\n");)
390 * initialize domains (initializes all protocols)
392 domaininit();
393 D(Printf("domaininit() complete\n");)
395 pfil_init();
396 D(Printf("pfil_init() complete\n");)
398 loconfig();
399 D(Printf("loconfig() complete\n");)
402 * Initialize NetDataBase
404 if (init_netdb() != 0)
405 return FALSE;
406 D(Printf("init_netdb() complete\n");)
409 * Make API visible
411 if (api_show() == FALSE)
412 return FALSE;
413 D(Printf("api_show() complete\n");)
415 if (Nettrace_Task) {
416 D(Printf("Initialization complete, signalling NETTRACE\n");)
417 Signal(Nettrace_Task, SIGBREAKF_CTRL_F);
418 } else
419 return FALSE;
421 rc_start();
422 D(Printf("rc_start() complete, initialization finished\n");)
424 #if defined(__AROS__)
425 D(bug("[AROSTCP](amiga_main.c) init_all: Initialisation successful.\n"));
426 #endif
428 return TRUE;
432 * clean up everything
434 void
435 deinit_all(void)
437 #if defined(__AROS__)
438 D(bug("[AROSTCP](amiga_main.c) deinit_all()\n"));
439 #endif
441 * make sure we are out of critical section
443 spl0();
444 D(Printf("spl0() completed\n");)
446 api_hide(); /* hides the API from users */
447 D(Printf("api_hide() completed\n");)
450 * Deinitialize network database.
452 netdb_deinit();
455 * Deinitialize network interfaces
457 sana_deinit();
460 * Deinitialize timers
462 timer_deinit();
465 * Free all resources allocated by mbufs.
467 mbdeinit();
468 D(Printf("mbdeinit() completed\n");)
470 log_deinit();
471 D(Printf("log_deinit() completed\n");)
474 * Free memory pool.
476 malloc_deinit();
477 D(Printf("malloc_deinit() completed\n");)
480 * Check that there are no libraries open (to our API). We can continue only
481 * if all bases are closed.
483 api_deinit(); /* NOTICE: this waits until every api user has exited */
487 * Notification function for taskname
489 int taskname_changed(void *p, IPTR new)
491 UBYTE *newname = (UBYTE *)new;
493 #if defined(__AROS__)
494 D(bug("[AROSTCP](amiga_main.c) taskname_changed()\n"));
495 #endif
497 AROSTCP_Task->tc_Node.ln_Name = newname;
498 if (initialized)
499 printf("New task name %s\n", newname);
501 return TRUE;