1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// SPDX-License-Identifier: LGPL-2.1-or-later
/* SPDX-FileCopyrightText: 2004-2015 Simon Wunderlich <sw@simonwunderlich.de>
*/
#include "s3d.h"
#include "s3dlib.h"
#include <string.h> /* memcpy() */
#include <stdlib.h> /* malloc(), free() */
#include <unistd.h> /* read(), write() */
#include <errno.h> /* errno */
#include <netinet/in.h> /* htons(),htonl() */
int con_type = CON_NULL;
#ifdef TCP
static int _s3d_net_receive(void);
#endif
int net_send(uint8_t opcode, char *buf, uint16_t length)
{
char *ptr;
/* char *buff; */
char buff[65539]; /* uint16_t really shouldn't be bigger ;) */
*(buff) = opcode;
ptr = buff + 1;
*((uint16_t *) ptr) = htons(length);
if (length != 0)
memcpy(buff + 3, buf, length);
switch (con_type) {
#ifdef SHM
case CON_SHM:
shm_writen(buff, length + 3);
break;
#endif
#ifdef TCP
case CON_TCP:
tcp_writen(buff, length + 3);
break;
#endif
}
return 0;
}
/* handler for socket based connection types */
#ifdef TCP
static int _s3d_net_receive(void)
{
return _s3d_tcp_net_receive();
}
#endif
/** \brief get events from server
*
* This functions is for programs which do not employ a mainloop, hence they
* need to check for new events on their own. Programs like these must make sure
* to call this function from time to time to convince the server that they did
* not freeze or bail out.
*/
int s3d_net_check(void)
{
switch (con_type) {
#ifdef TCP
case CON_TCP:
#ifdef SIGS
if (_s3d_sigio) {
#endif
while (_s3d_net_receive()) {}
#ifdef SIGS
_s3d_sigio = 0;
}
#endif
break;
#endif
#ifdef SHM
case CON_SHM:
while (_shm_net_receive()) {}
break;
#endif
}
s3d_process_stack();
return 0;
}
int s3d_net_init(char *urlc)
{
char *s, *sv, *port = NULL;
char *first_slash = NULL;
#ifdef TCP
int pn = 0;
#endif
int tcp, shm;
tcp = shm = 1; /* everything is possible, yet */
/* doing a very bad server/port extraction, but I think it'll work ... */
s = sv = urlc + 6; /* getting to the "real" thing */
/* while (((*s!='/') && (*s!=0)) && (s<(urlc-6))) */
while (*s != 0) {
if (*s == '/') {
if (first_slash == NULL)
first_slash = s;
if (port != NULL)
break;
}
if (*s == ':') { /* there is a port in here */
port = s + 1;
*s = 0; /* NULL the port */
}
s++;
}
*s = 0;
if (port == NULL) {
shm = 0;
if (first_slash != NULL)
*first_slash = 0;
} else {
if (first_slash < port)
tcp = 0;
else if (first_slash != NULL)
*first_slash = 0;
if (!strncmp(port, "shm", 3)) {
tcp = 0; /* null the others */
} else {
shm = 0;
}
}
#ifdef SHM
if (shm) {
if (!strncmp(port, "shm", 3))
if (!_shm_init(sv)) return con_type = CON_SHM;
}
#endif
#ifdef TCP
if (tcp) {
pn = 6066;
if (port != NULL) {
if (!(pn = atoi(port))) { /* I hope atoi is safe enough. */
errn("s3d_init():atoi()", errno);
pn = 6066;
}
}
if (!_tcp_init(sv, pn)) return con_type = CON_TCP;
}
#endif
return CON_NULL;
}
|