File: sockets.c

package info (click to toggle)
libtlen 20041113-3
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, sarge
  • size: 832 kB
  • ctags: 1,514
  • sloc: ansic: 13,713; sh: 214; makefile: 156
file content (185 lines) | stat: -rw-r--r-- 4,784 bytes parent folder | download
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * Ostatnia aktualizacja:
 *
 * - $Id: sockets.c,v 1.24 2004/01/06 08:15:52 who_ami Exp $
 *
*/

#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <netdb.h>

#include "libtlen.h"

/*
 * tlen_socket_create()
 *
 * tworzy socket i laczy sie z serwerem
 *
 * - address - adres IP serwera
 * - port - port na ktry si czymy
 *
 * zwraca gniazdo
 *
 */

int tlen_socket_create (const char *address, int port)
{
	int gniazdo, one = 1;
	struct sockaddr_in serwer;
	tlen_debug ("Connecting to %s:%d\n", address, port);
	if ((gniazdo = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
		perror ("gniazdo");

	if (ioctl (gniazdo, FIONBIO, &one) == -1)
	{
		close (gniazdo);
		return -1;
	}

	memset (&serwer, 0, sizeof (serwer));
	serwer.sin_family = AF_INET;
	serwer.sin_port = htons (port);

	if ((inet_pton (AF_INET, address, &serwer.sin_addr) <= 0))
		perror ("inet_pton");

	connect (gniazdo, (struct sockaddr *) &serwer, sizeof (serwer));

	return gniazdo;
}

/*
 * tlen_socket_write()
 * 
 * pisze do gniazda
 *
 * - sess - sesja, w ktrej jest nasze gniazdo
 * - data - to co chcemy wysa
 * - len - dugo tego co chcemy wysa
 *
 * zwraca 0 w przypadku bdu lub 1 jak si powiedzie
 *
 */

int tlen_socket_write (struct tlen_session *sess, const void *data, size_t len)
{
        struct tlen_writebuffer_item* item = sess->writebuffer_last_item;

	/* dopisujemy nowe dane na koniec bufora */

        if ((data != NULL) && (len > 0))
        {
                if (!item) {
                        sess->writebuffer = item = malloc(sizeof(struct tlen_writebuffer_item));
                } else {
                        item->next = malloc(sizeof(struct tlen_writebuffer_item));
                        item = item->next;
                }
                if (!item) return 1;
                sess->writebuffer_last_item = item;
                item->next = NULL;
                item->data_mem = item->data_ptr = malloc(len);
                if (!item->data_mem) return 1;
                memcpy(item->data_mem, data, len);
                item->data_len = len;
        }

	/* pobieramy dane do zapisania z poczatku bufora */

        while ((item = sess->writebuffer) != NULL) {
                if (item->data_mem)
                {
                        ssize_t wrote;

	                wrote = write (sess->fd, item->data_ptr, item->data_len);
                        if (wrote == -1)
                        {
                                if (errno == EAGAIN)
                                {
                                        sess->check |= TLEN_CHECK_WRITE;
                                        return 0;
                                }
                                else
                                {
                                        sess->error = TLEN_ERROR_NETWORK;
                                        return 1;
                                }
                        }
                        else
                        {
                                item->data_len-=wrote;
                                if (item->data_len == 0) {
                                        struct tlen_writebuffer_item* next_item = item->next;
                                        free(item->data_mem);
                                        free(item);
                                        sess->writebuffer = next_item;
                                } else item->data_ptr+=wrote;
                        }
                }
                else
                {
                        struct tlen_writebuffer_item* next_item = item->next;
                        free(item);
                        sess->writebuffer = next_item;
                }
        }
        sess->writebuffer_last_item = NULL;
        sess->check &= ~TLEN_CHECK_WRITE;
        return 0;
}

/*
 * tlen_socket_write_string()
 *
 * Pisze tekst do gniazda
 *
 * - sess - sesja z gniazdem
 * - string - tekst do wyslania
 *
 * Zwraca 0 w przypadku bledu, lub 1 jak operacja si powioda
 *
 */

int tlen_socket_write_string (struct tlen_session *sess, const void *string)
{
  if (string) tlen_debug ("%s\n", string);
  return tlen_socket_write(sess, string, strlen(string));
}

/*
 * tlen_socket_destroy()
 *
 * niszczy gniazdo
 *
 * - sess - sesja w ktrej jest gniazdo
 *
 * Zwraca 1 jak si powiedzie, lub 0 w przypadku bdu
 *
 */

int tlen_socket_destroy (struct tlen_session *sess)
{
	if (sess) 
	{
		if (sess->fd != -1) 
		{
			if (!(close (sess->fd)))
			{
       				sess->fd = -1;
				return 1;
			}
		}
	}
        return 0;
}