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

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

unix.superglobalmegacorp.com

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