aboutsummaryrefslogtreecommitdiff
path: root/src/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c85
1 files changed, 75 insertions, 10 deletions
diff --git a/src/client.c b/src/client.c
index 4835881..d64846c 100644
--- a/src/client.c
+++ b/src/client.c
@@ -1,10 +1,24 @@
#include "netcosm.h"
-int client_fd, to_parent, from_parent;
+static int client_fd, to_parent, from_parent;
+
+static volatile sig_atomic_t output_locked = 0, done_printing;
void out_raw(const unsigned char *buf, size_t len)
{
- write(client_fd, buf, len);
+try_again:
+ while(output_locked);
+
+ /* something weird happened and the value changed between the loop and here */
+ if(!output_locked)
+ {
+ output_locked = 1;
+ write(client_fd, buf, len);
+ output_locked = 0;
+ done_printing = 1;
+ }
+ else
+ goto try_again;
}
void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
@@ -18,6 +32,11 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
out_raw((unsigned char*)buf, len);
}
+void send_master(unsigned char cmd)
+{
+ write(to_parent, &cmd, 1);
+ kill(getppid(), SIGUSR1);
+}
#define BUFSZ 128
@@ -58,16 +77,35 @@ void all_upper(char *s)
}
}
-volatile sig_atomic_t done_printing;
-
void sigusr2_handler(int s)
{
(void) s;
+ printf("got SIGUSR2\n");
+ unsigned char cmd;
+ read(from_parent, &cmd, 1);
unsigned char buf[MSG_MAX + 1];
- size_t len = read(from_parent, buf, MSG_MAX);
- buf[MSG_MAX] = '\0';
- out_raw(buf, len);
- done_printing = 1;
+ switch(cmd)
+ {
+ case REQ_BCASTMSG:
+ {
+ printf("reading...\n");
+ size_t len = read(from_parent, buf, MSG_MAX);
+ printf("done reading\n");
+ buf[MSG_MAX] = '\0';
+ out_raw(buf, len);
+ break;
+ }
+ case REQ_KICK:
+ {
+ size_t len = read(from_parent, buf, MSG_MAX);
+ buf[MSG_MAX] = '\0';
+ out_raw(buf, len);
+ exit(EXIT_SUCCESS);
+ }
+ default:
+ fprintf(stderr, "WARNING: client process received unknown request\n");
+ break;
+ }
}
void client_change_state(int state)
@@ -94,6 +132,8 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
to_parent = to;
from_parent = from;
+ output_locked = 0;
+
signal(SIGUSR2, sigusr2_handler);
telnet_init();
@@ -197,7 +237,7 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
out("Usage: USER DEL <USERNAME>\n");
}
}
- else if(!strcmp(what, "ADD") || !strcmp(what, "PASS"))
+ else if(!strcmp(what, "ADD") || !strcmp(what, "MODIFY"))
{
char *user = strtok_r(NULL, WSPACE, &save);
if(user)
@@ -231,7 +271,7 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
free(pass);
}
else
- out("Usage: USER ADD|CHANGE <USERNAME>\n");
+ out("Usage: USER <ADD|MODIFY> <USERNAME>\n");
}
else if(!strcmp(what, "LIST"))
{
@@ -242,6 +282,10 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
{
char *what = strtok_r(NULL, WSPACE, &save);
all_upper(what);
+ if(!what)
+ {
+ out("Usage: CLIENT <LIST|KICK> <PID>\n");
+ }
if(!strcmp(what, "LIST"))
{
done_printing = 0;
@@ -251,7 +295,28 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
waitpid(-1, NULL, 0);
while(!done_printing);
}
+ else if(!strcmp(what, "KICK"))
+ {
+ char *pid_s = strtok_r(NULL, WSPACE, &save);
+ if(pid_s)
+ {
+ unsigned char cmd_code = REQ_KICK;
+ write(to_parent, &cmd_code, sizeof(cmd_code));
+ pid_t pid = strtol(pid_s, NULL, 0);
+ write(to_parent, &pid, sizeof(pid));
+ char buf[128];
+ int len = snprintf(buf, sizeof(buf), "You were kicked.\n");
+ write(to_parent, buf, len);
+ kill(getppid(), SIGUSR1);
+ }
+ else
+ out("Usage: CLIENT KICK <PID>\n");
+ }
}
+ //else if(!strcmp(tok, "HANG"))
+ //{
+ // send_master(REQ_HANG);
+ //}
}
if(!strcmp(tok, "QUIT") || !strcmp(tok, "EXIT"))