From 6e8b01b9eed1710891368772d9cd02a41aa88e07 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Thu, 18 Jun 2009 17:17:45 +0000 Subject: [PATCH] * Fleshed out the ctdlsh interface a bit. Right now it's just a simple shell that logs in to the server, authenticates as an internal program, and allows the user to enter protocol commands. In the future we'll probably add some other stuff to it. Or I might get bored and never touch it again. Who knows? --- ctdlsh/src/Makefile.am | 2 +- ctdlsh/src/Makefile.in | 2 +- ctdlsh/src/ctdlsh.h | 28 ++++++++++++ ctdlsh/src/main.c | 99 +++++++++++++++++++++++++++++++++++++----- ctdlsh/src/sockets.c | 13 ++++++ 5 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 ctdlsh/src/ctdlsh.h diff --git a/ctdlsh/src/Makefile.am b/ctdlsh/src/Makefile.am index 786948c0f..deaf0dbde 100644 --- a/ctdlsh/src/Makefile.am +++ b/ctdlsh/src/Makefile.am @@ -4,4 +4,4 @@ ##/ bin_PROGRAMS = ctdlsh -ctdlsh_SOURCES = main.c sockets.c +ctdlsh_SOURCES = main.c sockets.c ctdlsh.h diff --git a/ctdlsh/src/Makefile.in b/ctdlsh/src/Makefile.in index 1abc17182..e25aeb01c 100644 --- a/ctdlsh/src/Makefile.in +++ b/ctdlsh/src/Makefile.in @@ -139,7 +139,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -ctdlsh_SOURCES = main.c sockets.c +ctdlsh_SOURCES = main.c sockets.c ctdlsh.h all: all-am .SUFFIXES: diff --git a/ctdlsh/src/ctdlsh.h b/ctdlsh/src/ctdlsh.h new file mode 100644 index 000000000..48524bebe --- /dev/null +++ b/ctdlsh/src/ctdlsh.h @@ -0,0 +1,28 @@ +/* + * This is a small subset of 'struct config' ... don't worry about the rest; we + * only need to snarf the c_ipgm_secret. + */ +struct partial_config { + char c_nodename[16]; /* Unqualified "short" nodename */ + char c_fqdn[64]; /* Fully Qualified Domain Name */ + char c_humannode[21]; /* Long name of system */ + char c_phonenum[16]; /* Dialup number of system */ + uid_t c_ctdluid; /* UID under which we run Citadel */ + char c_creataide; /* room creator = room aide flag */ + int c_sleeping; /* watchdog timer setting */ + char c_initax; /* initial access level */ + char c_regiscall; /* call number to register on */ + char c_twitdetect; /* twit detect flag */ + char c_twitroom[128]; /* twit detect msg move to room */ + char c_moreprompt[80]; /* paginator prompt */ + char c_restrict; /* restrict Internet mail flag */ + long c_niu_1; /* (not in use) */ + char c_site_location[32]; /* physical location of server */ + char c_sysadm[26]; /* name of system administrator */ + char c_niu_2[15]; /* (not in use) */ + int c_setup_level; /* what rev level we've setup to */ + int c_maxsessions; /* maximum concurrent sessions */ + char c_ip_addr[20]; /* IP address to listen on */ + int c_port_number; /* Cit listener port (usually 504) */ + int c_ipgm_secret; /* Internal program authentication */ +}; diff --git a/ctdlsh/src/main.c b/ctdlsh/src/main.c index 876b8e0f4..2658b7374 100644 --- a/ctdlsh/src/main.c +++ b/ctdlsh/src/main.c @@ -7,21 +7,101 @@ #include #include #include +#include +#include #include +#include "ctdlsh.h" + +#define CTDLDIR "/root/ctdl/trunk/citadel" + + +int discover_ipgm_secret(void) { + int fd; + struct partial_config ccc; + + fd = open(CTDLDIR "/citadel.config", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "citadel.config: %s\n", strerror(errno)); + return(-1); + } + + if (read(fd, &ccc, sizeof(struct partial_config)) != sizeof(struct partial_config)) { + fprintf(stderr, "citadel.config: %s\n", strerror(errno)); + return(-1); + } + if (close(fd) != 0) { + fprintf(stderr, "citadel.config: %s\n", strerror(errno)); + return(-1); + } + return(ccc.c_ipgm_secret); +} + + +void do_main_loop(int server_socket) { + char *cmd = NULL; + char prompt[1024]; + char buf[1024]; + char server_reply[1024]; + int i; + + strcpy(prompt, "> "); + + /* Do an INFO command and learn the hostname for the prompt */ + sock_puts(server_socket, "INFO"); + sock_getln(server_socket, buf, sizeof buf); + if (buf[0] == '1') { + i = 0; + while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) { + if (i == 1) { + sprintf(prompt, "\n%s> ", buf); + } + ++i; + } + } + + /* Here we go ... main command loop */ + while (cmd = readline(prompt)) { + + if ((cmd) && (*cmd)) { + add_history(cmd); + + sock_puts(server_socket, cmd); + sock_getln(server_socket, server_reply, sizeof server_reply); + printf("%s\n", server_reply); + + if ((server_reply[0] == '4') || (server_reply[0] == '8')) { + // FIXME + } + + if ((server_reply[0] == '1') || (server_reply[0] == '8')) { + while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) { + printf("%s\n", buf); + } + } + + } + + free(cmd); + } +} int main(int argc, char **argv) { - char *cmd = NULL; - char *prompt = "> "; int server_socket = 0; char buf[1024]; + int ipgm_secret = (-1); printf("\nCitadel administration shell v" PACKAGE_VERSION "\n"); printf("(c) 2009 citadel.org GPLv3\n"); + ipgm_secret = discover_ipgm_secret(); + if (ipgm_secret < 0) { + exit(1); + } + printf("Attaching to server...\r"); fflush(stdout); - server_socket = uds_connectsock("/root/ctdl/trunk/citadel/citadel.socket"); + server_socket = uds_connectsock(CTDLDIR "/citadel.socket"); if (server_socket < 0) { exit(1); } @@ -30,16 +110,13 @@ int main(int argc, char **argv) sock_getln(server_socket, buf, sizeof buf); printf("%s\n", buf); - while (cmd = readline(prompt)) { - - if ((cmd) && (*cmd)) { - add_history(cmd); - } + sock_printf(server_socket, "IPGM %d\n", ipgm_secret); + sock_getln(server_socket, buf, sizeof buf); + printf("%s\n", buf); - printf("\nHaha, you said: '%s'\n\n", cmd); - free(cmd); + if (buf[0] == '2') { + do_main_loop(server_socket); } - printf("\r"); sock_puts(server_socket, "QUIT"); sock_getln(server_socket, buf, sizeof buf); diff --git a/ctdlsh/src/sockets.c b/ctdlsh/src/sockets.c index f949fe0eb..1f3ad78ea 100644 --- a/ctdlsh/src/sockets.c +++ b/ctdlsh/src/sockets.c @@ -15,6 +15,7 @@ #include #include #include +#include "ctdlsh.h" #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff @@ -167,3 +168,15 @@ int sock_puts(int sock, char *buf) } +void sock_printf(int sock, const char *format,...) +{ + va_list arg_ptr; + char buf[4096]; + size_t len; + + va_start(arg_ptr, format); + vsnprintf(buf, sizeof buf, format, arg_ptr); + va_end(arg_ptr); + + sock_write(sock, buf, strlen(buf)); +} -- 2.30.2