File: network.c

package info (click to toggle)
s3d 0.2.2.1-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,356 kB
  • sloc: ansic: 21,128; python: 488; perl: 98; makefile: 31; sh: 29
file content (142 lines) | stat: -rw-r--r-- 2,977 bytes parent folder | download | duplicates (3)
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;
}