2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
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,
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/synch.h>
28 #include <sys/malloc.h>
30 #include <sys/syslog.h>
31 #include <sys/socket.h>
32 #include <sys/socketvar.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);
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,
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
[])
108 struct Library
*TestSocketBase
;
111 SysBase
= *(struct ExecBase
**)4;
113 D(bug("[AROSTCP](amiga_main.c) main()\n"));
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.");
123 #if defined(__AROS__)
124 D(bug("[AROSTCP](amiga_main.c) main: Kernel launching ...\n"));
126 D(Printf(STACK_NAME
" kernel started\n");)
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
));
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"));
154 db_path_lock
= GetProgramDir();
155 #if defined(__AROS__)
156 db_path_lock
= ParentDir(db_path_lock
);
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
));
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
));
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
));
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
));
213 /* Save pointer to this tasks old name */
214 oldname
= AROSTCP_Task
->tc_Node
.ln_Name
;
217 #if defined(__AROS__)
218 D(bug("[AROSTCP](amiga_main.c) main: preparing AROSTCP_Task\n"));
220 /* Set our priority */
221 oldpri
= SetTaskPri(AROSTCP_Task
, 5);
223 /* Set our Task name */
227 if (taskname
= bsd_malloc(16, M_CFGVAR
, M_WAITOK
)) {
228 strcpy(taskname
, "bsdsocket.library");
229 taskname
[6] = '.'; taskname
[7] = '0' + nthLibrary
;
233 taskname
= "bsdsocket.library";
238 if (taskname
) AROSTCP_Task
->tc_Node
.ln_Name
= taskname
;
240 initialized
= TRUE
; /* Global initialization flag */
243 /* Show our task address */
244 printf("%s Task address : %lx\n", taskname
, (long) AROSTCP_Task
);
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!
258 sig
= Wait(signalmask
); /* Sleep until we are signalled. */
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
) {
275 #if defined(__AROS__)
276 D(bug("[AROSTCP](amiga_main.c) main: Task received CTRL-C\n"));
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"));
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 */
310 /* free all resources */
314 SetTaskPri(AROSTCP_Task
, oldpri
);
315 AROSTCP_Task
->tc_Node
.ln_Name
= oldname
;
321 * Do all initializations
326 #if defined(__AROS__)
327 D(bug("[AROSTCP](amiga_main.c) init_all()\n"));
330 * Initialize malloc semaphore
333 D(Printf("malloc_init() complete\n");)
336 * initialize concurrency control subsystem
339 D(Printf("spl_init() complete\n");)
342 * initialize sleep queues
345 D(Printf("sleep_init() complete\n");)
348 * Read command line arguments and configuration file
352 D(Printf("readconfig() complete\n");)
355 * initialize logging system
359 D(Printf("log_init() complete\n");)
362 * initialize the mbuf subsystem
366 D(Printf("mbinit() complete\n");)
371 if ((timermask
= timer_init()) == 0L)
373 D(Printf("timer_init() complete\n");)
380 D(Printf("api_init() complete\n");)
383 * initialize SANA-II subsystem
385 if ((sanamask
= sana_init()) == 0L)
387 D(Printf("sana_init() complete\n");)
390 * initialize domains (initializes all protocols)
393 D(Printf("domaininit() complete\n");)
396 D(Printf("pfil_init() complete\n");)
399 D(Printf("loconfig() complete\n");)
402 * Initialize NetDataBase
404 if (init_netdb() != 0)
406 D(Printf("init_netdb() complete\n");)
411 if (api_show() == FALSE
)
413 D(Printf("api_show() complete\n");)
416 D(Printf("Initialization complete, signalling NETTRACE\n");)
417 Signal(Nettrace_Task
, SIGBREAKF_CTRL_F
);
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"));
432 * clean up everything
437 #if defined(__AROS__)
438 D(bug("[AROSTCP](amiga_main.c) deinit_all()\n"));
441 * make sure we are out of critical section
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.
455 * Deinitialize network interfaces
460 * Deinitialize timers
465 * Free all resources allocated by mbufs.
468 D(Printf("mbdeinit() completed\n");)
471 D(Printf("log_deinit() completed\n");)
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"));
497 AROSTCP_Task
->tc_Node
.ln_Name
= newname
;
499 printf("New task name %s\n", newname
);