aboutsummaryrefslogtreecommitdiff
path: root/src/client.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-12-07 17:48:32 -0500
committerFranklin Wei <git@fwei.tk>2015-12-07 17:48:32 -0500
commit0f3bd99c40594c46b5b4bb0603085ec9cc111e0e (patch)
tree0533aa2d245a8bc8aaa652c8c4c039c27504f0f9 /src/client.c
parent8bc78787a99efdf4c64032d7fe55905ff995cd98 (diff)
downloadnetcosm-0f3bd99c40594c46b5b4bb0603085ec9cc111e0e.zip
netcosm-0f3bd99c40594c46b5b4bb0603085ec9cc111e0e.tar.gz
netcosm-0f3bd99c40594c46b5b4bb0603085ec9cc111e0e.tar.bz2
netcosm-0f3bd99c40594c46b5b4bb0603085ec9cc111e0e.tar.xz
child-parent communication
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c84
1 files changed, 75 insertions, 9 deletions
diff --git a/src/client.c b/src/client.c
index 18c390c..4ed944c 100644
--- a/src/client.c
+++ b/src/client.c
@@ -1,6 +1,11 @@
#include "netcosm.h"
-int client_fd;
+int client_fd, to_parent, from_parent;
+
+void out_raw(const unsigned char *buf, size_t len)
+{
+ write(client_fd, buf, len);
+}
void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
{
@@ -8,22 +13,20 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
memset(buf, 0, sizeof(buf));
va_list ap;
va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
+ int len = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- write(client_fd, buf, sizeof(buf));
+ out_raw((unsigned char*)buf, len);
}
-void out_raw(const unsigned char *buf, size_t len)
-{
- write(client_fd, buf, len);
-}
#define BUFSZ 128
char *client_read(void)
{
char *buf;
+
tryagain:
+
buf = malloc(BUFSZ);
memset(buf, 0, BUFSZ);
if(read(client_fd, buf, BUFSZ - 1) < 0)
@@ -55,11 +58,40 @@ void all_upper(char *s)
}
}
+void sigusr2_handler(int s)
+{
+ (void) s;
+ unsigned char buf[MSG_MAX + 1];
+ size_t len = read(from_parent, buf, MSG_MAX);
+ buf[MSG_MAX] = '\0';
+ out_raw(buf, len);
+}
+
+void client_change_state(int state)
+{
+ unsigned char cmdcode = REQ_CHANGESTATE;
+ write(to_parent, &cmdcode, sizeof(cmdcode));
+ write(to_parent, &state, sizeof(state));
+ kill(getppid(), SIGUSR1);
+}
+
+void client_change_user(const char *user)
+{
+ unsigned char cmdcode = REQ_CHANGEUSER;
+ write(to_parent, &cmdcode, sizeof(cmdcode));
+ write(to_parent, user, strlen(user) + 1);
+ kill(getppid(), SIGUSR1);
+}
+
#define WSPACE " \t\r\n"
-void client_main(int fd, struct sockaddr_in *addr, int total)
+void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
{
client_fd = fd;
+ to_parent = to;
+ from_parent = from;
+
+ signal(SIGUSR2, sigusr2_handler);
telnet_init();
@@ -81,13 +113,20 @@ void client_main(int fd, struct sockaddr_in *addr, int total)
char *current_user;
+ client_change_state(STATE_AUTH);
+
/* auth loop */
while(1)
{
out("login: ");
current_user = client_read();
+ remove_cruft(current_user);
+ telnet_echo_off();
out("Password: ");
char *pass = client_read();
+ telnet_echo_on();
+ out("\n");
+ client_change_state(STATE_CHECKING);
struct authinfo_t auth = auth_check(current_user, pass);
memset(pass, 0, strlen(pass));
free(pass);
@@ -95,11 +134,13 @@ void client_main(int fd, struct sockaddr_in *addr, int total)
authlevel = auth.authlevel;
if(auth.success)
{
+ client_change_state(STATE_LOGGEDIN);
out("Access Granted.\n\n");
break;
}
else
{
+ client_change_state(STATE_FAILED);
free(current_user);
out("Access Denied.\n\n");
if(++failures >= MAX_FAILURES)
@@ -112,8 +153,12 @@ void client_main(int fd, struct sockaddr_in *addr, int total)
return;
bool admin = (authlevel == PRIV_ADMIN);
+ if(admin)
+ client_change_state(STATE_ADMIN);
/* authenticated */
+ printf("Authenticated as %s\n", current_user);
+ client_change_user(current_user);
while(1)
{
out(">> ");
@@ -123,6 +168,8 @@ void client_main(int fd, struct sockaddr_in *addr, int total)
char *tok = strtok_r(cmd, WSPACE, &save);
+ if(!tok)
+ continue;
all_upper(tok);
if(admin)
@@ -183,14 +230,33 @@ void client_main(int fd, struct sockaddr_in *addr, int total)
else
out("Usage: USER ADD|CHANGE <USERNAME>\n");
}
+ else if(!strcmp(what, "LIST"))
+ {
+ auth_list_users();
+ }
+ }
+ else if(!strcmp(tok, "CLIENTS"))
+ {
+ unsigned char cmd_code = REQ_LISTCLIENTS;
+ write(to_parent, &cmd_code, sizeof(cmd_code));
+ kill(getppid(), SIGUSR1);
+ waitpid(-1, NULL, 0);
}
}
- if(!strcmp(tok, "QUIT"))
+ if(!strcmp(tok, "QUIT") || !strcmp(tok, "EXIT"))
{
free(cmd);
goto done;
}
+ else if(!strcmp(tok, "SAY"))
+ {
+ char *what = strtok_r(NULL, "", &save);
+ unsigned char cmd_code = REQ_BCASTMSG;
+ write(to_parent, &cmd_code, sizeof(cmd_code));
+ dprintf(to_parent, "%s says %s", current_user, what);
+ kill(getppid(), SIGUSR1);
+ }
next_cmd: