Created
July 19, 2013 09:50
-
-
Save s9gf4ult/6038024 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <netdb.h> | |
#include <netinet/in.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <readline/readline.h> | |
#include <readline/history.h> | |
#define BUFSIZE 1000 | |
int sendMsg(int const sock, struct sockaddr const *addr) { | |
int ret = 0; | |
char *msg; | |
if (! (msg = readline("enter message: "))) { | |
printf("could not read message\n"); | |
ret = 1; | |
goto freemsg; | |
} | |
if (-1 == sendto(sock, | |
msg, | |
strlen(msg), | |
0, | |
addr, | |
sizeof(struct sockaddr))) { | |
printf("error while sending message\n"); | |
ret = 1; | |
goto freemsg; | |
} | |
printf("message sent\n"); | |
freemsg: | |
free(msg); | |
return ret; | |
} | |
int recvMsg(int const sock) { | |
int ret = 0; | |
void *buf; | |
char *cbuf; | |
int msglen; | |
if (! (buf = malloc(BUFSIZE))) { | |
printf("could not allocate memory\n"); | |
ret = 1; | |
goto end; | |
} | |
if (-1 == (msglen = recvfrom(sock, | |
buf, | |
BUFSIZE-1, | |
0, | |
0, | |
0))) { | |
printf("could not receive message, errno %d\n", errno); | |
ret = 1; | |
goto freebuf; | |
} | |
cbuf = (char*)buf; | |
cbuf[msglen] = 0; | |
printf("message is: %s\n", cbuf); | |
freebuf: | |
free(buf); | |
end: | |
return ret; | |
} | |
int getBindedSock(int * const outsock, struct sockaddr const *addr) { | |
int ret = 0; | |
int sock; | |
if(-1 == (sock = socket(AF_INET, SOCK_DGRAM, 0))) { | |
printf("can not open socket, errno %d\n", errno); | |
ret = 1; | |
goto end; | |
} | |
if (-1 == bind(sock, addr, sizeof(struct sockaddr))) { | |
printf("can not bind socket, errno %d\n", errno); | |
ret = 1; | |
close(sock); | |
goto end; | |
} | |
*outsock = sock; | |
end: | |
return ret; | |
} | |
int getsockaddr(char const *laddr, char const *lport, struct sockaddr *saddr) { | |
int ret = 0; | |
struct addrinfo hint, *ainfo; | |
memset(&hint, 0, sizeof(struct addrinfo)); | |
hint.ai_family = AF_INET; | |
hint.ai_socktype = SOCK_DGRAM; | |
if (getaddrinfo(laddr, lport, &hint, &ainfo)) { | |
printf("could not get addrinfo, for address %s:%s, errno %d", laddr, lport, errno); | |
ret = -1; | |
} else { | |
memcpy((void*)saddr, ainfo->ai_addr, sizeof(struct sockaddr)); | |
freeaddrinfo(ainfo); | |
} | |
return ret; | |
} | |
#define ERRJMP( labelname, ... ) \ | |
{ \ | |
printf( __VA_ARGS__ ); \ | |
ret = -1; \ | |
quit = 1; \ | |
goto labelname; \ | |
} | |
int run(struct sockaddr const *laddr, struct sockaddr const *saddr) { | |
int ret = 0; | |
int quit = 0; | |
int sock; | |
if (getBindedSock(&sock, laddr)) { | |
printf("could not get socket"); | |
return -1; | |
} | |
while(!quit) { | |
char *cmd; | |
if (! (cmd = readline("s - send, l - listen, q - quit > "))) | |
ERRJMP( endwhile, "Could not read line, errno %d\n", errno ); | |
if (! strcmp(cmd, "l")) { /* equal to "l" */ | |
if (recvMsg(sock)) | |
ERRJMP( freecmd, "could not receive message" ); | |
} else if (! strcmp(cmd, "s")) { | |
if (sendMsg(sock, saddr)) | |
ERRJMP( freecmd, "could not send message" ); | |
} else if (! strcmp(cmd, "q")) { | |
printf("quitting\n"); | |
quit = 1; | |
} else { | |
printf("dont understand \"%s\"\n", cmd); | |
} | |
freecmd: | |
free(cmd); | |
endwhile:; | |
} | |
close(sock); | |
return ret; | |
} | |
#undef ERRJMP | |
int main(int argc, char **argv) { | |
int ret = 0; | |
if ((argc-1) != 4) { | |
printf("call: {ADDRES} {PORT} {ADDRESS} {PORT}\n"); | |
printf("where the first address and port is for listening and second is for sending messsages to.\n"); | |
} else { | |
char *laddr, *lport, *saddr, *sport; | |
struct sockaddr listenAddr, sendAddr; | |
laddr = argv[1]; | |
lport = argv[2]; | |
saddr = argv[3]; | |
sport = argv[4]; | |
if (-1 != getsockaddr(laddr, lport, &listenAddr) && | |
-1 != getsockaddr(saddr, sport, &sendAddr)) { | |
ret = run(&listenAddr, &sendAddr); | |
} | |
} | |
return ret; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CFLAGS := -pedantic -Wall -Wextra -std=gnu99 | |
LDFLAGS := -lreadline | |
SOURCES := $(wildcard *.c) | |
TARGETS := $(patsubst %.c, %, $(SOURCES)) | |
CLEANS := $(patsubst %.c, %_clean, $(SOURCES)) | |
$(TARGETS): %: %.c | |
gcc -o $@ $(CFLAGS) $(LDFLAGS) $^ | |
$(CLEANS): | |
rm $(patsubst %_clean, %, $@) || echo "removed" | |
all: $(TARGETS) | |
clean: $(CLEANS) | |
.PHONY: all clean $(CLEANS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment