"Fossies" - the Fresh Open Source Software Archive

Member "uae-0.8.29/src/bsdsocket.c" (15 Aug 2007, 39813 Bytes) of archive /linux/misc/old/uae-0.8.29.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "bsdsocket.c" see the Fossies "Dox" file reference documentation.

    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"
   22 #include "traps.h"
   23 #include "threaddep/thread.h"
   24 #include "bsdsocket.h"
   25 
   26 #ifdef BSDSOCKET
   27 
   28 #ifdef WIN32
   29 # include <winsock2.h>
   30 #endif
   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 
   44 uae_u32 addstr (uae_u32 *dst, const char *src)
   45 {
   46     uae_u32 res = *dst;
   47     int len;
   48 
   49     len = strlen (src) + 1;
   50 
   51     strcpyha_safe (*dst, src);
   52     (*dst) += len;
   53 
   54     return res;
   55 }
   56 
   57 uae_u32 addmem (uae_u32 *dst, const char *src, int len)
   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 */
   71 static uae_u32 gettask (TrapContext *context)
   72 {
   73     uae_u32 currtask, a1 = m68k_areg (regs, 1);
   74 
   75     m68k_areg (regs, 1) = 0;
   76     currtask = CallLib (context, get_long (4), -0x126); /* FindTask */
   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 */
   85 void bsdsocklib_seterrno (SB, int sb_errno)
   86 {
   87     sb->sb_errno = sb_errno;
   88 
   89     if (sb->sb_errno >= 1001 && sb->sb_errno <= 1005)
   90     bsdsocklib_setherrno (sb, sb->sb_errno - 1000);
   91 
   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 
  106 void bsdsocklib_setherrno (SB, int sb_herrno)
  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 
  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 
  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;
  169         return i + 1;
  170     }
  171     /* descriptor table full. */
  172     bsdsocklib_seterrno (sb, 24);       /* EMFILE */
  173 
  174     return -1;
  175 }
  176 
  177 int getsock (SB, int sd)
  178 {
  179     if ((unsigned int) (sd - 1) >= (unsigned int) sb->dtablesize) {
  180     TRACE (("Invalid Socket Descriptor (%d, %d)\n", sd - 1, sb->dtablesize));
  181     bsdsocklib_seterrno (sb, 38);   /* ENOTSOCK */
  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 
  218 static uae_u32 bsdsock_int_handler (TrapContext *context)
  219 {
  220     SB;
  221 
  222     locksigqueue ();
  223     if (sbsigqueue != NULL) {
  224     for (sb = sbsigqueue; sb; sb = sb->nextsig) {
  225         if (sb->dosignal == 1) {
  226         struct regstruct sbved_regs = regs;
  227 
  228         m68k_areg (regs, 1) = sb->ownertask;
  229         m68k_dreg (regs, 0) = sb->sigstosend;
  230         CallLib (context, get_long (4), -0x144);        /* Signal() */
  231 
  232         regs = sbved_regs;
  233 
  234         sb->sigstosend = 0;
  235         }
  236         sb->dosignal = 0;
  237     }
  238 
  239     sbsigqueue = NULL;
  240     }
  241     unlocksigqueue ();
  242 
  243     return 0;
  244 }
  245 
  246 void waitsig (TrapContext *context, SB)
  247 {
  248     long sigs;
  249     m68k_dreg (regs, 0) = (((uae_u32) 1) << sb->signal) | sb->eintrsigs;
  250 
  251     if ((sigs = CallLib (context, get_long (4), -0x13e)) & sb->eintrsigs) {
  252     sockabort (sb);
  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() */
  259 
  260     sb->eintr = 1;
  261     } else
  262     sb->eintr = 0;
  263 }
  264 
  265 void cancelsig (TrapContext *context, 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 (context, get_long (4), -0x132);    /* SetSignal() */
  275 
  276 }
  277 
  278 /* Allocate and initialize per-task state structure */
  279 static struct socketbase *alloc_socketbase (TrapContext *context)
  280 {
  281     struct socketbase *sb;
  282     int i;
  283 
  284     if ((sb = calloc (sizeof (struct socketbase), 1)) != NULL) {
  285     sb->ownertask = gettask (context);
  286 
  287     m68k_dreg (regs, 0) = -1;
  288     sb->signal = CallLib (context, 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 (context, sb)) {
  309         /* @@@ free everything   */
  310     }
  311 
  312     locksigqueue ();
  313 
  314     if (socketbases)
  315         sb->next = socketbases;
  316     socketbases = sb;
  317 
  318     unlocksigqueue ();
  319 
  320     return sb;
  321     }
  322     return NULL;
  323 }
  324 
  325 STATIC_INLINE struct socketbase *get_socketbase (TrapContext *context)
  326 {
  327     return get_pointer (m68k_areg (regs, 6) + offsetof (struct UAEBSDBase, sb));
  328 }
  329 
  330 static void free_socketbase (TrapContext *context)
  331 {
  332     struct socketbase *sb, *nsb;
  333 
  334     if ((sb = get_socketbase (context)) != NULL) {
  335     m68k_dreg (regs, 0) = sb->signal;
  336     CallLib (context, get_long (4), -0x150);        /* FreeSignal */
  337 
  338     if (sb->hostent) {
  339         m68k_areg (regs, 1) = sb->hostent;
  340         m68k_dreg (regs, 0) = sb->hostentsize;
  341         CallLib (context, get_long (4), -0xD2); /* FreeMem */
  342     }
  343 
  344     if (sb->protoent) {
  345         m68k_areg (regs, 1) = sb->protoent;
  346         m68k_dreg (regs, 0) = sb->protoentsize;
  347         CallLib (context, get_long (4), -0xD2); /* FreeMem */
  348     }
  349 
  350     if (sb->servent) {
  351         m68k_areg (regs, 1) = sb->servent;
  352         m68k_dreg (regs, 0) = sb->serventsize;
  353         CallLib (context, get_long (4), -0xD2); /* FreeMem */
  354     }
  355 
  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 
  391 static uae_u32 bsdsocklib_Expunge (TrapContext *context)
  392 {
  393     TRACE (("Expunge() -> [ignored]\n"));
  394     return 0;
  395 }
  396 
  397 static uae_u32 functable, datatable, inittable;
  398 
  399 
  400 static uae_u32 bsdsocklib_Open (TrapContext *context)
  401 {
  402     uae_u32 result = 0;
  403     int opencount;
  404     unsigned int i;
  405     struct socketbase *sb;
  406     uae_u32 p[sizeof (void*) / 4];
  407 
  408     TRACE (("OpenLibrary() -> "));
  409 
  410     if ((sb = alloc_socketbase (context)) != NULL) {
  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;
  418     result = CallLib (context, get_long (4), -0x54);
  419 
  420     put_pointer (result + offsetof (struct UAEBSDBase, sb), sb);
  421 
  422     TRACE (("%0lx [%d]\n", result, opencount));
  423     } else {
  424     TRACE (("failed (out of memory)\n"));
  425     }
  426 
  427     return result;
  428 }
  429 
  430 static uae_u32 bsdsocklib_Close (TrapContext *context)
  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 (context);
  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 (context, 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 (TrapContext *context)
  452 {
  453     struct socketbase *sb = get_socketbase (context);
  454     return host_socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1),
  455             m68k_dreg (regs, 2));
  456 }
  457 
  458 /* bind(s, name, namelen)(d0/a0/d1) */
  459 static uae_u32 bsdsocklib_bind (TrapContext *context)
  460 {
  461     struct socketbase *sb = get_socketbase (context);
  462     return host_bind (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0),
  463               m68k_dreg (regs, 1));
  464 }
  465 
  466 /* listen(s, backlog)(d0/d1) */
  467 static uae_u32 bsdsocklib_listen (TrapContext *context)
  468 {
  469     struct socketbase *sb = get_socketbase (context);
  470     return host_listen (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
  471 }
  472 
  473 /* accept(s, addr, addrlen)(d0/a0/a1) */
  474 static uae_u32 bsdsocklib_accept (TrapContext *context)
  475 {
  476     struct socketbase *sb = get_socketbase (context);
  477     host_accept (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
  478     return sb->resultval;
  479 }
  480 
  481 /* connect(s, name, namelen)(d0/a0/d1) */
  482 static uae_u32 bsdsocklib_connect (TrapContext *context)
  483 {
  484     struct socketbase *sb = get_socketbase (context);
  485     host_connect (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1));
  486     return sb->sb_errno ? -1 : 0;
  487 }
  488 
  489 /* sendto(s, msg, len, flags, to, tolen)(d0/a0/d1/d2/a1/d3) */
  490 static uae_u32 bsdsocklib_sendto (TrapContext *context)
  491 {
  492     struct socketbase *sb = get_socketbase (context);
  493     host_sendto (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
  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) */
  499 static uae_u32 bsdsocklib_send (TrapContext *context)
  500 {
  501     struct socketbase *sb = get_socketbase (context);
  502     host_sendto (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
  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) */
  508 static uae_u32 bsdsocklib_recvfrom (TrapContext *context)
  509 {
  510     struct socketbase *sb = get_socketbase (context);
  511     host_recvfrom (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
  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) */
  517 static uae_u32 bsdsocklib_recv (TrapContext *context)
  518 {
  519     struct socketbase *sb = get_socketbase (context);
  520     host_recvfrom (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
  521            m68k_dreg (regs, 2), 0, 0);
  522     return sb->resultval;
  523 }
  524 
  525 /* shutdown(s, how)(d0/d1) */
  526 static uae_u32 bsdsocklib_shutdown (TrapContext *context)
  527 {
  528     struct socketbase *sb = get_socketbase (context);
  529     return host_shutdown (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
  530 }
  531 
  532 /* setsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/d3) */
  533 static uae_u32 bsdsocklib_setsockopt (TrapContext *context)
  534 {
  535     struct socketbase *sb = get_socketbase (context);
  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) */
  542 static uae_u32 bsdsocklib_getsockopt (TrapContext *context)
  543 {
  544     struct socketbase *sb = get_socketbase (context);
  545     return host_getsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
  546                 m68k_areg (regs, 0), m68k_areg (regs, 1));
  547 }
  548 
  549 /* getsockname(s, hostname, namelen)(d0/a0/a1) */
  550 static uae_u32 bsdsocklib_getsockname (TrapContext *context)
  551 {
  552     struct socketbase *sb = get_socketbase (context);
  553     return host_getsockname (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
  554 }
  555 
  556 /* getpeername(s, hostname, namelen)(d0/a0/a1) */
  557 static uae_u32 bsdsocklib_getpeername (TrapContext *context)
  558 {
  559     struct socketbase *sb = get_socketbase (context);
  560     return host_getpeername (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
  561 }
  562 
  563 /* *------ generic system calls related to sockets */
  564 /* IoctlSocket(d, request, argp)(d0/d1/a0) */
  565 static uae_u32 bsdsocklib_IoctlSocket (TrapContext *context)
  566 {
  567     struct socketbase *sb = get_socketbase (context);
  568     return host_IoctlSocket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_areg (regs, 0));
  569 }
  570 
  571 /* *------ AmiTCP/IP specific stuff */
  572 /* CloseSocket(d)(d0) */
  573 static uae_u32 bsdsocklib_CloseSocket (TrapContext *context)
  574 {
  575     struct socketbase *sb = get_socketbase (context);
  576     return host_CloseSocket (sb, m68k_dreg (regs, 0));
  577 }
  578 
  579 /* WaitSelect(nfds, readfds, writefds, execptfds, timeout, maskp)(d0/a0/a1/a2/a3/d1) */
  580 static uae_u32 bsdsocklib_WaitSelect (TrapContext *context)
  581 {
  582     struct socketbase *sb = get_socketbase (context);
  583     host_WaitSelect (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1),
  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) */
  589 static uae_u32 bsdsocklib_SetSocketSignals (TrapContext *context)
  590 {
  591     struct socketbase *sb = get_socketbase (context);
  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) */
  601 static uae_u32 bsdsocklib_SetDTableSize (SB, int newSize)
  602 {
  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;
  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) */
  647 static uae_u32 bsdsocklib_ObtainSocket (TrapContext *context)
  648 {
  649     struct socketbase *sb = get_socketbase (context);
  650     int sd;
  651     long id;
  652     int s;
  653     int i;
  654 
  655     id = m68k_dreg (regs, 0);
  656 
  657     TRACE (("ObtainSocket(%d,%d,%d,%d) -> ", id, m68k_dreg (regs, 1), m68k_dreg (regs, 2), m68k_dreg (regs, 3)));
  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 
  669     TRACE (("%d, %d\n", s, sd));
  670 
  671     if (sd != -1) {
  672     sb->ftable[sd - 1] = sockpoolflags[i];
  673     sockpoolids[i] = UNIQUE_ID;
  674     return sd-1;
  675     }
  676 
  677     return -1;
  678 }
  679 
  680 /* ReleaseSocket(fd, id)(d0/d1) */
  681 static uae_u32 bsdsocklib_ReleaseSocket (TrapContext *context)
  682 {
  683     struct socketbase *sb = get_socketbase (context);
  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 
  693     sd++;
  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 
  734     TRACE (("id %d s %d\n", id,s));
  735     } else {
  736     TRACE (("[invalid socket descriptor]\n"));
  737     return -1;
  738     }
  739 
  740     return id;
  741 }
  742 
  743 /* ReleaseCopyOfSocket(fd, id)(d0/d1) */
  744 static uae_u32 bsdsocklib_ReleaseCopyOfSocket (TrapContext *context)
  745 {
  746     write_log ("bsdsocket: UNSUPPORTED: ReleaseCopyOfSocket()\n");
  747     return 0;
  748 }
  749 
  750 /* Errno()() */
  751 static uae_u32 bsdsocklib_Errno (TrapContext *context)
  752 {
  753     struct socketbase *sb = get_socketbase (context);
  754     TRACE (("Errno() -> %d\n", sb->sb_errno));
  755     return sb->sb_errno;
  756 }
  757 
  758 /* SetErrnoPtr(errno_p, size)(a0/d0) */
  759 static uae_u32 bsdsocklib_SetErrnoPtr (TrapContext *context)
  760 {
  761     struct socketbase *sb = get_socketbase (context);
  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     }
  772     bsdsocklib_seterrno (sb, 22);       /* EINVAL */
  773 
  774     return -1;
  775 }
  776 
  777 /* *------ inet library calls related to inet address manipulation */
  778 /* Inet_NtoA(in)(d0) */
  779 static uae_u32 bsdsocklib_Inet_NtoA (TrapContext *context)
  780 {
  781     struct socketbase *sb = get_socketbase (context);
  782     return host_Inet_NtoA (context, sb, m68k_dreg (regs, 0));
  783 }
  784 
  785 /* inet_addr(cp)(a0) */
  786 static uae_u32 bsdsocklib_inet_addr (TrapContext *context)
  787 {
  788     return host_inet_addr (m68k_areg (regs, 0));
  789 }
  790 
  791 /* Inet_LnaOf(in)(d0) */
  792 static uae_u32 bsdsocklib_Inet_LnaOf (TrapContext *context)
  793 {
  794     write_log ("bsdsocket: UNSUPPORTED: Inet_LnaOf()\n");
  795     return 0;
  796 }
  797 
  798 /* Inet_NetOf(in)(d0) */
  799 static uae_u32 bsdsocklib_Inet_NetOf (TrapContext *context)
  800 {
  801     write_log ("bsdsocket: UNSUPPORTED: Inet_NetOf()\n");
  802     return 0;
  803 }
  804 
  805 /* Inet_MakeAddr(net, host)(d0/d1) */
  806 static uae_u32 bsdsocklib_Inet_MakeAddr (TrapContext *context)
  807 {
  808     write_log ("bsdsocket: UNSUPPORTED: Inet_MakeAddr()\n");
  809     return 0;
  810 }
  811 
  812 /* inet_network(cp)(a0) */
  813 static uae_u32 bsdsocklib_inet_network (TrapContext *context)
  814 {
  815     return host_inet_addr (m68k_areg (regs, 0));
  816 }
  817 
  818 /* *------ gethostbyname etc */
  819 /* gethostbyname(name)(a0) */
  820 static uae_u32 bsdsocklib_gethostbyname (TrapContext *context)
  821 {
  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;
  825 }
  826 
  827 /* gethostbyaddr(addr, len, type)(a0/d0/d1) */
  828 static uae_u32 bsdsocklib_gethostbyaddr (TrapContext *context)
  829 {
  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;
  833 }
  834 
  835 /* getnetbyname(name)(a0) */
  836 static uae_u32 bsdsocklib_getnetbyname (TrapContext *context)
  837 {
  838     write_log ("bsdsocket: UNSUPPORTED: getnetbyname()\n");
  839     return 0;
  840 }
  841 
  842 /* getnetbyaddr(net, type)(d0/d1) */
  843 static uae_u32 bsdsocklib_getnetbyaddr (TrapContext *context)
  844 {
  845     write_log ("bsdsocket: UNSUPPORTED: getnetbyaddr()\n");
  846     return 0;
  847 }
  848 
  849 /* getservbyname(name, proto)(a0/a1) */
  850 static uae_u32 bsdsocklib_getservbyname (TrapContext *context)
  851 {
  852     struct socketbase *sb = get_socketbase (context);
  853     host_getservbynameport (context, sb, m68k_areg (regs, 0), m68k_areg (regs, 1), 0);
  854     return sb->sb_errno ? 0 : sb->servent;
  855 }
  856 
  857 /* getservbyport(port, proto)(d0/a0) */
  858 static uae_u32 bsdsocklib_getservbyport (TrapContext *context)
  859 {
  860     struct socketbase *sb = get_socketbase (context);
  861     host_getservbynameport (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), 1);
  862     return sb->sb_errno ? 0 : sb->servent;
  863 }
  864 
  865 /* getprotobyname(name)(a0) */
  866 static uae_u32 bsdsocklib_getprotobyname (TrapContext *context)
  867 {
  868     struct socketbase *sb = get_socketbase (context);
  869     host_getprotobyname (context, sb, m68k_areg (regs, 0));
  870     return sb->sb_errno ? 0 : sb->protoent;
  871 }
  872 
  873 /* getprotobynumber(proto)(d0)  */
  874 static uae_u32 bsdsocklib_getprotobynumber (TrapContext *context)
  875 {
  876     struct socketbase *sb = get_socketbase (context);
  877     host_getprotobynumber (context, sb, m68k_dreg (regs, 0));
  878     return sb->sb_errno ? 0 : sb->protoent;
  879 }
  880 
  881 /* *------ syslog functions */
  882 /* Syslog(level, format, ap)(d0/a0/a1) */
  883 static uae_u32 bsdsocklib_vsyslog (TrapContext *context)
  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) */
  891 static uae_u32 bsdsocklib_Dup2Socket (TrapContext *context)
  892 {
  893     struct socketbase *sb = get_socketbase (context);
  894     return host_dup2socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
  895 }
  896 
  897 static uae_u32 bsdsocklib_sendmsg (TrapContext *context)
  898 {
  899     write_log ("bsdsocket: UNSUPPORTED: sendmsg()\n");
  900     return 0;
  901 }
  902 
  903 static uae_u32 bsdsocklib_recvmsg (TrapContext *context)
  904 {
  905     write_log ("bsdsocket: UNSUPPORTED: recvmsg()\n");
  906     return 0;
  907 }
  908 
  909 static uae_u32 bsdsocklib_gethostname (TrapContext *context)
  910 {
  911     return host_gethostname (m68k_areg (regs, 0), m68k_dreg (regs, 0));
  912 }
  913 
  914 static uae_u32 bsdsocklib_gethostid (TrapContext *context)
  915 {
  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)));
  917     return 0x7f000001;
  918 }
  919 
  920 const char * const errortexts[] =
  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",
  932  "Message too long", "Protocol wrong type for socket", "Protocol not available",
  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",
  944  "Function not implemented", "Inappropriate file type or format", "PError 0"};
  945 
  946 uae_u32 errnotextptrs[sizeof (errortexts) / sizeof (*errortexts)];
  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 
  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> */
  996 #define SBTC_S2ERRNOSTRPTR  17  /* <devices/sana2.h> */
  997 #define SBTC_S2WERRNOSTRPTR 18  /* <devices/sana2.h> */
  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 
 1025 static uae_u32 bsdsocklib_SocketBaseTagList (TrapContext *context)
 1026 {
 1027     struct socketbase *sb = get_socketbase (context);
 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;
 1072          case SBTC_SIGIOMASK:
 1073             TRACE (("SBTC_SIGEVENTMASK),0x%lx", currval));
 1074             tagcopy (currtag, currval, tagptr, &sb->eventsigs);
 1075             break;
 1076          case SBTC_ERRNO:
 1077             TRACE (("SBTC_ERRNO),%d", currval));
 1078             tagcopy (currtag, currval, tagptr, (uae_u32 *)&sb->sb_errno);
 1079             break;
 1080          case SBTC_HERRNO:
 1081             TRACE (("SBTC_HERRNO),%d", currval));
 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             }
 1091             break;
 1092          case SBTC_ERRNOSTRPTR:
 1093             if (currtag & 1) {
 1094             TRACE (("ERRNOSTRPTR),invalid"));
 1095             } else {
 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);
 1108             }
 1109             break;
 1110          case SBTC_HERRNOSTRPTR:
 1111             if (currtag & 1) {
 1112             TRACE (("HERRNOSTRPTR),invalid"));
 1113             } else {
 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);
 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 
 1166 static uae_u32 bsdsocklib_GetSocketEvents (TrapContext *context)
 1167 {
 1168 #ifdef _WIN32
 1169     struct socketbase *sb = get_socketbase (context);
 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));
 1186         return sb->eventindex; // xxx
 1187         }
 1188     }
 1189     }
 1190 #endif
 1191     TRACE (("-1\n"));
 1192     return -1;
 1193 }
 1194 
 1195 static uae_u32 bsdsocklib_getdtablesize (TrapContext *context)
 1196 {
 1197     return get_socketbase (context)->dtablesize;
 1198 }
 1199 
 1200 static uae_u32 bsdsocklib_null (TrapContext *context)
 1201 {
 1202     return 0;
 1203 }
 1204 
 1205 static uae_u32 bsdsocklib_init (TrapContext *context)
 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;
 1218     tmp1 = CallLib (context, m68k_areg (regs, 6), -0x54);
 1219 
 1220     if (!tmp1) {
 1221     write_log ("bsdoscket: FATAL: Cannot create bsdsocket.library!\n");
 1222     return 0;
 1223     }
 1224     m68k_areg (regs, 1) = tmp1;
 1225     CallLib (context, m68k_areg (regs, 6), -0x18c);
 1226     SockLibBase = tmp1;
 1227 #if 0
 1228     m68k_areg (regs, 1) = ds ("dos.library");
 1229     m68k_dreg (regs, 0) = 0;
 1230     dosbase = CallLib (context, m68k_areg (regs, 6), -552);
 1231     printf ("%08lx\n", dosbase);
 1232 #endif
 1233 
 1234     /* Install error strings in Amiga memory */
 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;
 1244 
 1245     m68k_dreg (regs, 0) = tmp1;
 1246     m68k_dreg (regs, 1) = 0;
 1247     tmp1 = CallLib (context, get_long (4), -0xC6);
 1248 
 1249     if (!tmp1) {
 1250     write_log ("bsdsocket: FATAL: Ran out of memory while creating bsdsocket.library!\n");
 1251     return 0;
 1252     }
 1253     for (i = 0; i < (int) (number_sys_error); i++)
 1254     errnotextptrs[i] = addstr (&tmp1, errortexts[i]);
 1255 
 1256     for (i = 0; i < (int) (number_host_error); i++)
 1257     herrnotextptrs[i] = addstr (&tmp1, herrortexts[i]);
 1258 
 1259     strErrptr = addstr (&tmp1, strErr);
 1260 
 1261     /* @@@ someone please implement a proper interrupt handler setup here :) */
 1262     tmp1 = here ();
 1263     calltrap (deftrap2 (bsdsock_int_handler, TRAPFLAG_EXTRA_STACK | TRAPFLAG_NO_RETVAL, "bsdsock_int_handler"));
 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 
 1277     if (currprefs.socket_emu == 0)
 1278     return;
 1279 
 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 
 1306 static const TrapHandler sockfuncs[] = {
 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,
 1312     bsdsocklib_SetSocketSignals, bsdsocklib_getdtablesize, bsdsocklib_ObtainSocket, bsdsocklib_ReleaseSocket,
 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 
 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)];
 1339 
 1340 void bsdlib_install (void)
 1341 {
 1342     uae_u32 resname, resid;
 1343     uae_u32 begin, end;
 1344     uae_u32 func_place, data_place, init_place;
 1345     int i;
 1346 
 1347     if (currprefs.socket_emu == 0)
 1348     return;
 1349 
 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 ();
 1377     calltrap (deftrap2 (sockfuncs[i], TRAPFLAG_EXTRA_STACK, funcnames[i]));
 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 
 1429 #else /* ! BSDSOCKET */
 1430 
 1431 void bsdlib_install (void)
 1432 {
 1433    return;
 1434 }
 1435 
 1436 void bsdlib_reset (void)
 1437 {
 1438     return;
 1439 }
 1440 
 1441 #endif