aboutsummaryrefslogtreecommitdiff
path: root/net.c
blob: cce4dc6952ca9cc69ba98b444f98127c339b2cd2 (plain)
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
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include "net.h"


bool net_send_raw_text(int fd,const char *text,i64 len){
	i64 cursor=0;
	while(cursor<len){
		i64 nwr=send(fd,text+cursor,len-cursor,0);
		if(nwr<0){
			if(errno==EINTR)continue;
			if(errno==ECONNRESET||errno==EPIPE)return true;
			die_perror("send");
		}
		cursor+=nwr;
	}
	return false;
}

bool net_send_ok(int fd,const char *tag){
	char *buf=NULL;
	i64 len=asprintf(&buf,"%s ok\n",tag);
	bool closed=net_send_raw_text(fd,buf,len);
	free(buf);
	return closed;
}

bool net_send_number(int fd,const char *tag,i64 number){
	char *buf=NULL;
	i64 len=asprintf(&buf,"%s number %" PRIi64 "\n",tag,number);
	bool closed=net_send_raw_text(fd,buf,len);
	free(buf);
	return closed;
}

bool net_send_error(int fd,const char *tag,const char *msg){
	char *buf=NULL;
	i64 len=asprintf(&buf,"%s error %s\n",tag,msg);
	bool closed=net_send_raw_text(fd,buf,len);
	free(buf);
	return closed;
}

bool net_send_name(int fd,const char *tag,const char *name){
	char *buf=NULL;
	i64 len=asprintf(&buf,"%s name %s\n",tag,name);
	bool closed=net_send_raw_text(fd,buf,len);
	free(buf);
	return closed;
}

bool net_send_list(int fd,const char *tag,i64 count,const char **list){
	char *buf=NULL;
	i64 len=asprintf(&buf,"%s list %" PRIi64,tag,count);
	bool closed=net_send_raw_text(fd,buf,len);
	free(buf);
	if(closed)return true;

	if(count>0){
		i64 bufsz=64;
		buf=malloc(bufsz,char);

		for(i64 i=0;i<count;i++){
			i64 len=strlen(list[i]);
			if(len>=bufsz){
				bufsz=len+512;
				buf=realloc(buf,bufsz,char);
			}
			memcpy(buf+1,list[i],len);
			buf[0]=' ';
			if(net_send_raw_text(fd,buf,len+1)){
				free(buf);
				return true;
			}
		}

		free(buf);
	}

	return net_send_raw_text(fd,"\n",1);
}

bool net_send_pong(int fd,const char *tag){
	char *buf=NULL;
	i64 len=asprintf(&buf,"%s pong\n",tag);
	bool closed=net_send_raw_text(fd,buf,len);
	free(buf);
	return closed;
}