Let dynamic filters and taggers support a $listen-address variable
[privoxy.git] / amiga.c
1 const char amiga_rcs[] = "$Id: amiga.c,v 1.15 2012/03/09 16:23:50 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/amiga.c,v $
5  *
6  * Purpose     :  Amiga-specific declarations.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
9  *                Privoxy team. http://www.privoxy.org/
10  *
11  *                This program is free software; you can redistribute it
12  *                and/or modify it under the terms of the GNU General
13  *                Public License as published by the Free Software
14  *                Foundation; either version 2 of the License, or (at
15  *                your option) any later version.
16  *
17  *                This program is distributed in the hope that it will
18  *                be useful, but WITHOUT ANY WARRANTY; without even the
19  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
20  *                PARTICULAR PURPOSE.  See the GNU General Public
21  *                License for more details.
22  *
23  *                The GNU General Public License should be included with
24  *                this file.  If not, you can view it at
25  *                http://www.gnu.org/copyleft/gpl.html
26  *                or write to the Free Software Foundation, Inc., 59
27  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  *
29  *********************************************************************/
30
31
32 #include "config.h"
33
34 #ifdef AMIGA
35
36 #include <stdio.h>
37 #include <signal.h>
38
39 #include "project.h"
40
41 const char amiga_h_rcs[] = AMIGA_H_VERSION;
42
43 static char *ver USED = "$VER: Privoxy " __AMIGAVERSION__ " (" __AMIGADATE__ ")";
44 #ifdef __amigaos4__
45 static char *stack USED = "$STACK: 524288";
46 #else
47 unsigned long __stack = 100*1024;
48 #endif
49 struct Task *main_task = NULL;
50 int childs = 0;
51
52 void serve(struct client_state *csp);
53
54 SAVEDS ULONG server_thread(void)
55 {
56    struct client_state *local_csp;
57    struct UserData UserData;
58    struct Task *me=FindTask(NULL);
59 #ifdef __amigaos4__
60    struct Library *SocketBase;
61 #endif
62
63    Wait(SIGF_SINGLE);
64    local_csp=(struct client_state *)(me->tc_UserData);
65    me->tc_UserData=&UserData;
66    SocketBase=(APTR)OpenLibrary("bsdsocket.library",3);
67    if (SocketBase)
68 #ifdef __amigaos4__
69    {
70       ISocket = (struct SocketIFace *)GetInterface(SocketBase, "main", 1, NULL);
71    }
72    if (ISocket)
73 #endif
74    {
75       SetErrnoPtr(&(UserData.eno),sizeof(int));
76       local_csp->cfd=ObtainSocket(local_csp->cfd, AF_INET, SOCK_STREAM, 0);
77       if (JB_INVALID_SOCKET!=local_csp->cfd)
78       {
79          Signal(main_task,SIGF_SINGLE);
80          serve((struct client_state *) local_csp);
81       } else {
82          local_csp->flags &= ~CSP_FLAG_ACTIVE;
83          Signal(main_task,SIGF_SINGLE);
84       }
85 #ifdef __amigaos4__
86       DropInterface((struct Interface *)ISocket);
87 #endif
88       CloseLibrary(SocketBase);
89    } else {
90 #ifdef __amigaos4__
91       CloseLibrary(SocketBase);
92 #endif
93       local_csp->flags &= ~CSP_FLAG_ACTIVE;
94       Signal(main_task,SIGF_SINGLE);
95    }
96    childs--;
97    return 0;
98 }
99
100 static BPTR olddir;
101
102 void amiga_exit(void)
103 {
104 #ifdef __amigaos4__
105    if (ISocket)
106 #else
107    if (SocketBase)
108 #endif
109    {
110 #ifdef __amigaos4__
111       struct Library *SocketBase = ISocket->Data.LibBase;
112       DropInterface((struct Interface *)ISocket);
113 #endif
114       CloseLibrary(SocketBase);
115    }
116    CurrentDir(olddir);
117 }
118
119 #ifndef __amigaos4__
120 static struct SignalSemaphore memsem;
121 static struct SignalSemaphore *memsemptr = NULL;
122 #endif
123 static struct UserData GlobalUserData;
124
125 void InitAmiga(void)
126 {
127 #ifdef __amigaos4__
128    struct Library *SocketBase;
129 #endif
130
131    main_task = FindTask(NULL);
132    main_task->tc_UserData = &GlobalUserData;
133
134    if (((struct Library *)SysBase)->lib_Version < 39)
135    {
136       exit(RETURN_FAIL);
137    }
138
139    signal(SIGINT,SIG_IGN);
140    SocketBase = (APTR)OpenLibrary("bsdsocket.library",3);
141 #ifdef __amigaos4__
142    if (SocketBase)
143    {
144       ISocket = (struct SocketIFace *)GetInterface(SocketBase, "main", 1, NULL);
145    }
146    if (!ISocket)
147 #else
148    if (!SocketBase)
149 #endif
150    {
151 #ifdef __amigaos4__
152       CloseLibrary(SocketBase);
153 #endif
154       fprintf(stderr, "Can't open bsdsocket.library V3+\n");
155       exit(RETURN_ERROR);
156    }
157    SetErrnoPtr(&(GlobalUserData.eno),sizeof(int));
158 #ifndef __amigaos4__
159    InitSemaphore(&memsem);
160    memsemptr = &memsem;
161 #endif
162
163    olddir=CurrentDir(GetProgramDir());
164    atexit(amiga_exit);
165 }
166
167 #ifndef __amigaos4__
168 #ifdef __GNUC__
169 #ifdef libnix
170 /* multithreadingsafe libnix replacements */
171 static void *memPool=NULL;
172
173 void *malloc (size_t s)
174 {
175    ULONG *mem;
176    LONG size = s;
177
178    if (size<=0)
179    {
180       return NULL;
181    }
182    if (!memPool)
183    {
184       if (!(memPool=CreatePool(MEMF_ANY,32*1024,8*1024)))
185       {
186          return NULL;
187       }
188    }
189    size += sizeof(ULONG) + MEM_BLOCKMASK;
190    size &= ~MEM_BLOCKMASK;
191    if (memsemptr)
192    {
193       ObtainSemaphore(memsemptr);
194    }
195    if ((mem=AllocPooled(memPool,size)))
196    {
197       *mem++=size;
198    }
199    if (memsemptr)
200    {
201       ReleaseSemaphore(memsemptr);
202    }
203    return mem;
204 }
205
206 void free (void *m)
207 {
208    ULONG *mem = m;
209
210    if (mem && memPool)
211    {
212       ULONG size=*--mem;
213
214       if (memsemptr)
215       {
216          ObtainSemaphore(memsemptr);
217       }
218       FreePooled(memPool,mem,size);
219       if (memsemptr)
220       {
221          ReleaseSemaphore(memsemptr);
222       }
223    }
224 }
225
226 void *realloc (void *old, size_t ns)
227 {
228    void *new;
229    LONG osize, *o = old;
230    LONG nsize = ns;
231
232    if (!old)
233    {
234       return malloc(nsize);
235    }
236    osize = (*(o-1)) - sizeof(ULONG);
237    if (nsize <= osize)
238    {
239       return old;
240    }
241    if ((new = malloc(nsize)))
242    {
243       ULONG *n = new;
244
245       osize >>= 2;
246       while(osize--)
247       {
248          *n++ = *o++;
249       }
250       free(old);
251    }
252    return new;
253 }
254
255 void __memCleanUp (void)
256 {
257    if (memsemptr)
258    {
259       ObtainSemaphore(memsemptr);
260    }
261    if (memPool)
262    {
263       DeletePool(memPool);
264    }
265    if (memsemptr)
266    {
267       ReleaseSemaphore(memsemptr);
268    }
269 }
270
271 #define ADD2LIST(a,b,c) asm(".stabs \"_" #b "\"," #c ",0,0,_" #a)
272 #define ADD2EXIT(a,pri) ADD2LIST(a,__EXIT_LIST__,22); \
273                         asm(".stabs \"___EXIT_LIST__\",20,0,0," #pri "+128")
274 ADD2EXIT(__memCleanUp,-50);
275 #elif !defined(ixemul)
276 #error No libnix and no ixemul!?
277 #endif /* libnix */
278 #else
279 #error Only GCC is supported, multithreading safe malloc/free required.
280 #endif /* __GNUC__ */
281 #endif /* !__amigaos4__ */
282
283 #endif /* def AMIGA */