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