|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * bsdsocket.library emulation machine-independent part
5: *
6: * Copyright 1997, 1998 Mathias Ortmann
7: *
8: * Library initialization code (c) Tauno Taipaleenmaki
9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include <assert.h>
15: #include <stddef.h>
16:
17: #include "config.h"
18: #include "options.h"
19: #include "memory.h"
20: #include "custom.h"
21: #include "newcpu.h"
22: #include "autoconf.h"
23: #include "bsdsocket.h"
24: #include "osdep/exectasks.h"
25:
26: #ifdef BSDSOCKET_SUPPORTED
27:
28: static uae_u32 SockLibBase;
29:
30: #define SOCKPOOLSIZE 128
31: #define UNIQUE_ID (-1)
32:
33: /* ObtainSocket()/ReleaseSocket() public socket pool */
34: long sockpoolids[SOCKPOOLSIZE];
35: int sockpoolsocks[SOCKPOOLSIZE];
36: uae_u32 sockpoolflags[SOCKPOOLSIZE];
37:
38: long curruniqid = 65536;
39:
40: /* Memory-related helper functions */
41: static void memcpyha (uae_u32 dst, char *src, int size)
42: {
43: while (size--)
44: put_byte (dst++, *src++);
45: }
46:
47: char *strncpyah (char *dst, uae_u32 src, int size)
48: {
49: char *res = dst;
50: while (size-- && (*dst++ = get_byte (src++)));
51: return res;
52: }
53:
54: char *strcpyah (char *dst, uae_u32 src)
55: {
56: char *res = dst;
57: while ((*dst++ = get_byte (src++)) != 0);
58: return res;
59: }
60:
61: uae_u32 strcpyha (uae_u32 dst, char *src)
62: {
63: uae_u32 res = dst;
64:
65: do {
66: put_byte (dst++, *src);
67: } while (*src++);
68:
69: return res;
70: }
71:
72: uae_u32 strncpyha (uae_u32 dst, char *src, int size)
73: {
74: uae_u32 res = dst;
75: while (size--) {
76: put_byte (dst++, *src);
77: if (!*src++)
78: return res;
79: }
80: return res;
81: }
82:
83: uae_u32 addstr (uae_u32 * dst, char *src)
84: {
85: uae_u32 res = *dst;
86: int len;
87:
88: len = strlen (src) + 1;
89:
90: strcpyha (*dst, src);
91: (*dst) += len;
92:
93: return res;
94: }
95:
96: uae_u32 addmem (uae_u32 * dst, char *src, int len)
97: {
98: uae_u32 res = *dst;
99:
100: if (!src)
101: return 0;
102:
103: memcpyha (*dst, src, len);
104: (*dst) += len;
105:
106: return res;
107: }
108:
109: /* Get current task */
110: static uae_u32 gettask (void)
111: {
112: uae_u32 currtask, a1 = m68k_areg (regs, 1);
113:
114: m68k_areg (regs, 1) = 0;
115: currtask = CallLib (get_long (4), -0x126); /* FindTask */
116:
117: m68k_areg (regs, 1) = a1;
118:
119: TRACE (("[%s] ", get_real_address (get_long (currtask + 10))));
120: return currtask;
121: }
122:
123: /* errno/herrno setting */
124: void seterrno (SB, int sb_errno)
125: {
126: sb->sb_errno = sb_errno;
127:
128: if (sb->errnoptr) {
129: switch (sb->errnosize) {
130: case 1:
131: put_byte (sb->errnoptr, sb_errno);
132: break;
133: case 2:
134: put_word (sb->errnoptr, sb_errno);
135: break;
136: case 4:
137: put_long (sb->errnoptr, sb_errno);
138: }
139: }
140: }
141:
142: void setherrno (SB, int sb_herrno)
143: {
144: sb->sb_herrno = sb_herrno;
145:
146: if (sb->herrnoptr) {
147: switch (sb->herrnosize) {
148: case 1:
149: put_byte (sb->herrnoptr, sb_herrno);
150: break;
151: case 2:
152: put_word (sb->herrnoptr, sb_herrno);
153: break;
154: case 4:
155: put_long (sb->herrnoptr, sb_herrno);
156: }
157: }
158: }
159:
160: /* Socket descriptor/opaque socket handle management */
161: int getsd (SB, int s)
162: {
163: int i;
164: int *dt = sb->dtable;
165:
166: /* return socket descriptor if already exists */
167: for (i = sb->dtablesize; i--;)
168: if (dt[i] == s)
169: return i + 1;
170:
171: /* create new table entry */
172: for (i = 0; i < sb->dtablesize; i++)
173: if (dt[i] == -1) {
174: dt[i] = s;
175: sb->ftable[i] = SF_BLOCKING;
176: return i + 1;
177: }
178: /* descriptor table full. */
179: seterrno (sb, 24); /* EMFILE */
180:
181: return -1;
182: }
183:
184: int getsock (SB, int sd)
185: {
186: if ((unsigned int) (sd - 1) >= (unsigned int) sb->dtablesize) {
187: TRACE (("Invalid Socket Descriptor (%d)\n", sd));
188: seterrno (sb, 38); /* ENOTSOCK */
189:
190: return -1;
191: }
192: return sb->dtable[sd - 1];
193: }
194:
195: void releasesock (SB, int sd)
196: {
197: if ((unsigned int) (sd - 1) < (unsigned int) sb->dtablesize)
198: sb->dtable[sd - 1] = -1;
199: }
200:
201: /* Signal queue */
202: /* @@@ TODO: ensure proper interlocking */
203: struct socketbase *sbsigqueue;
204:
205: void addtosigqueue (SB, int events)
206: {
207: locksigqueue ();
208:
209: if (events)
210: sb->sigstosend |= sb->eventsigs;
211: else
212: sb->sigstosend |= ((uae_u32) 1) << sb->signal;
213:
214: if (!sb->dosignal) {
215: sb->nextsig = sbsigqueue;
216: sbsigqueue = sb;
217: }
218: sb->dosignal = 1;
219:
220: unlocksigqueue ();
221:
222: INTREQ (0xA000);
223: }
224:
225: static uae_u32 bsdsock_int_handler (void)
226: {
227: SB;
228:
229: if (sbsigqueue != NULL) {
230: locksigqueue ();
231:
232: for (sb = sbsigqueue; sb; sb = sb->nextsig) {
233: if (sb->dosignal == 1) {
234: struct regstruct sbved_regs = regs;
235: m68k_areg (regs, 1) = sb->ownertask;
236: m68k_dreg (regs, 0) = sb->sigstosend;
237: CallLib (get_long (4), -0x144); /* Signal() */
238:
239: regs = sbved_regs;
240:
241: sb->sigstosend = 0;
242: }
243: sb->dosignal = 0;
244: }
245:
246: sbsigqueue = NULL;
247: unlocksigqueue ();
248: }
249: return 0;
250: }
251:
252: void waitsig (SB)
253: {
254: m68k_dreg (regs, 0) = (((uae_u32) 1) << sb->signal) | sb->eintrsigs;
255: if (CallLib (get_long (4), -0x13e) & sb->eintrsigs) {
256: sockabort (sb);
257: seterrno (sb, 4); /* EINTR */
258:
259: sb->eintr = 1;
260: } else
261: sb->eintr = 0;
262: }
263:
264: void cancelsig (SB)
265: {
266: locksigqueue ();
267: if (sb->dosignal)
268: sb->dosignal = 2;
269: unlocksigqueue ();
270:
271: m68k_dreg (regs, 0) = 0;
272: m68k_dreg (regs, 1) = ((uae_u32) 1) << sb->signal;
273: CallLib (get_long (4), -0x132); /* SetSignal() */
274:
275: }
276:
277: /* Allocate and initialize per-task state structure */
278: static struct socketbase *alloc_socketbase (void)
279: {
280: SB;
281: int i;
282:
283: if ((sb = calloc (sizeof (struct socketbase), 1)) != NULL) {
284: sb->ownertask = gettask ();
285:
286: m68k_dreg (regs, 0) = -1;
287: sb->signal = CallLib (get_long (4), -0x14A);
288:
289: if (sb->signal == -1) {
290: write_log ("bsdsocket: ERROR: Couldn't allocate signal for task 0x%lx.\n", sb->ownertask);
291: free (sb);
292: return NULL;
293: }
294: m68k_dreg (regs, 0) = SCRATCHBUFSIZE;
295: m68k_dreg (regs, 1) = 0;
296:
297: sb->dtablesize = DEFAULT_DTABLE_SIZE;
298: /* @@@ check malloc() result */
299: sb->dtable = malloc (sb->dtablesize * sizeof (*sb->dtable));
300: sb->ftable = malloc (sb->dtablesize * sizeof (*sb->ftable));
301:
302: for (i = sb->dtablesize; i--;)
303: sb->dtable[i] = -1;
304:
305: sb->eintrsigs = 0x1000; /* SIGBREAKF_CTRL_C */
306:
307: if (!host_sbinit (sb)) {
308: /* @@@ free everything */
309: }
310: if (socketbases)
311: sb->next = socketbases;
312: socketbases = sb;
313:
314: return sb;
315: }
316: return NULL;
317: }
318:
319: struct socketbase *get_socketbase (void)
320: {
321: /* @@@ make portable for sizeof(void *) != sizeof(uae_u32) */
322: return (struct socketbase *) get_long (m68k_areg (regs, 6) + offsetof (struct UAEBSDBase, sb));
323: }
324:
325: static void free_socketbase (void)
326: {
327: struct socketbase *sb, *nsb;
328: int i;
329:
330: if ((sb = get_socketbase ()) != NULL) {
331: m68k_dreg (regs, 0) = sb->signal;
332: CallLib (get_long (4), -0x150); /* FreeSignal */
333:
334: if (sb->hostent) {
335: m68k_areg (regs, 1) = sb->hostent;
336: m68k_dreg (regs, 0) = sb->hostentsize;
337: CallLib (get_long (4), -0xD2); /* FreeMem */
338:
339: }
340: if (sb->protoent) {
341: m68k_areg (regs, 1) = sb->protoent;
342: m68k_dreg (regs, 0) = sb->protoentsize;
343: CallLib (get_long (4), -0xD2); /* FreeMem */
344:
345: }
346: if (sb->servent) {
347: m68k_areg (regs, 1) = sb->servent;
348: m68k_dreg (regs, 0) = sb->serventsize;
349: CallLib (get_long (4), -0xD2); /* FreeMem */
350:
351: }
352: host_sbcleanup (sb);
353:
354: free (sb->dtable);
355: free (sb->ftable);
356:
357: locksigqueue ();
358:
359: if (sb == socketbases)
360: socketbases = sb->next;
361: else {
362: for (nsb = socketbases; nsb; nsb = nsb->next) {
363: if (sb == nsb->next) {
364: nsb->next = sb->next;
365: break;
366: }
367: }
368: }
369:
370: if (sb == sbsigqueue)
371: sbsigqueue = sb->next;
372: else {
373: for (nsb = sbsigqueue; nsb; nsb = nsb->next) {
374: if (sb == nsb->next) {
375: nsb->next = sb->next;
376: break;
377: }
378: }
379: }
380:
381: unlocksigqueue ();
382:
383: free (sb);
384: }
385: }
386:
387: static uae_u32 bsdsocklib_Expunge (void)
388: {
389: TRACE (("Expunge() -> [ignored]\n"));
390: return 0;
391: }
392:
393: static uae_u32 functable, datatable, inittable;
394:
395: #define SOCKETBASE get_socketbase()
396:
397: static uae_u32 bsdsocklib_Open (void)
398: {
399: uae_u32 result = 0;
400: int opencount;
401: SB;
402:
403: locksigqueue ();
404:
405: TRACE (("OpenLibrary() -> "));
406:
407: if ((sb = alloc_socketbase ()) != NULL) {
408: put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) + 1);
409:
410: m68k_areg (regs, 0) = functable;
411: m68k_areg (regs, 1) = datatable;
412: m68k_areg (regs, 2) = 0;
413: m68k_dreg (regs, 0) = sizeof (struct UAEBSDBase);
414: m68k_dreg (regs, 1) = 0;
415: result = CallLib (get_long (4), -0x54);
416:
417: /* @@@ make portable for sizeof(void *) != sizeof(uae_u32) */
418: put_long (result + offsetof (struct UAEBSDBase, sb), (uae_u32) sb);
419:
420: TRACE (("%0lx [%d]\n", result, opencount));
421: } else
422: TRACE (("failed (out of memory)\n"));
423:
424: unlocksigqueue ();
425:
426: return result;
427: }
428:
429: static uae_u32 bsdsocklib_Close (void)
430: {
431: int opencount;
432:
433: uae_u32 base = m68k_areg (regs, 6);
434: uae_u32 negsize = get_word (base + 16);
435:
436: free_socketbase ();
437:
438: put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) - 1);
439:
440: m68k_areg (regs, 1) = base - negsize;
441: m68k_dreg (regs, 0) = negsize + get_word (base + 18);
442: CallLib (get_long (4), -0xD2); /* FreeMem */
443:
444: TRACE (("CloseLibrary() -> [%d]\n", opencount));
445:
446: return 0;
447: }
448:
449: /* socket(domain, type, protocol)(d0/d1/d2) */
450: static uae_u32 bsdsocklib_socket (void)
451: {
452: return host_socket (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1),
453: m68k_dreg (regs, 2));
454: }
455:
456: /* bind(s, name, namelen)(d0/a0/d1) */
457: static uae_u32 bsdsocklib_bind (void)
458: {
459: return host_bind (SOCKETBASE, m68k_dreg (regs, 0), m68k_areg (regs, 0),
460: m68k_dreg (regs, 1));
461: }
462:
463: /* listen(s, backlog)(d0/d1) */
464: static uae_u32 bsdsocklib_listen (void)
465: {
466: return host_listen (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
467: }
468:
469: /* accept(s, addr, addrlen)(d0/a0/a1) */
470: static uae_u32 bsdsocklib_accept (void)
471: {
472: SB = get_socketbase ();
473: host_accept (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
474: return sb->resultval;
475: }
476:
477: /* connect(s, name, namelen)(d0/a0/d1) */
478: static uae_u32 bsdsocklib_connect (void)
479: {
480: SB = get_socketbase ();
481: host_connect (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1));
482: return sb->sb_errno ? -1 : 0;
483: }
484:
485: /* sendto(s, msg, len, flags, to, tolen)(d0/a0/d1/d2/a1/d3) */
486: static uae_u32 bsdsocklib_sendto (void)
487: {
488: SB = get_socketbase ();
489: host_sendto (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
490: m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_dreg (regs, 3));
491: return sb->resultval;
492: }
493:
494: /* send(s, msg, len, flags)(d0/a0/d1/d2) */
495: static uae_u32 bsdsocklib_send (void)
496: {
497: SB = get_socketbase ();
498: host_sendto (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
499: m68k_dreg (regs, 2), 0, 0);
500: return sb->resultval;
501: }
502:
503: /* recvfrom(s, buf, len, flags, from, fromlen)(d0/a0/d1/d2/a1/a2) */
504: static uae_u32 bsdsocklib_recvfrom (void)
505: {
506: SB = get_socketbase ();
507: host_recvfrom (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
508: m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_areg (regs, 2));
509: return sb->resultval;
510: }
511:
512: /* recv(s, buf, len, flags)(d0/a0/d1/d2) */
513: static uae_u32 bsdsocklib_recv (void)
514: {
515: SB = get_socketbase ();
516: host_recvfrom (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
517: m68k_dreg (regs, 2), 0, 0);
518: return sb->resultval;
519: }
520:
521: /* shutdown(s, how)(d0/d1) */
522: static uae_u32 bsdsocklib_shutdown (void)
523: {
524: return host_shutdown (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
525: }
526:
527: /* setsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/d3) */
528: static uae_u32 bsdsocklib_setsockopt (void)
529: {
530: SB = get_socketbase ();
531: host_setsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
532: m68k_areg (regs, 0), m68k_dreg (regs, 3));
533: return sb->resultval;
534: }
535:
536: /* getsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/a1) */
537: static uae_u32 bsdsocklib_getsockopt (void)
538: {
539: return host_getsockopt (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
540: m68k_areg (regs, 0), m68k_areg (regs, 1));
541: }
542:
543: /* getsockname(s, hostname, namelen)(d0/a0/a1) */
544: static uae_u32 bsdsocklib_getsockname (void)
545: {
546: return host_getsockname (SOCKETBASE, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
547: }
548:
549: /* getpeername(s, hostname, namelen)(d0/a0/a1) */
550: static uae_u32 bsdsocklib_getpeername (void)
551: {
552: return host_getpeername (SOCKETBASE, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
553: }
554:
555: /* *------ generic system calls related to sockets */
556: /* IoctlSocket(d, request, argp)(d0/d1/a0) */
557: static uae_u32 bsdsocklib_IoctlSocket (void)
558: {
559: return host_IoctlSocket (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_areg (regs, 0));
560: }
561:
562: /* *------ AmiTCP/IP specific stuff */
563: /* CloseSocket(d)(d0) */
564: static uae_u32 bsdsocklib_CloseSocket (void)
565: {
566: return host_CloseSocket (SOCKETBASE, m68k_dreg (regs, 0));
567: }
568:
569: /* WaitSelect(nfds, readfds, writefds, execptfds, timeout, maskp)(d0/a0/a1/a2/a3/d1) */
570: static uae_u32 bsdsocklib_WaitSelect (void)
571: {
572: SB = get_socketbase ();
573: host_WaitSelect (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1),
574: m68k_areg (regs, 2), m68k_areg (regs, 3), m68k_dreg (regs, 1));
575: return sb->resultval;
576: }
577:
578: /* SetSocketSignals(SIGINTR, SIGIO, SIGURG)(d0/d1/d2) */
579: static uae_u32 bsdsocklib_SetSocketSignals (void)
580: {
581: SB = get_socketbase ();
582:
583: TRACE (("SetSocketSignals(0x%08lx,0x%08lx,0x%08lx) -> ", m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2)));
584: sb->eintrsigs = m68k_dreg (regs, 0);
585: sb->eventsigs = m68k_dreg (regs, 1);
586:
587: return 0;
588: }
589:
590: /* SetDTableSize(size)(d0) */
591: static uae_u32 bsdsocklib_SetDTableSize (void)
592: {
593: write_log ("bsdsocket: UNSUPPORTED: SetDTableSize()\n");
594: return 0;
595: }
596:
597: static int sockpoolindex (long id)
598: {
599: int i;
600:
601: for (i = 0; i < SOCKPOOLSIZE; i++)
602: if (sockpoolids[i] == id)
603: return i;
604:
605: return -1;
606: }
607:
608: /* ObtainSocket(id, domain, type, protocol)(d0/d1/d2/d3) */
609: static uae_u32 bsdsocklib_ObtainSocket (void)
610: {
611: SB = SOCKETBASE;
612: int sd;
613: long id;
614: int s;
615: int i;
616:
617: id = m68k_dreg (regs, 0);
618:
619: TRACE (("ReleaseSocket(%d,%d,%d,%d) -> ", id, m68k_dreg (regs, 1), m68k_dreg (regs, 2), m68k_dreg (regs, 3)));
620:
621: i = sockpoolindex (id);
622:
623: if (i == -1) {
624: TRACE (("[invalid key]\n"));
625: return -1;
626: }
627: s = sockpoolsocks[i];
628:
629: sd = getsd (sb, s);
630: sb->ftable[sd - 1] = sockpoolflags[i];
631:
632: TRACE (("%d\n", sd));
633:
634: sockpoolids[i] = UNIQUE_ID;
635:
636: return sd;
637: }
638:
639: /* ReleaseSocket(fd, id)(d0/d1) */
640: static uae_u32 bsdsocklib_ReleaseSocket (void)
641: {
642: SB = SOCKETBASE;
643: int sd;
644: long id;
645: int s;
646: int i;
647: uae_u32 flags;
648:
649: sd = m68k_dreg (regs, 0);
650: id = m68k_dreg (regs, 1);
651:
652: TRACE (("ReleaseSocket(%d,%d) -> ", sd, id));
653:
654: s = getsock (sb, sd);
655:
656: if (s != -1) {
657: flags = sb->ftable[sd - 1];
658:
659: if (flags & REP_ALL) {
660: write_log ("bsdsocket: ERROR: ReleaseSocket() is not supported for sockets with async event notification enabled!\n");
661: return -1;
662: }
663: releasesock (sb, sd);
664:
665: if (id == UNIQUE_ID) {
666: for (;;) {
667: if (sockpoolindex (curruniqid) == -1)
668: break;
669: curruniqid += 129;
670: if ((unsigned long) (curruniqid + 1) < 65536)
671: curruniqid += 65537;
672: }
673:
674: id = curruniqid;
675: } else if (id < 0 && id > 65535) {
676: if (sockpoolindex (id) != -1) {
677: TRACE (("[unique ID already exists]\n"));
678: return -1;
679: }
680: }
681: i = sockpoolindex (-1);
682:
683: if (i == -1) {
684: TRACE (("-1\n"));
685: write_log (("bsdsocket: ERROR: Global socket pool overflow\n"));
686: return -1;
687: }
688: sockpoolids[i] = id;
689: sockpoolsocks[i] = s;
690: sockpoolflags[i] = flags;
691:
692: TRACE (("%d\n", id));
693: } else {
694: TRACE (("[invalid socket descriptor]\n"));
695: return -1;
696: }
697:
698: return id;
699: }
700:
701: /* ReleaseCopyOfSocket(fd, id)(d0/d1) */
702: static uae_u32 bsdsocklib_ReleaseCopyOfSocket (void)
703: {
704: write_log ("bsdsocket: UNSUPPORTED: ReleaseCopyOfSocket()\n");
705: return 0;
706: }
707:
708: /* Errno()() */
709: static uae_u32 bsdsocklib_Errno (void)
710: {
711: SB = get_socketbase ();
712: TRACE (("Errno() -> %d\n", sb->sb_errno));
713: return sb->sb_errno;
714: }
715:
716: /* SetErrnoPtr(errno_p, size)(a0/d0) */
717: static uae_u32 bsdsocklib_SetErrnoPtr (void)
718: {
719: SB = get_socketbase ();
720: uae_u32 errnoptr = m68k_areg (regs, 0), size = m68k_dreg (regs, 0);
721:
722: TRACE (("SetErrnoPtr(0x%lx,%d) -> ", errnoptr, size));
723:
724: if (size == 1 || size == 2 || size == 4) {
725: sb->errnoptr = errnoptr;
726: sb->errnosize = size;
727: TRACE (("OK\n"));
728: return 0;
729: }
730: seterrno (sb, 22); /* EINVAL */
731:
732: return -1;
733: }
734:
735: /* *------ inet library calls related to inet address manipulation */
736: /* Inet_NtoA(in)(d0) */
737: static uae_u32 bsdsocklib_Inet_NtoA (void)
738: {
739: return host_Inet_NtoA (SOCKETBASE, m68k_dreg (regs, 0));
740: }
741:
742: /* inet_addr(cp)(a0) */
743: static uae_u32 bsdsocklib_inet_addr (void)
744: {
745: return host_inet_addr (m68k_areg (regs, 0));
746: }
747:
748: /* Inet_LnaOf(in)(d0) */
749: static uae_u32 bsdsocklib_Inet_LnaOf (void)
750: {
751: write_log ("bsdsocket: UNSUPPORTED: Inet_LnaOf()\n");
752: return 0;
753: }
754:
755: /* Inet_NetOf(in)(d0) */
756: static uae_u32 bsdsocklib_Inet_NetOf (void)
757: {
758: write_log ("bsdsocket: UNSUPPORTED: Inet_NetOf()\n");
759: return 0;
760: }
761:
762: /* Inet_MakeAddr(net, host)(d0/d1) */
763: static uae_u32 bsdsocklib_Inet_MakeAddr (void)
764: {
765: write_log ("bsdsocket: UNSUPPORTED: Inet_MakeAddr()\n");
766: return 0;
767: }
768:
769: /* inet_network(cp)(a0) */
770: static uae_u32 bsdsocklib_inet_network (void)
771: {
772: return host_inet_addr (m68k_areg (regs, 0));
773: }
774:
775: /* *------ gethostbyname etc */
776: /* gethostbyname(name)(a0) */
777: static uae_u32 bsdsocklib_gethostbyname (void)
778: {
779: SB = get_socketbase ();
780: host_gethostbynameaddr (sb, m68k_areg (regs, 0), 0, -1);
781: return sb->sb_errno ? 0 : sb->hostent;
782: }
783:
784: /* gethostbyaddr(addr, len, type)(a0/d0/d1) */
785: static uae_u32 bsdsocklib_gethostbyaddr (void)
786: {
787: SB = get_socketbase ();
788: host_gethostbynameaddr (sb, m68k_areg (regs, 0), m68k_dreg (regs, 0), m68k_dreg (regs, 1));
789: return sb->sb_errno ? 0 : sb->hostent;
790: }
791:
792: /* getnetbyname(name)(a0) */
793: static uae_u32 bsdsocklib_getnetbyname (void)
794: {
795: write_log ("bsdsocket: UNSUPPORTED: getnetbyname()\n");
796: return 0;
797: }
798:
799: /* getnetbyaddr(net, type)(d0/d1) */
800: static uae_u32 bsdsocklib_getnetbyaddr (void)
801: {
802: write_log ("bsdsocket: UNSUPPORTED: getnetbyaddr()\n");
803: return 0;
804: }
805:
806: /* getservbyname(name, proto)(a0/a1) */
807: static uae_u32 bsdsocklib_getservbyname (void)
808: {
809: SB = get_socketbase ();
810: host_getservbynameport (sb, m68k_areg (regs, 0), m68k_areg (regs, 1), 0);
811: return sb->sb_errno ? 0 : sb->servent;
812: }
813:
814: /* getservbyport(port, proto)(d0/a0) */
815: static uae_u32 bsdsocklib_getservbyport (void)
816: {
817: SB = get_socketbase ();
818: host_getservbynameport (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), 1);
819: return sb->sb_errno ? 0 : sb->servent;
820: }
821:
822: /* getprotobyname(name)(a0) */
823: static uae_u32 bsdsocklib_getprotobyname (void)
824: {
825: SB = get_socketbase ();
826: host_getprotobyname (sb, m68k_areg (regs, 0));
827: return sb->sb_errno ? 0 : sb->protoent;
828: }
829:
830: /* getprotobynumber(proto)(d0) */
831: static uae_u32 bsdsocklib_getprotobynumber (void)
832: {
833: write_log ("bsdsocket: UNSUPPORTED: getprotobynumber()\n");
834: return 0;
835: }
836:
837: /* *------ syslog functions */
838: /* Syslog(level, format, ap)(d0/a0/a1) */
839: static uae_u32 bsdsocklib_vsyslog (void)
840: {
841: write_log ("bsdsocket: UNSUPPORTED: vsyslog()\n");
842: return 0;
843: }
844:
845: /* *------ AmiTCP/IP 1.1 extensions */
846: /* Dup2Socket(fd1, fd2)(d0/d1) */
847: static uae_u32 bsdsocklib_Dup2Socket (void)
848: {
849: write_log ("bsdsocket: UNSUPPORTED: Dup2Socket()\n");
850: return 0;
851: }
852:
853: static uae_u32 bsdsocklib_sendmsg (void)
854: {
855: write_log ("bsdsocket: UNSUPPORTED: sendmsg()\n");
856: return 0;
857: }
858:
859: static uae_u32 bsdsocklib_recvmsg (void)
860: {
861: write_log ("bsdsocket: UNSUPPORTED: recvmsg()\n");
862: return 0;
863: }
864:
865: static uae_u32 bsdsocklib_gethostname (void)
866: {
867: return host_gethostname (m68k_areg (regs, 0), m68k_dreg (regs, 0));
868: }
869:
870: static uae_u32 bsdsocklib_gethostid (void)
871: {
872: write_log ("bsdsocket: WARNING: Process '%s' calls deprecated function gethostid() - returning 127.0.0.1\n", get_real_address (get_long (gettask () + 10)));
873: return 0x7f000001;
874: }
875:
876: char *errortexts[] =
877: {"No error", "Operation not permitted", "No such file or directory",
878: "No such process", "Interrupted system call", "Input/output error", "Device not configured",
879: "Argument list too long", "Exec format error", "Bad file descriptor", "No child processes",
880: "Resource deadlock avoided", "Cannot allocate memory", "Permission denied", "Bad address",
881: "Block device required", "Device busy", "Object exists", "Cross-device link",
882: "Operation not supported by device", "Not a directory", "Is a directory", "Invalid argument",
883: "Too many open files in system", "Too many open files", "Inappropriate ioctl for device",
884: "Text file busy", "File too large", "No space left on device", "Illegal seek",
885: "Read-only file system", "Too many links", "Broken pipe", "Numerical argument out of domain",
886: "Result too large", "Resource temporarily unavailable", "Operation now in progress",
887: "Operation already in progress", "Socket operation on non-socket", "Destination address required",
888: "Messbge too long", "Protocol wrong type for socket", "Protocol not available",
889: "Protocol not supported", "Socket type not supported", "Operation not supported",
890: "Protocol family not supported", "Address family not supported by protocol family",
891: "Address already in use", "Can't assign requested address", "Network is down",
892: "Network is unreachable", "Network dropped connection on reset", "Software caused connection abort",
893: "Connection reset by peer", "No buffer space available", "Socket is already connected",
894: "Socket is not connected", "Can't send after socket shutdown", "Too many references: can't splice",
895: "Connection timed out", "Connection refused", "Too many levels of symbolic links",
896: "File name too long", "Host is down", "No route to host", "Directory not empty",
897: "Too many processes", "Too many users", "Disc quota exceeded", "Stale NFS file handle",
898: "Too many levels of remote in path", "RPC struct is bad", "RPC version wrong",
899: "RPC prog. not avail", "Program version wrong", "Bad procedure for program", "No locks available",
900: "Function not implemented", "Inappropriate file type or format", "PError 0",
901: "No error", "Unknown host", "Host name lookup failure", "Unknown server error",
902: "No address associated with name"};
903:
904: uae_u32 errnotextptrs[sizeof (errortexts) / sizeof (*errortexts)];
905:
906: #define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */
907: #define TAG_IGNORE (1L) /* ignore this item, not end of array */
908: #define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems */
909: #define TAG_SKIP (3L) /* skip this and the next ti_Data items */
910: #define TAG_USER ((uae_u32)(1L<<31))
911:
912: #define SBTF_VAL 0x0000
913: #define SBTF_REF 0x8000
914: #define SBTB_CODE 1
915: #define SBTS_CODE 0x3FFF
916: #define SBTM_CODE(tag) ((((UWORD)(tag))>>SBTB_CODE) & SBTS_CODE)
917: #define SBTF_GET 0x0
918: #define SBTF_SET 0x1
919: #define SBTM_GETREF(code) \
920: (TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE))
921: #define SBTM_GETVAL(code) (TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE))
922: #define SBTM_SETREF(code) \
923: (TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET)
924: #define SBTM_SETVAL(code) \
925: (TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET)
926: #define SBTC_BREAKMASK 1
927: #define SBTC_SIGIOMASK 2
928: #define SBTC_SIGURGMASK 3
929: #define SBTC_SIGEVENTMASK 4
930: #define SBTC_ERRNO 6
931: #define SBTC_HERRNO 7
932: #define SBTC_DTABLESIZE 8
933: #define SBTC_FDCALLBACK 9
934: #define SBTC_LOGSTAT 10
935: #define SBTC_LOGTAGPTR 11
936: #define SBTC_LOGFACILITY 12
937: #define SBTC_LOGMASK 13
938: #define SBTC_ERRNOSTRPTR 14 /* <sys/errno.h> */
939: #define SBTC_HERRNOSTRPTR 15 /* <netdb.h> */
940: #define SBTC_IOERRNOSTRPTR 16 /* <exec/errors.h> */
941: #define SBTC_S2ERRNOSTRPTR 17 /* <devices/sbna2.h> */
942: #define SBTC_S2WERRNOSTRPTR 18 /* <devices/sbna2.h> */
943: #define SBTC_ERRNOBYTEPTR 21
944: #define SBTC_ERRNOWORDPTR 22
945: #define SBTC_ERRNOLONGPTR 24
946: #define SBTC_HERRNOLONGPTR 25
947: #define SBTC_RELEASESTRPTR 29
948:
949: static void tagcopy (uae_u32 currtag, uae_u32 currval, uae_u32 tagptr, uae_u32 * ptr)
950: {
951: switch (currtag & 0x8001) {
952: case 0x0000: /* SBTM_GETVAL */
953:
954: put_long (tagptr + 4, *ptr);
955: break;
956: case 0x8000: /* SBTM_GETREF */
957:
958: put_long (currval, *ptr);
959: break;
960: case 0x0001: /* SBTM_SETVAL */
961:
962: *ptr = currval;
963: break;
964: default: /* SBTM_SETREF */
965:
966: *ptr = get_long (currval);
967: }
968: }
969:
970: static uae_u32 bsdsocklib_SocketBaseTagList (void)
971: {
972: SB = SOCKETBASE;
973: uae_u32 tagptr = m68k_areg (regs, 0);
974: uae_u32 tagsprocessed = 1;
975: uae_u32 currtag;
976: uae_u32 currval;
977:
978: TRACE (("SocketBaseTagList("));
979:
980: for (;;) {
981: currtag = get_long (tagptr);
982: currval = get_long (tagptr + 4);
983: tagsprocessed++;
984:
985: switch (currtag) {
986: case TAG_DONE:
987: TRACE (("TAG_DONE"));
988: tagsprocessed = 0;
989: goto done;
990: case TAG_IGNORE:
991: TRACE (("TAG_IGNORE"));
992: break;
993: case TAG_MORE:
994: TRACE (("TAG_MORE(0x%lx)", currval));
995: tagptr = currval;
996: break;
997: case TAG_SKIP:
998: TRACE (("TAG_SKIP(%d)", currval));
999: tagptr += currval * 8;
1000: break;
1001:
1002: default:
1003: if (currtag & TAG_USER) {
1004: TRACE (("SBTM_"));
1005: TRACE ((currtag & 0x0001 ? "SET" : "GET"));
1006: TRACE ((currtag & 0x8000 ? "REF(" : "VAL("));
1007:
1008: switch ((currtag >> 1) & SBTS_CODE) {
1009: case SBTC_BREAKMASK:
1010: TRACE (("SBTC_BREAKMASK),0x%lx", currval));
1011: tagcopy (currtag, currval, tagptr, &sb->eintrsigs);
1012: break;
1013: case SBTC_SIGEVENTMASK:
1014: TRACE (("SBTC_SIGEVENTMASK),0x%lx", currval));
1015: tagcopy (currtag, currval, tagptr, &sb->eventsigs);
1016: break;
1017: case SBTC_ERRNO:
1018: TRACE (("SBTC_ERRNO),%d", currval));
1019: tagcopy (currtag, currval, tagptr, &sb->sb_errno);
1020: break;
1021: case SBTC_HERRNO:
1022: TRACE (("SBTC_HERRNO),%d", currval));
1023: tagcopy (currtag, currval, tagptr, &sb->sb_herrno);
1024: break;
1025: case SBTC_ERRNOSTRPTR:
1026: if (currtag & 1) {
1027: TRACE (("ERRNOSTRPTR),invalid"));
1028: } else {
1029: TRACE (("ERRNOSTRPTR),%d", currval));
1030: put_long (tagptr + 4, errnotextptrs[currval]);
1031: }
1032: break;
1033: case SBTC_HERRNOSTRPTR:
1034: if (currtag & 1) {
1035: TRACE (("HERRNOSTRPTR),invalid"));
1036: } else {
1037: TRACE (("HERRNOSTRPTR),%d", currval));
1038: put_long (tagptr + 4, errnotextptrs[currval + sizeof (errortexts) / sizeof (*errortexts) - 6]);
1039: }
1040: break;
1041: case SBTC_ERRNOBYTEPTR:
1042: TRACE (("SBTC_ERRNOBYTEPTR),0x%lx", currval));
1043: tagcopy (currtag, currval, tagptr, &sb->errnoptr);
1044: sb->errnosize = 1;
1045: break;
1046: case SBTC_ERRNOWORDPTR:
1047: TRACE (("SBTC_ERRNOWORDPTR),0x%lx", currval));
1048: tagcopy (currtag, currval, tagptr, &sb->errnoptr);
1049: sb->errnosize = 2;
1050: break;
1051: case SBTC_ERRNOLONGPTR:
1052: TRACE (("SBTC_ERRNOLONGPTR),0x%lx", currval));
1053: tagcopy (currtag, currval, tagptr, &sb->errnoptr);
1054: sb->errnosize = 4;
1055: break;
1056: case SBTC_HERRNOLONGPTR:
1057: TRACE (("SBTC_HERRNOLONGPTR),0x%lx", currval));
1058: tagcopy (currtag, currval, tagptr, &sb->herrnoptr);
1059: sb->herrnosize = 4;
1060: break;
1061: default:
1062: write_log ("bsdsocket: WARNING: Unsupported tag type (%x) in SocketBaseTagList()\n", currtag);
1063: }
1064: } else {
1065: TRACE (("TAG_UNKNOWN(0x%x)", currtag));
1066: }
1067: }
1068:
1069: TRACE ((","));
1070: tagptr += 8;
1071: }
1072:
1073: done:
1074: TRACE ((") -> %d\n", tagsprocessed));
1075:
1076: return tagsprocessed;
1077: }
1078:
1079: static uae_u32 bsdsocklib_GetSocketEvents (void)
1080: {
1081: SB = SOCKETBASE;
1082: int i;
1083: int flags;
1084: uae_u32 ptr = m68k_areg (regs, 0);
1085:
1086: TRACE (("GetSocketEvents(0x%x) -> ", ptr));
1087:
1088: for (i = sb->dtablesize; i--; sb->eventindex++) {
1089: if (sb->eventindex >= sb->dtablesize)
1090: sb->eventindex = 0;
1091:
1092: if (sb->mtable[sb->eventindex]) {
1093: flags = sb->ftable[sb->eventindex] & SET_ALL;
1094:
1095: if (flags) {
1096: sb->ftable[sb->eventindex] &= ~SET_ALL;
1097: put_long (m68k_areg (regs, 0), flags >> 8);
1098: TRACE (("%d (0x%x)\n", sb->eventindex + 1, flags >> 8));
1099: return sb->eventindex + 1;
1100: }
1101: }
1102: }
1103:
1104: TRACE (("-1\n"));
1105: return -1;
1106: }
1107:
1108: static uae_u32 bsdsocklib_getdtablesize (void)
1109: {
1110: return get_socketbase ()->dtablesize;
1111: }
1112:
1113: static uae_u32 bsdsocklib_null (void)
1114: {
1115: return 0;
1116: }
1117:
1118: extern uae_u32 sockfuncvecs[];
1119:
1120: static uae_u32 bsdsocklib_init (void)
1121: {
1122: uae_u32 tmp1;
1123: int i;
1124: write_log ("Creating UAE bsdsocket.library 4.1\n");
1125: if (SockLibBase)
1126: bsdlib_reset ();
1127:
1128: m68k_areg (regs, 0) = functable;
1129: m68k_areg (regs, 1) = datatable;
1130: m68k_areg (regs, 2) = 0;
1131: m68k_dreg (regs, 0) = LIBRARY_SIZEOF;
1132: m68k_dreg (regs, 1) = 0;
1133: tmp1 = CallLib (m68k_areg (regs, 6), -0x54);
1134:
1135: if (!tmp1) {
1136: write_log ("bsdoscket: FATAL: Cannot create bsdsocket.library!\n");
1137: return 0;
1138: }
1139: m68k_areg (regs, 1) = tmp1;
1140: CallLib (m68k_areg (regs, 6), -0x18c);
1141: SockLibBase = tmp1;
1142: #if 0
1143: m68k_areg (regs, 1) = ds ("dos.library");
1144: m68k_dreg (regs, 0) = 0;
1145: dosbase = CallLib (m68k_areg (regs, 6), -552);
1146: printf ("%08lx\n", dosbase);
1147: #endif
1148:
1149: /* Install error strings in Amiga memory */
1150: for (tmp1 = i = sizeof (errortexts) / sizeof (*errortexts); i--;)
1151: tmp1 += strlen (errortexts[i]);
1152:
1153: m68k_dreg (regs, 0) = tmp1;
1154: m68k_dreg (regs, 1) = 0;
1155: tmp1 = CallLib (get_long (4), -0xC6);
1156:
1157: if (!tmp1) {
1158: write_log ("bsdsocket: FATAL: Ran out of memory while creating bsdsocket.library!\n");
1159: return 0;
1160: }
1161: for (i = 0; i < (int) (sizeof (errortexts) / sizeof (*errortexts)); i++)
1162: errnotextptrs[i] = addstr (&tmp1, errortexts[i]);
1163:
1164: /* @@@ someone please implement a proper interrupt handler setup here :) */
1165: tmp1 = here ();
1166: calltrap (deftrap2 (bsdsock_int_handler, TRAPFLAG_EXTRA_STACK | TRAPFLAG_NO_RETVAL, ""));
1167: dw (0x4ef9);
1168: dl (get_long (regs.vbr + 0x78));
1169: put_long (regs.vbr + 0x78, tmp1);
1170:
1171: m68k_dreg (regs, 0) = 1;
1172: return 0;
1173: }
1174:
1175: void bsdlib_reset (void)
1176: {
1177: SB, *nsb;
1178: int i;
1179:
1180: SockLibBase = 0;
1181:
1182: for (sb = socketbases; sb; sb = nsb) {
1183: nsb = sb->next;
1184:
1185: host_sbcleanup (sb);
1186:
1187: free (sb->dtable);
1188: free (sb->ftable);
1189:
1190: free (sb);
1191: }
1192:
1193: socketbases = NULL;
1194: sbsigqueue = NULL;
1195:
1196: for (i = 0; i < SOCKPOOLSIZE; i++) {
1197: if (sockpoolids[i] != UNIQUE_ID) {
1198: sockpoolids[i] = UNIQUE_ID;
1199: host_closesocketquick (sockpoolsocks[i]);
1200: }
1201: }
1202:
1203: host_sbreset ();
1204: }
1205:
1206: uae_u32 (*sockfuncs[])(void) = {
1207: bsdsocklib_init, bsdsocklib_Open, bsdsocklib_Close, bsdsocklib_Expunge,
1208: bsdsocklib_socket, bsdsocklib_bind, bsdsocklib_listen, bsdsocklib_accept,
1209: bsdsocklib_connect, bsdsocklib_sendto, bsdsocklib_send, bsdsocklib_recvfrom, bsdsocklib_recv,
1210: bsdsocklib_shutdown, bsdsocklib_setsockopt, bsdsocklib_getsockopt, bsdsocklib_getsockname,
1211: bsdsocklib_getpeername, bsdsocklib_IoctlSocket, bsdsocklib_CloseSocket, bsdsocklib_WaitSelect,
1212: bsdsocklib_SetSocketSignals, bsdsocklib_SetDTableSize, bsdsocklib_ObtainSocket, bsdsocklib_ReleaseSocket,
1213: bsdsocklib_ReleaseCopyOfSocket, bsdsocklib_Errno, bsdsocklib_SetErrnoPtr, bsdsocklib_Inet_NtoA,
1214: bsdsocklib_inet_addr, bsdsocklib_Inet_LnaOf, bsdsocklib_Inet_NetOf, bsdsocklib_Inet_MakeAddr,
1215: bsdsocklib_inet_network, bsdsocklib_gethostbyname, bsdsocklib_gethostbyaddr, bsdsocklib_getnetbyname,
1216: bsdsocklib_getnetbyaddr, bsdsocklib_getservbyname, bsdsocklib_getservbyport, bsdsocklib_getprotobyname,
1217: bsdsocklib_getprotobynumber, bsdsocklib_vsyslog, bsdsocklib_Dup2Socket, bsdsocklib_sendmsg,
1218: bsdsocklib_recvmsg, bsdsocklib_gethostname, bsdsocklib_gethostid, bsdsocklib_SocketBaseTagList,
1219: bsdsocklib_GetSocketEvents
1220: };
1221:
1222: uae_u32 sockfuncvecs[sizeof (sockfuncs) / sizeof (*sockfuncs)];
1223:
1224: void bsdlib_install (void)
1225: {
1226: uae_u32 resname, resid;
1227: uae_u32 begin, end, inittable;
1228: uae_u32 func_place, data_place, init_place;
1229: int i;
1230:
1231: if (!init_socket_layer ())
1232: return;
1233:
1234: memset (sockpoolids, UNIQUE_ID, sizeof (sockpoolids));
1235:
1236: resname = ds ("bsdsocket.library");
1237: resid = ds ("UAE bsdsocket.library 4.1");
1238:
1239: begin = here ();
1240: dw (0x4AFC); /* RT_MATCHWORD */
1241: dl (begin); /* RT_MATCHTAG */
1242: dl (0); /* RT_ENDSKIP */
1243: dw (0x8004); /* RTF_AUTOINIT, RT_VERSION */
1244: dw (0x0970); /* NT_LIBRARY, RT_PRI */
1245: dl (resname); /* RT_NAME */
1246: dl (resid); /* RT_IDSTRING */
1247: dl (here () + 4); /* RT_INIT */
1248: dl (512);
1249: func_place = here ();
1250: dl (0);
1251: data_place = here ();
1252: dl (0);
1253: init_place = here ();
1254: dl (0);
1255:
1256: for (i = 0; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++) {
1257: sockfuncvecs[i] = here ();
1258: calltrap (deftrap2 (sockfuncs[i], TRAPFLAG_EXTRA_STACK, ""));
1259: dw (RTS);
1260: }
1261:
1262: /* FuncTable */
1263: functable = here ();
1264: for (i = 1; i < 4; i++)
1265: dl (sockfuncvecs[i]); /* Open / Close / Expunge */
1266: dl (EXPANSION_nullfunc); /* Null */
1267: for (i = 4; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++)
1268: dl (sockfuncvecs[i]);
1269: dl (0xFFFFFFFF); /* end of table */
1270:
1271: /* DataTable */
1272: datatable = here ();
1273: dw (0xE000); /* INITBYTE */
1274: dw (0x0008); /* LN_TYPE */
1275: dw (0x0900); /* NT_LIBRARY */
1276: dw (0xC000); /* INITLONG */
1277: dw (0x000A); /* LN_NAME */
1278: dl (resname);
1279: dw (0xE000); /* INITBYTE */
1280: dw (0x000E); /* LIB_FLAGS */
1281: dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
1282: dw (0xD000); /* INITWORD */
1283: dw (0x0014); /* LIB_VERSION */
1284: dw (0x0004);
1285: dw (0xD000);
1286: dw (0x0016); /* LIB_REVISION */
1287: dw (0x0001);
1288: dw (0xC000);
1289: dw (0x0018); /* LIB_IDSTRING */
1290: dl (resid);
1291: dl (0x00000000); /* end of table */
1292:
1293: end = here ();
1294:
1295: org (begin + 6); /* Load END value */
1296: dl (end);
1297:
1298: org (data_place);
1299: dl (datatable);
1300:
1301: org (func_place);
1302: dl (functable);
1303:
1304: org (init_place);
1305: dl (*sockfuncvecs);
1306:
1307: org (end);
1308: }
1309:
1310: #else /* ! BSDSOCKET_SUPPORTED */
1311:
1312: void bsdlib_reset (void)
1313: {
1314: }
1315:
1316: #endif /* ! BSDSOCKET_SUPPORTED */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.