(root)/
gcc-13.2.0/
libgm2/
libm2iso/
wrapsock.c
       1  /* wrapsock.c provides access to socket related system calls.
       2  
       3  Copyright (C) 2008-2022 Free Software Foundation, Inc.
       4  Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
       5  
       6  This file is part of GNU Modula-2.
       7  
       8  GNU Modula-2 is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU General Public License as published by
      10  the Free Software Foundation; either version 3, or (at your option)
      11  any later version.
      12  
      13  GNU Modula-2 is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of
      15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16  General Public License for more details.
      17  
      18  Under Section 7 of GPL version 3, you are granted additional
      19  permissions described in the GCC Runtime Library Exception, version
      20  3.1, as published by the Free Software Foundation.
      21  
      22  You should have received a copy of the GNU General Public License and
      23  a copy of the GCC Runtime Library Exception along with this program;
      24  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      25  <http://www.gnu.org/licenses/>.  */
      26  
      27  #include "config.h"
      28  #include <stdbool.h>
      29  
      30  #define EXPORT(FUNC) m2iso ## _wrapsock_ ## FUNC
      31  #define IMPORT(MODULE,FUNC) m2iso ## _ ## MODULE ## _ ## FUNC
      32  #define M2EXPORT(FUNC) m2iso ## _M2_wrapsock_ ## FUNC
      33  #define M2LIBNAME "m2iso"
      34  
      35  /* This module should be rewritten to use C++.  */
      36  
      37  typedef void (*proc_con) (int, char **, char **);
      38  typedef void (*proc_dep) (void);
      39  
      40  extern void m2iso_M2RTS_RequestDependant (const char *modulename, const char *libname, const char *dependancy);
      41  extern void m2iso_M2RTS_RegisterModule (const char *modulename, const char *libname,
      42                                          proc_con init, proc_con fini, proc_dep dependencies);
      43  
      44  #if defined(HAVE_SYS_TYPES_H)
      45  #include "sys/types.h"
      46  #endif
      47  
      48  #if defined(HAVE_SYS_SOCKET_H)
      49  #include "sys/socket.h"
      50  #endif
      51  
      52  #if defined(HAVE_NETINET_IN_H)
      53  #include "netinet/in.h"
      54  #endif
      55  
      56  #if defined(HAVE_NETDB_H)
      57  #include "netdb.h"
      58  #endif
      59  
      60  #if defined(HAVE_UNISTD_H)
      61  #include "unistd.h"
      62  #endif
      63  
      64  #if defined(HAVE_SIGNAL_H)
      65  #include "signal.h"
      66  #endif
      67  
      68  #if defined(HAVE_SYS_ERRNO_H)
      69  #include "sys/errno.h"
      70  #endif
      71  
      72  #if defined(HAVE_ERRNO_H)
      73  #include "errno.h"
      74  #endif
      75  
      76  #if defined(HAVE_MALLOC_H)
      77  #include "malloc.h"
      78  #endif
      79  
      80  #if defined(HAVE_MALLOC_H)
      81  #include "signal.h"
      82  #endif
      83  
      84  #if defined(HAVE_STRING_H)
      85  #include "string.h"
      86  #endif
      87  
      88  #if defined(HAVE_STDLIB_H)
      89  #include "stdlib.h"
      90  #endif
      91  
      92  #include "ChanConsts.h"
      93  
      94  #define MAXHOSTNAME 1024
      95  #define MAXPBBUF 1024
      96  
      97  #if defined(HAVE_NETINET_IN_H)
      98  
      99  typedef struct
     100  {
     101    char hostname[MAXHOSTNAME];
     102    struct hostent *hp;
     103    struct sockaddr_in sa;
     104    int sockFd;
     105    int portNo;
     106    int hasChar;
     107    char pbChar[MAXPBBUF];
     108  } clientInfo;
     109  
     110  static openResults clientConnect (clientInfo *c);
     111  
     112  /* clientOpen - returns an ISO Modula-2 OpenResult.  It attempts to
     113     connect to: hostname:portNo.  If successful then the data
     114     structure, c, will have its fields initialized.  */
     115  
     116  openResults
     117  EXPORT(clientOpen) (clientInfo *c, char *hostname, unsigned int length,
     118                       int portNo)
     119  {
     120    /* remove SIGPIPE which is raised on the server if the client is killed.  */
     121    signal (SIGPIPE, SIG_IGN);
     122  
     123    c->hp = gethostbyname (hostname);
     124    if (c->hp == NULL)
     125      return noSuchFile;
     126  
     127    memset ((void *)&c->sa, 0, sizeof (c->sa));
     128    c->sa.sin_family = AF_INET;
     129    memcpy ((void *)&c->sa.sin_addr, (void *)c->hp->h_addr, c->hp->h_length);
     130    c->portNo = portNo;
     131    c->sa.sin_port = htons (portNo);
     132    c->hasChar = 0;
     133    /* Open a TCP socket (an Internet stream socket) */
     134  
     135    c->sockFd = socket (c->hp->h_addrtype, SOCK_STREAM, 0);
     136    return clientConnect (c);
     137  }
     138  
     139  /* clientOpenIP - returns an ISO Modula-2 OpenResult.  It attempts to
     140     connect to: ipaddress:portNo.  If successful then the data
     141     structure, c, will have its fields initialized.  */
     142  
     143  openResults
     144  EXPORT(clientOpenIP) (clientInfo *c, unsigned int ip, int portNo)
     145  {
     146    /* remove SIGPIPE which is raised on the server if the client is killed.  */
     147    signal (SIGPIPE, SIG_IGN);
     148  
     149    memset ((void *)&c->sa, 0, sizeof (c->sa));
     150    c->sa.sin_family = AF_INET;
     151    memcpy ((void *)&c->sa.sin_addr, (void *)&ip, sizeof (ip));
     152    c->portNo = portNo;
     153    c->sa.sin_port = htons (portNo);
     154  
     155    /* Open a TCP socket (an Internet stream socket) */
     156  
     157    c->sockFd = socket (PF_INET, SOCK_STREAM, 0);
     158    return clientConnect (c);
     159  }
     160  
     161  /* clientConnect - returns an ISO Modula-2 OpenResult once a connect
     162     has been performed.  If successful the clientInfo will include the
     163     file descriptor ready for read/write operations.  */
     164  
     165  static openResults
     166  clientConnect (clientInfo *c)
     167  {
     168    if (connect (c->sockFd, (struct sockaddr *)&c->sa, sizeof (c->sa)) < 0)
     169      return noSuchFile;
     170  
     171    return opened;
     172  }
     173  
     174  /* getClientPortNo - returns the portNo from structure, c.  */
     175  
     176  int
     177  EXPORT(getClientPortNo) (clientInfo *c)
     178  {
     179    return c->portNo;
     180  }
     181  
     182  /* getClientHostname - fills in the hostname of the server the to
     183     which the client is connecting.  */
     184  
     185  void
     186  EXPORT(getClientHostname) (clientInfo *c, char *hostname, unsigned int high)
     187  {
     188    strncpy (hostname, c->hostname, high + 1);
     189  }
     190  
     191  /* getClientSocketFd - returns the sockFd from structure, c.  */
     192  
     193  int
     194  EXPORT(getClientSocketFd) (clientInfo *c)
     195  {
     196    return c->sockFd;
     197  }
     198  
     199  /* getClientIP - returns the sockFd from structure, s.  */
     200  
     201  unsigned int
     202  EXPORT(getClientIP) (clientInfo *c)
     203  {
     204  #if 0
     205    printf("client ip = %s\n", inet_ntoa (c->sa.sin_addr.s_addr));
     206  #endif
     207    return c->sa.sin_addr.s_addr;
     208  }
     209  
     210  /* getPushBackChar returns true if a pushed back character is
     211     available.  */
     212  
     213  bool
     214  EXPORT(getPushBackChar) (clientInfo *c, char *ch)
     215  {
     216    if (c->hasChar > 0)
     217      {
     218        c->hasChar--;
     219        *ch = c->pbChar[c->hasChar];
     220        return true;
     221      }
     222    return false;
     223  }
     224  
     225  /* setPushBackChar returns true if it is able to push back a
     226     character.  */
     227  
     228  bool
     229  EXPORT(setPushBackChar) (clientInfo *c, char ch)
     230  {
     231    if (c->hasChar == MAXPBBUF)
     232      return false;
     233    c->pbChar[c->hasChar] = ch;
     234    c->hasChar++;
     235    return true;
     236  }
     237  
     238  /* getSizeOfClientInfo - returns the sizeof (opaque data type).  */
     239  
     240  unsigned int
     241  EXPORT(getSizeOfClientInfo) (void)
     242  {
     243    return sizeof (clientInfo);
     244  }
     245  
     246  #endif
     247  
     248  
     249  /* GNU Modula-2 linking hooks.  */
     250  
     251  void
     252  M2EXPORT(init) (int, char **, char **)
     253  {
     254  }
     255  
     256  void
     257  M2EXPORT(fini) (int, char **, char **)
     258  {
     259  }
     260  
     261  void
     262  M2EXPORT(dep) (void)
     263  {
     264  }
     265  
     266  void __attribute__((__constructor__))
     267  M2EXPORT(ctor) (void)
     268  {
     269    m2iso_M2RTS_RegisterModule ("wrapsock", M2LIBNAME,
     270  			      M2EXPORT(init), M2EXPORT(fini),
     271  			      M2EXPORT(dep));
     272  }