diff options
Diffstat (limited to 'client')
| -rw-r--r-- | client/.gitignore | 1 | ||||
| -rw-r--r-- | client/Makefile | 30 | ||||
| -rw-r--r-- | client/client.c | 418 | ||||
| -rw-r--r-- | client/global.c | 33 | ||||
| -rw-r--r-- | client/global.h | 14 | ||||
| -rw-r--r-- | client/memory.c | 16 | ||||
| -rw-r--r-- | client/memory.h | 15 | 
7 files changed, 0 insertions, 527 deletions
| diff --git a/client/.gitignore b/client/.gitignore deleted file mode 100644 index b051c6c..0000000 --- a/client/.gitignore +++ /dev/null @@ -1 +0,0 @@ -client diff --git a/client/Makefile b/client/Makefile deleted file mode 100644 index e9bbb91..0000000 --- a/client/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -CC = gcc -CFLAGS = -Wall -Wextra -std=c11 -g -fwrapv -I$(TERMIO)/include -LDFLAGS = -L$(TERMIO)/lib -ltermio - -TERMIO = $(HOME)/prefix - -TARGETS = client - -.PHONY: all clean remake - -# Clear all implicit suffix rules -.SUFFIXES: - -# Don't delete intermediate files -.SECONDARY: - -all: $(TARGETS) - -clean: -	rm -f $(TARGETS) *.o - -remake: clean -	$(MAKE) all - - -$(TARGETS): $(patsubst %.c,%.o,$(wildcard *.c)) -	$(CC) -o $@ $^ $(LDFLAGS) - -%.o: %.c $(wildcard *.h) -	$(CC) $(CFLAGS) -c -o $@ $< diff --git a/client/client.c b/client/client.c deleted file mode 100644 index 6609f89..0000000 --- a/client/client.c +++ /dev/null @@ -1,418 +0,0 @@ -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <stdarg.h> -#include <string.h> -#include <sys/select.h> -#include <sys/socket.h> -#include <netdb.h> -#include <unistd.h> -#include <errno.h> -#include <assert.h> -#include <termio.h> -#include "global.h" - - -static const Style normal_style={9,9,false,false}; -static const Style bold_style={9,9,true,false}; -static const Style command_style={3,9,false,false}; -static const Style server_style={6,9,false,false}; -static const Style error_style={1,9,true,false}; - - -static i64 uniqid(void){ -	static i64 id=1; -	return id++; -} - -static ssize_t send_all(int socket,const void *buffer,i64 length){ -	ssize_t cursor=0; -	while(cursor<length){ -		ssize_t nwr=send(socket,buffer+cursor,length-cursor,0); -		if(nwr<=0)return nwr; -		cursor+=nwr; -	} -	return cursor; -} - - -static int connect_server(const char *hostname,int port){ -	struct addrinfo hints,*res; - -	memset(&hints,0,sizeof(hints)); -	hints.ai_family=AF_UNSPEC; -	hints.ai_socktype=SOCK_STREAM; - -	char portbuf[16]; -	snprintf(portbuf,16,"%d",port); -	int ret=getaddrinfo(hostname,portbuf,&hints,&res); -	if(ret!=0){ -		fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(ret)); -		exit(1); -	} - -	int sock; -	struct addrinfo *current=res; -	while(current){ -		sock=socket(res->ai_family,res->ai_socktype,res->ai_protocol); -		if(sock!=-1){ -			if(connect(sock,res->ai_addr,res->ai_addrlen)==0){ -				break; -			} -		} -		close(sock); -		sock=-1; -		current=current->ai_next; -	} -	freeaddrinfo(res); - -	return sock; -} - -static bool termio_needs_reset=false; - -static void termio_reset(void){ -	if(!termio_needs_reset)return; -	endkeyboard(); -	endscreen(); -	termio_needs_reset=false; -} - -static void termio_init(void){ -	initscreen(); -	initkeyboard(false); -	installCLhandler(true); -	atexit(termio_reset); -	termio_needs_reset=true; -} - - -static i64 bar_width=11; - -static char *user_buffer=NULL; -static i64 user_bufsz=0; -static i64 user_buflen=0; - -static int server_sock=-1; - - -enum log_type{ -	LOG_MESSAGE, -	LOG_SERVER, -	LOG_COMMAND, -	LOG_ERROR, -}; - -static void emit_log_line(enum log_type type,const char *head,const char *line){ -	i64 headlen=strlen(head); -	if(headlen+1>bar_width){ -		bar_width=headlen+1; -	} -	Size termsize=gettermsize(); -	assert(termsize.w>bar_width); - -	i64 linelen=strlen(line); -	i64 nlines=1,cursor=termsize.w-bar_width; -	while(cursor<linelen){ -		cursor+=termsize.w-bar_width; -		nlines++; -	} - -	scrollterm(0,1,termsize.w,termsize.h-2,nlines); - -	char buffer[termsize.w+1]; - -	switch(type){ -		case LOG_MESSAGE: setstyle(&normal_style); break; -		case LOG_SERVER: setstyle(&server_style); break; -		case LOG_COMMAND: setstyle(&command_style); break; -		case LOG_ERROR: setstyle(&error_style); break; -	} - -	pushcursor(); -	moveto(bar_width-1-headlen,termsize.h-1-nlines); -	tprintf("%s",head); -	cursor=0; -	for(int y=0;y<nlines;y++){ -		memcpy(buffer,line+cursor,termsize.w-bar_width); -		buffer[termsize.w-bar_width]='\0'; - -		moveto(bar_width,termsize.h-1-nlines); -		tprintf("%s",buffer); - -		cursor+=termsize.w-bar_width; -	} -	popcursor(); -	redraw(); -} - -__attribute__((format (printf, 3, 4))) -static void emit_log_line_f(enum log_type type,const char *head,const char *format,...){ -	va_list ap; -	va_start(ap,format); -	char *buf=NULL; -	vasprintf(&buf,format,ap); -	va_end(ap); -	assert(buf); -	emit_log_line(type,head,buf); -	free(buf); -} - -static void redraw_prompt(void){ -	Size termsize=gettermsize(); -	moveto(0,termsize.h-1); -	setstyle(&bold_style); -	tprintf("> "); - -	setstyle(&normal_style); -	fillrect(2,termsize.h-1,termsize.w-2,1,' '); -	tprintf("%s",user_buffer); -	redraw(); -} - - -static char *server_user=NULL; -static char *server_room=NULL; - -static void send_message(const char *msg){ -	if(server_user==NULL){ -		emit_log_line(LOG_ERROR,"--","Cannot send messages while not logged in"); -		return; -	} -	if(server_room==NULL){ -		emit_log_line(LOG_ERROR,"--","Cannot send messages while not in a room"); -		return; -	} -} - -static void cmd_register(const char **args){ -	emit_log_line_f(LOG_COMMAND,"##","/register %s %s",args[0],args[1]); -} - -static void cmd_login(const char **args){ -	emit_log_line_f(LOG_COMMAND,"##","Login called with %s and %s",args[0],args[1]); -} - -static void cmd_quit(const char **args){ -	close(server_sock); -	exit(0); -} - -struct cmd_list_item{ -	const char *name; -	int nargs; -	bool longlast; -	void (*func)(const char **args); -}; - -static struct cmd_list_item cmd_list[]={ -	{"register",2,true,cmd_register}, -	{"login",2,true,cmd_login}, -	{"quit",0,false,cmd_quit}, -}; -#define NCOMMANDS ((i64)(sizeof(cmd_list)/sizeof(cmd_list[0]))) - -static void execute_command(char *line){ -	if(line[0]=='/'){ -		send_message(line); -		return; -	} - -	i64 linelen=strlen(line); -	char *sepp=memchr(line,' ',linelen); -	if(sepp==NULL)sepp=line+linelen; -	*sepp='\0'; -	i64 cmdlen=sepp-line; -	i64 cmdi; -	for(cmdi=0;cmdi<NCOMMANDS;cmdi++){ -		if(strncmp(line,cmd_list[cmdi].name,cmdlen)==0){ -			break; -		} -	} - -	if(cmdi==NCOMMANDS){ -		emit_log_line_f(LOG_ERROR,"--","Unknown command '%s'",line); -		return; -	} - -	int nargs=cmd_list[cmdi].nargs; -	char *args[nargs]; -	i64 cursor=cmdlen+1; -	while(line[cursor]==' ')cursor++; - -	for(int i=0;i<nargs;i++){ -		if(cursor>linelen){ -			emit_log_line_f(LOG_ERROR,"--","Too few parameters to command '%s'",line); -			return; -		} -		if(i==nargs-1&&cmd_list[cmdi].longlast){ -			sepp=line+linelen; -		} else { -			sepp=memchr(line+cursor,' ',linelen-cursor); -			if(sepp==NULL)sepp=line+linelen; -		} -		*sepp='\0'; -		args[i]=line+cursor; -		cursor=sepp-line+1; -		while(line[cursor]==' ')cursor++; -	} -	if(sepp-line<linelen){ -		emit_log_line_f(LOG_ERROR,"--","Too many parameters to command '%s'",line); -		return; -	} - -	cmd_list[cmdi].func((const char**)args); -} - - -// Returns whether stdin was closed -static bool handle_stdin(void){ -	int key=tgetkey(); -	switch(key){ -		case KEY_LF: -		case KEY_CR: { -			if(user_buffer[0]=='/'){ -				execute_command(user_buffer+1); -			} else { -				send_message(user_buffer); -			} -			user_buflen=0; -			user_buffer[0]='\0'; -			redraw_prompt(); -			break; -		} - -		case KEY_BACKSPACE: -			if(user_buflen>0){ -				user_buflen--; -				user_buffer[user_buflen]='\0'; -				redraw_prompt(); -			} else { -				bel(); -			} -			break; - -		case KEY_CTRL+'U': -			user_buflen=0; -			user_buffer[0]='\0'; -			redraw_prompt(); -			break; - -		default: -			if(key>=32&&key<=126){ -				if(user_buflen==user_bufsz-1){ -					user_bufsz*=2; -					user_buffer=realloc(user_buffer,user_bufsz,char); -				} -				user_buffer[user_buflen++]=key; -				user_buffer[user_buflen]='\0'; -				redraw_prompt(); -			} else { -				bel(); -			} -			break; -	} -	return false; -} - -// Returns whether socket was closed -static bool handle_server(void){ -	static i64 bufsz=256,buflen=0; -	static char *buffer=NULL; -	if(buffer==NULL){ -		buffer=malloc(bufsz,char); -	} - -	if(bufsz-buflen<128){ -		bufsz*=2; -		buffer=realloc(buffer,bufsz,char); -	} - -	ssize_t nr; -	while(true){ -		nr=read(server_sock,buffer+buflen,bufsz-buflen); -		if(nr<0){ -			if(errno==EINTR)continue; -			if(errno==ECONNRESET){ -				buflen=0; -				return true; -			} -			perror("read"); -			exit(1); -		} -		if(nr==0){ -			buflen=0; -			return true; -		} -		buflen+=nr; -		break; -	} - -	char *lfp=memchr(buffer,'\n',buflen); -	if(lfp==NULL)return false; -	*lfp='\0'; -	emit_log_line(LOG_SERVER,">>",buffer); -	i64 linelen=lfp-buffer; -	memmove(buffer,buffer+linelen+1,buflen-linelen-1); -	buflen-=linelen+1; -	return false; -} - - -int main(int argc,char **argv){ -	const char *hostname="tomsmeding.com"; -	int port=29536; - -	if(argc>=2){ -		hostname=argv[1]; -		if(argc>=3){ -			port=strtol(argv[2],NULL,10); -			if(argc>=4){ -				fprintf(stderr,"Usage: %s [host [port]]\n",argv[0]); -				return 1; -			} -		} -	} - -	server_sock=connect_server(hostname,port); -	if(server_sock==-1){ -		fprintf(stderr,"Could not connect to %s port %d\n",hostname,port); -		return 1; -	} - -	termio_init(); - -	clearscreen(); -	moveto(0,0); -	setstyle(&bold_style); -	tprintf("TOMSG CLIENT"); - -	user_bufsz=256; -	user_buflen=0; -	user_buffer=malloc(user_bufsz,char); - -	redraw_prompt(); - -	while(true){ -		fd_set inset; -		FD_ZERO(&inset); -		FD_SET(STDIN_FILENO,&inset); -		FD_SET(server_sock,&inset); -		int ret=select(server_sock+1,&inset,NULL,NULL,NULL); -		if(ret==-1){ -			if(errno==EINTR)continue; -			perror("select"); -			return 1; -		} -		if(FD_ISSET(STDIN_FILENO,&inset)){ -			if(handle_stdin())break; -		} -		if(FD_ISSET(server_sock,&inset)){ -			if(handle_server())break; -		} -	} - -	close(server_sock); -	termio_reset(); -} diff --git a/client/global.c b/client/global.c deleted file mode 100644 index bf5bf2e..0000000 --- a/client/global.c +++ /dev/null @@ -1,33 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <errno.h> -#include "global.h" - -__attribute__((noreturn, format(printf, 1, 2))) -void die(const char *format,...){ -	fprintf(stderr,"DIE: "); -	va_list ap; -	va_start(ap,format); -	vfprintf(stderr,format,ap); -	va_end(ap); -	fputc('\n',stderr); -	exit(1); -} - -__attribute__((noreturn)) -void die_perror(const char *func){ -	fprintf(stderr,"DIE: %s: %s\n",func,strerror(errno)); -	exit(1); -} - -__attribute__((format (printf, 1, 2))) -void debug(const char *format,...){ -	fprintf(stderr,"DEBUG: "); -	va_list ap; -	va_start(ap,format); -	vfprintf(stderr,format,ap); -	va_end(ap); -	fputc('\n',stderr); -} diff --git a/client/global.h b/client/global.h deleted file mode 100644 index de0873b..0000000 --- a/client/global.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include <stdbool.h> -#include <stdint.h> -#include <inttypes.h> -#include "memory.h" - -typedef int64_t i64; -typedef uint64_t u64; - -void die(const char *format,...) __attribute__((noreturn, format(printf, 1, 2))); -void die_perror(const char *func) __attribute__((noreturn)); - -void debug(const char *format,...) __attribute__((format(printf, 1, 2))); diff --git a/client/memory.c b/client/memory.c deleted file mode 100644 index aec3da2..0000000 --- a/client/memory.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "global.h" -#include "memory.h" - -void* check_after_allocation(const char *func,size_t num,size_t sz,void *ptr){ -	if(ptr==NULL){ -		die("Allocation failed: %s(%zu * %zuB = %zu)",func,num,sz,num*sz); -	} -	return ptr; -} - -void* check_after_allocation_str(const char *func,void *ptr){ -	if(ptr==NULL){ -		die("Allocation failed: %s()",func); -	} -	return ptr; -} diff --git a/client/memory.h b/client/memory.h deleted file mode 100644 index 19cfb95..0000000 --- a/client/memory.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <stdlib.h> - -#define malloc(num,type) \ -	((type*)check_after_allocation("malloc",num,sizeof(type),malloc((num)*sizeof(type)))) -#define calloc(num,type) \ -	((type*)check_after_allocation("calloc",num,sizeof(type),calloc((num),sizeof(type)))) -#define realloc(ptr,num,type) \ -	((type*)check_after_allocation("realloc",num,sizeof(type),realloc((ptr),(num)*sizeof(type)))) -#define strdup(str) \ -	((char*)check_after_allocation_str("strdup",strdup(str))) - -void* check_after_allocation(const char *func,size_t num,size_t sz,void *ptr); -void* check_after_allocation_str(const char *func,void *ptr); | 
