123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633 |
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include "libguile/__scm.h"
- #include "libguile/modules.h"
- #include "libguile/numbers.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- #ifndef PATH_MAX
- #define PATH_MAX 255
- #endif
- #include "win32-socket.h"
- typedef struct
- {
- int error;
- char *str;
- int replace;
- char *replace_str;
- char *correct_str;
- }
- socket_error_t;
- #define FILE_ETC_SERVICES "services"
- #define ENVIRON_ETC_SERVICES "SERVICES"
- #define FILE_ETC_NETWORKS "networks"
- #define ENVIRON_ETC_NETWORKS "NETWORKS"
- #define FILE_ETC_PROTOCOLS "protocol"
- #define ENVIRON_ETC_PROTOCOLS "PROTOCOLS"
- #define MAX_NAMLEN 256
- #define MAX_ALIASES 4
- typedef struct
- {
- FILE *fd;
- char file[PATH_MAX];
- struct servent ent;
- char name[MAX_NAMLEN];
- char proto[MAX_NAMLEN];
- char alias[MAX_ALIASES][MAX_NAMLEN];
- char *aliases[MAX_ALIASES];
- int port;
- }
- scm_i_servent_t;
- static scm_i_servent_t scm_i_servent;
- typedef struct
- {
- FILE *fd;
- char file[PATH_MAX];
- struct protoent ent;
- char name[MAX_NAMLEN];
- char alias[MAX_ALIASES][MAX_NAMLEN];
- char *aliases[MAX_ALIASES];
- int proto;
- }
- scm_i_protoent_t;
- static scm_i_protoent_t scm_i_protoent;
- #ifndef EWOULDBLOCK
- # define EWOULDBLOCK WSAEWOULDBLOCK
- #endif
- #ifndef EINPROGRESS
- # define EINPROGRESS WSAEINPROGRESS
- #endif
- #ifndef EALREADY
- # define EALREADY WSAEALREADY
- #endif
- #ifndef EDESTADDRREQ
- # define EDESTADDRREQ WSAEDESTADDRREQ
- #endif
- #ifndef EMSGSIZE
- # define EMSGSIZE WSAEMSGSIZE
- #endif
- #ifndef EPROTOTYPE
- # define EPROTOTYPE WSAEPROTOTYPE
- #endif
- #ifndef ENOTSOCK
- # define ENOTSOCK WSAENOTSOCK
- #endif
- #ifndef ENOPROTOOPT
- # define ENOPROTOOPT WSAENOPROTOOPT
- #endif
- #ifndef EPROTONOSUPPORT
- # define EPROTONOSUPPORT WSAEPROTONOSUPPORT
- #endif
- #ifndef ESOCKTNOSUPPORT
- # define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
- #endif
- #ifndef EOPNOTSUPP
- # define EOPNOTSUPP WSAEOPNOTSUPP
- #endif
- #ifndef EPFNOSUPPORT
- # define EPFNOSUPPORT WSAEPFNOSUPPORT
- #endif
- #ifndef EAFNOSUPPORT
- # define EAFNOSUPPORT WSAEAFNOSUPPORT
- #endif
- #ifndef EADDRINUSE
- # define EADDRINUSE WSAEADDRINUSE
- #endif
- #ifndef EADDRNOTAVAIL
- # define EADDRNOTAVAIL WSAEADDRNOTAVAIL
- #endif
- #ifndef ENETDOWN
- # define ENETDOWN WSAENETDOWN
- #endif
- #ifndef ENETUNREACH
- # define ENETUNREACH WSAENETUNREACH
- #endif
- #ifndef ENETRESET
- # define ENETRESET WSAENETRESET
- #endif
- #ifndef ECONNABORTED
- # define ECONNABORTED WSAECONNABORTED
- #endif
- #ifndef ECONNRESET
- # define ECONNRESET WSAECONNRESET
- #endif
- #ifndef ENOBUFS
- # define ENOBUFS WSAENOBUFS
- #endif
- #ifndef EISCONN
- # define EISCONN WSAEISCONN
- #endif
- #ifndef ENOTCONN
- # define ENOTCONN WSAENOTCONN
- #endif
- #ifndef ESHUTDOWN
- # define ESHUTDOWN WSAESHUTDOWN
- #endif
- #ifndef ETOOMANYREFS
- # define ETOOMANYREFS WSAETOOMANYREFS
- #endif
- #ifndef ETIMEDOUT
- # define ETIMEDOUT WSAETIMEDOUT
- #endif
- #ifndef ECONNREFUSED
- # define ECONNREFUSED WSAECONNREFUSED
- #endif
- #ifndef ELOOP
- # define ELOOP WSAELOOP
- #endif
- #ifndef EHOSTDOWN
- # define EHOSTDOWN WSAEHOSTDOWN
- #endif
- #ifndef EHOSTUNREACH
- # define EHOSTUNREACH WSAEHOSTUNREACH
- #endif
- #ifndef EPROCLIM
- # define EPROCLIM WSAEPROCLIM
- #endif
- #ifndef EUSERS
- # define EUSERS WSAEUSERS
- #endif
- #ifndef EDQUOT
- # define EDQUOT WSAEDQUOT
- #endif
- #ifndef ESTALE
- # define ESTALE WSAESTALE
- #endif
- #ifndef EREMOTE
- # define EREMOTE WSAEREMOTE
- #endif
- static socket_error_t socket_errno [] = {
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSAEINTR, "Interrupted function call", EINTR, NULL, "WSAEINTR" },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSAEBADF, "Bad file number", EBADF, NULL, "WSAEBADF" },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSAEACCES, "Permission denied", EACCES, NULL, "WSAEACCES" },
- { WSAEFAULT, "Bad address", EFAULT, NULL, "WSAEFAULT" },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSAEINVAL, "Invalid argument", EINVAL, NULL, "WSAEINVAL" },
- { 0, NULL, 0, NULL, NULL },
- { WSAEMFILE, "Too many open files", EMFILE, NULL, "WSAEMFILE" },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSAEWOULDBLOCK, "Resource temporarily unavailable",
- EWOULDBLOCK, "EWOULDBLOCK", "WSAEWOULDBLOCK" },
- { WSAEINPROGRESS, "Operation now in progress",
- EINPROGRESS, "EINPROGRESS", "WSAEINPROGRESS" },
- { WSAEALREADY, "Operation already in progress",
- EALREADY, "EALREADY", "WSAEALREADY" },
- { WSAENOTSOCK, "Socket operation on non-socket",
- ENOTSOCK, "ENOTSOCK", "WSAENOTSOCK"},
- { WSAEDESTADDRREQ, "Destination address required",
- EDESTADDRREQ, "EDESTADDRREQ", "WSAEDESTADDRREQ" },
- { WSAEMSGSIZE, "Message too long",
- EMSGSIZE, "EMSGSIZE", "WSAEMSGSIZE" },
- { WSAEPROTOTYPE, "Protocol wrong type for socket",
- EPROTOTYPE, "EPROTOTYPE", "WSAEPROTOTYPE" },
- { WSAENOPROTOOPT, "Bad protocol option",
- ENOPROTOOPT, "ENOPROTOOPT", "WSAENOPROTOOPT" },
- { WSAEPROTONOSUPPORT, "Protocol not supported",
- EPROTONOSUPPORT, "EPROTONOSUPPORT", "WSAEPROTONOSUPPORT" },
- { WSAESOCKTNOSUPPORT, "Socket type not supported",
- ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "WSAESOCKTNOSUPPORT" },
- { WSAEOPNOTSUPP, "Operation not supported",
- EOPNOTSUPP, "EOPNOTSUPP", "WSAEOPNOTSUPP" },
- { WSAEPFNOSUPPORT, "Protocol family not supported",
- EPFNOSUPPORT, "EPFNOSUPPORT", "WSAEPFNOSUPPORT" },
- { WSAEAFNOSUPPORT,
- "Address family not supported by protocol family",
- EAFNOSUPPORT, "EAFNOSUPPORT", "WSAEAFNOSUPPORT" },
- { WSAEADDRINUSE, "Address already in use",
- EADDRINUSE, "EADDRINUSE", "WSAEADDRINUSE" },
- { WSAEADDRNOTAVAIL, "Cannot assign requested address",
- EADDRNOTAVAIL, "EADDRNOTAVAIL", "WSAEADDRNOTAVAIL" },
- { WSAENETDOWN, "Network is down",
- ENETDOWN, "ENETDOWN", "WSAENETDOWN" },
- { WSAENETUNREACH, "Network is unreachable",
- ENETUNREACH, "ENETUNREACH", "WSAENETUNREACH" },
- { WSAENETRESET, "Network dropped connection on reset",
- ENETRESET, "ENETRESET", "WSAENETRESET" },
- { WSAECONNABORTED, "Software caused connection abort",
- ECONNABORTED, "ECONNABORTED", "WSAECONNABORTED" },
- { WSAECONNRESET, "Connection reset by peer",
- ECONNRESET, "ECONNRESET", "WSAECONNRESET" },
- { WSAENOBUFS, "No buffer space available",
- ENOBUFS, "ENOBUFS", "WSAENOBUFS" },
- { WSAEISCONN, "Socket is already connected",
- EISCONN, "EISCONN", "WSAEISCONN" },
- { WSAENOTCONN, "Socket is not connected",
- ENOTCONN, "ENOTCONN", "WSAENOTCONN" },
- { WSAESHUTDOWN, "Cannot send after socket shutdown",
- ESHUTDOWN, "ESHUTDOWN", "WSAESHUTDOWN" },
- { WSAETOOMANYREFS, "Too many references; can't splice",
- ETOOMANYREFS, "ETOOMANYREFS", "WSAETOOMANYREFS" },
- { WSAETIMEDOUT, "Connection timed out",
- ETIMEDOUT, "ETIMEDOUT", "WSAETIMEDOUT" },
- { WSAECONNREFUSED, "Connection refused",
- ECONNREFUSED, "ECONNREFUSED", "WSAECONNREFUSED" },
- { WSAELOOP, "Too many levels of symbolic links",
- ELOOP, "ELOOP", "WSAELOOP" },
- { WSAENAMETOOLONG, "File name too long",
- ENAMETOOLONG, NULL, "WSAENAMETOOLONG" },
- { WSAEHOSTDOWN, "Host is down",
- EHOSTDOWN, "EHOSTDOWN", "WSAEHOSTDOWN" },
- { WSAEHOSTUNREACH, "No route to host",
- EHOSTUNREACH, "EHOSTUNREACH", "WSAEHOSTUNREACH" },
- { WSAENOTEMPTY, "Directory not empty",
- ENOTEMPTY, NULL, "WSAENOTEMPTY" },
- { WSAEPROCLIM, "Too many processes",
- EPROCLIM, "EPROCLIM", "WSAEPROCLIM" },
- { WSAEUSERS, "Too many users",
- EUSERS, "EUSERS", "WSAEUSERS" },
- { WSAEDQUOT, "Disc quota exceeded",
- EDQUOT, "EDQUOT", "WSAEDQUOT" },
- { WSAESTALE, "Stale NFS file handle",
- ESTALE, "ESTALE", "WSAESTALE" },
- { WSAEREMOTE, "Too many levels of remote in path",
- EREMOTE, "EREMOTE", "WSAEREMOTE" },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSASYSNOTREADY, "Network subsystem is unavailable",
- 0, NULL, "WSASYSNOTREADY" },
- { WSAVERNOTSUPPORTED, "WINSOCK.DLL version out of range",
- 0, NULL, "WSAVERNOTSUPPORTED" },
- { WSANOTINITIALISED, "Successful WSAStartup not yet performed",
- 0, NULL, "WSANOTINITIALISED" },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { 0, NULL, 0, NULL, NULL },
- { WSAEDISCON, "Graceful shutdown in progress",
- 0, NULL, "WSAEDISCON" },
- { WSAENOMORE, "No more services",
- 0, NULL, "WSAENOMORE" },
- { WSAECANCELLED, "Service lookup cancelled",
- 0, NULL, "WSAECANCELLED" },
- { WSAEINVALIDPROCTABLE, "Invalid procedure call table",
- 0, NULL, "WSAEINVALIDPROCTABLE" },
- { WSAEINVALIDPROVIDER, "Invalid service provider",
- 0, NULL, "WSAEINVALIDPROVIDER" },
- { WSAEPROVIDERFAILEDINIT, "Service provider failure",
- 0, NULL, "WSAEPROVIDERFAILEDINIT" },
- { WSASYSCALLFAILURE, "System call failed",
- 0, NULL, "WSASYSCALLFAILURE" },
- { WSASERVICE_NOT_FOUND, "No such service",
- 0, NULL, "WSASERVICE_NOT_FOUND" },
- { WSATYPE_NOT_FOUND, "Class not found",
- 0, NULL, "WSATYPE_NOT_FOUND" },
- { WSA_E_NO_MORE, "No more services",
- 0, NULL, "WSA_E_NO_MORE" },
- { WSA_E_CANCELLED, "Service lookup cancelled",
- 0, NULL, "WSA_E_CANCELLED" },
- { WSAEREFUSED, "Database query refused",
- 0, NULL, "WSAEREFUSED" },
- { -1, NULL, -1, NULL, NULL }
- };
- static socket_error_t socket_h_errno [] = {
- { 0, NULL, 0, NULL, NULL },
- { WSAHOST_NOT_FOUND, "Host not found",
- HOST_NOT_FOUND, "HOST_NOT_FOUND", "WSAHOST_NOT_FOUND" },
- { WSATRY_AGAIN, "Non-authoritative host not found",
- TRY_AGAIN, "TRY_AGAIN", "WSATRY_AGAIN" },
- { WSANO_RECOVERY, "This is a non-recoverable error",
- NO_RECOVERY, "NO_RECOVERY", "WSANO_RECOVERY" },
- { WSANO_DATA, "Valid name, no data record of requested type",
- NO_DATA, "NO_DATA", "WSANO_DATA" },
- { WSANO_ADDRESS, "No address, look for MX record",
- NO_ADDRESS, "NO_ADDRESS", "WSANO_ADDRESS" },
- { -1, NULL, -1, NULL, NULL }
- };
- int
- scm_i_socket_errno (void)
- {
- return WSAGetLastError ();
- }
- char *
- scm_i_socket_strerror (int error)
- {
- if (error >= WSABASEERR && error <= (WSABASEERR + 112))
- return socket_errno[error - WSABASEERR].str;
- else if (error >= (WSABASEERR + 1000) && error <= (WSABASEERR + 1005))
- return socket_h_errno[error - (WSABASEERR + 1000)].str;
- return NULL;
- }
- char *
- scm_i_socket_filename (char *file)
- {
- static char dir[PATH_MAX];
- int len = PATH_MAX;
- len = GetWindowsDirectory (dir, len);
- if (dir[len - 1] != '\\')
- strcat (dir, "\\");
- strcat (dir, file);
- return dir;
- }
- static char *
- scm_i_socket_uncomment (char *line)
- {
- char *end;
- if ((end = strchr (line, '#')) != NULL)
- *end-- = '\0';
- else
- {
- end = line + strlen (line) - 1;
- while (end > line && (*end == '\r' || *end == '\n'))
- *end-- = '\0';
- }
- while (end > line && isspace ((int) (*end)))
- *end-- = '\0';
- return end;
- }
- struct servent *
- getservent (void)
- {
- char line[MAX_NAMLEN], *end, *p;
- int done = 0, i, n, a;
- struct servent *e = NULL;
-
- if (scm_i_servent.fd == NULL || feof (scm_i_servent.fd))
- {
- setservent (1);
- if (scm_i_servent.fd == NULL)
- return NULL;
- }
- while (!done)
- {
-
- if (fgets (line, MAX_NAMLEN, scm_i_servent.fd) != NULL)
- {
- end = scm_i_socket_uncomment (line);
-
- if ((i = sscanf (line, "%s %d/%s%n",
- scm_i_servent.name,
- &scm_i_servent.port,
- scm_i_servent.proto, &n)) != 3)
- continue;
-
- p = line + n;
- for (a = 0; a < MAX_ALIASES && p < end && i != -1 && n > 1;
- a++, p += n)
- i = sscanf (p, "%s%n", scm_i_servent.alias[a], &n);
-
- e = &scm_i_servent.ent;
- e->s_name = scm_i_servent.name;
- e->s_port = htons (scm_i_servent.port);
- e->s_proto = scm_i_servent.proto;
- e->s_aliases = scm_i_servent.aliases;
- scm_i_servent.aliases[a] = NULL;
- while (a--)
- scm_i_servent.aliases[a] = scm_i_servent.alias[a];
- done = 1;
- }
- else
- break;
- }
- return done ? e : NULL;
- }
- void
- setservent (int stayopen)
- {
- char *file = NULL;
- endservent ();
- if ((file = getenv (ENVIRON_ETC_SERVICES)) != NULL)
- strcpy (scm_i_servent.file, file);
- else if ((file = scm_i_socket_filename (FILE_ETC_SERVICES)) != NULL)
- strcpy (scm_i_servent.file, file);
- scm_i_servent.fd = fopen (scm_i_servent.file, "rt");
- }
- void
- endservent (void)
- {
- if (scm_i_servent.fd != NULL)
- {
- fclose (scm_i_servent.fd);
- scm_i_servent.fd = NULL;
- }
- }
- struct protoent *
- getprotoent (void)
- {
- char line[MAX_NAMLEN], *end, *p;
- int done = 0, i, n, a;
- struct protoent *e = NULL;
-
- if (scm_i_protoent.fd == NULL || feof (scm_i_protoent.fd))
- {
- setprotoent (1);
- if (scm_i_protoent.fd == NULL)
- return NULL;
- }
- while (!done)
- {
-
- if (fgets (line, MAX_NAMLEN, scm_i_protoent.fd) != NULL)
- {
- end = scm_i_socket_uncomment (line);
-
- if ((i = sscanf (line, "%s %d%n",
- scm_i_protoent.name,
- &scm_i_protoent.proto, &n)) != 2)
- continue;
-
- p = line + n;
- for (a = 0; a < MAX_ALIASES && p < end && i != -1 && n > 1;
- a++, p += n)
- i = sscanf (p, "%s%n", scm_i_protoent.alias[a], &n);
-
- e = &scm_i_protoent.ent;
- e->p_name = scm_i_protoent.name;
- e->p_proto = scm_i_protoent.proto;
- e->p_aliases = scm_i_protoent.aliases;
- scm_i_protoent.aliases[a] = NULL;
- while (a--)
- scm_i_protoent.aliases[a] = scm_i_protoent.alias[a];
- done = 1;
- }
- else
- break;
- }
- return done ? e : NULL;
- }
- void
- setprotoent (int stayopen)
- {
- char *file = NULL;
- endprotoent ();
- if ((file = getenv (ENVIRON_ETC_PROTOCOLS)) != NULL)
- strcpy (scm_i_protoent.file, file);
- else if ((file = scm_i_socket_filename (FILE_ETC_PROTOCOLS)) != NULL)
- strcpy (scm_i_protoent.file, file);
- scm_i_protoent.fd = fopen (scm_i_protoent.file, "rt");
- }
- void
- endprotoent (void)
- {
- if (scm_i_protoent.fd != NULL)
- {
- fclose (scm_i_protoent.fd);
- scm_i_protoent.fd = NULL;
- }
- }
- static void
- scm_socket_symbols_Win32 (socket_error_t * e)
- {
- while (e->error != -1)
- {
- if (e->error)
- {
- if (e->correct_str)
- scm_c_define (e->correct_str, scm_from_int (e->error));
- if (e->replace && e->replace_str)
- scm_c_define (e->replace_str, scm_from_int (e->replace));
- }
- e++;
- }
- }
- void
- scm_i_init_socket_Win32 (void)
- {
- scm_socket_symbols_Win32 (socket_errno);
- scm_socket_symbols_Win32 (socket_h_errno);
- }
|