Annotation of uae/src/bsdsocket.c, revision 1.1.1.1

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 "readcpu.h"
                     22: #include "newcpu.h"
                     23: #include "autoconf.h"
                     24: #include "bsdsocket.h"
                     25: #include "osdep/exectasks.h"
                     26: 
                     27: #ifdef BSDSOCKET_SUPPORTED
                     28: 
                     29: static uae_u32 SockLibBase;
                     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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.