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

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

unix.superglobalmegacorp.com

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