Annotation of uae/src/bsdsocket.c, revision 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.