Working on uthash

This commit is contained in:
Emil 2023-09-24 17:05:28 +00:00
parent 0a0a7bbaa9
commit 5c56c20c60
No known key found for this signature in database
GPG Key ID: 5432DB986FDBCF8A
5 changed files with 189 additions and 141 deletions

View File

@ -1,10 +1,10 @@
PROGN:=probotic
TARGET:=probotic
USER := probotic
PREFIX = /opt/${USER}/
CFLAGS:=-std=c99 -Wall -Wextra -Wpedantic -Wvla -Wshadow -Wundef
CPPFLAGS:=-I./lib/libircclient/include/ -Iinclude -D_GNU_SOURCE -DPROGN=\"${PROGN}\" -D_FORTIFY_SOURCE=2
CPPFLAGS:=-I./lib/libircclient/include/ -Iinclude -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 -DPROGN=\"${TARGET}\"
LDLIBS:=-lsqlite3
LIB:=./lib/libircclient/src/libircclient.o
@ -28,7 +28,7 @@ ifeq (${ENABLE_SSL},1)
LDLIBS += -lssl -lcrypto
endif
${PROGN}: include/config.h ${HDR} ${SRC}
${TARGET}: include/config.h ${HDR} ${SRC}
${LINK.c} -pipe ${LIB} src/unity.c -o $@ ${LDLIBS}
# do nothing but update them...
@ -38,7 +38,7 @@ include/config.h: config.mk.h
cp -f $< $@
clean:
-rm ${OBJ}
-rm ${TARGET}
${PREFIX}:
mkdir $@
@ -47,8 +47,8 @@ bootstrap:
make -C bootstrap
install: bootstrap ${PREFIX}
useradd ${USER} -r -s /sbin/nologin -d ${PREFIX} || true
install -v -g ${USER} -o ${USER} -m 744 ./bootstrap/data.sqlite ${PROGN} ${PREFIX}
useradd ${USER} -r -s /sbin/nologin -d ${PREFIX} || true # Bypass "Already Exists"
install -v -g ${USER} -o ${USER} -m 744 ./bootstrap/data.sqlite ${TARGET} ${PREFIX}
chown ${USER}:${USER} ${PREFIX} -R
uninstall:

View File

@ -10,3 +10,6 @@
/* Enables SSL support
* FIXME broken at the moment */
/* #define IRC_SSL_SUPPORT */
/* the bot that encompasses secondary users */
/* #define SECONDARY_NAMES_BOT "nil" */

262
src/irc.c
View File

@ -4,8 +4,6 @@
#define IRCMSG(msg) irc_cmd_msg(session, creds.channel, msg)
#define MAX(a,b) (a) > (b)
typedef struct
{
char * username;
@ -15,6 +13,13 @@ typedef struct
int port;
} creds_t;
typedef struct
{
const char * key;
int val;
UT_hash_handle hh;
} map_t;
VARDECL creds_t creds =
{
.username = NULL,
@ -28,6 +33,8 @@ VARDECL creds_t creds =
#endif /* !IRC_SSL_SUPPORT */
};
VARDECL map_t * map = NULL;
VARDECL char * ident_password = NULL;
VARDECL irc_session_t * session;
@ -45,12 +52,16 @@ IRC_GREEN "!reroll " IRC_STOP " : Rerolls assignment\n"
/* IRC_GREEN "!request " IRC_STOP " : Request personal project\n" */
IRC_GREEN "!remind " IRC_STOP " : Prints your assignment\n"
IRC_GREEN "!poll " IRC_STOP " : Start the democratic process (N message ...])\n"
IRC_GREEN "!vote " IRC_STOP " : Casts a vote (y/n [message ...])\n"
IRC_GREEN "!y " IRC_STOP " : Votes yes\n"
IRC_GREEN "!n " IRC_STOP " : Votes no\n"
IRC_GREEN "!stop " IRC_STOP " : Stop the current polling\n"
IRC_BLUE "!magic " IRC_STOP " : A random value at or below 100 or (N)\n";
IRC_BLUE "!magic " IRC_STOP " : (N) Who knows.\n"
IRC_GREEN "!dice " IRC_STOP " : (N or AdX format) Rolls dice.";
DECL void parse_command(char const * cmd);
DECL void parse_command(char * cmd);
#ifdef SECONDARY_NAMES_BOT
DECL size_t parse_secondary_username(char const * msg);
#endif /* SECONDARY_NAMES_BOT */
DECL char *
get_username(const char * origin)
@ -132,13 +143,13 @@ event_connect(irc_session_t * lsession,
DECL void
event_channel(irc_session_t * lsession,
char const * event,
char const * origin,
char const ** params,
char * event,
char * origin,
char ** params,
unsigned int count)
{
/* char const * channel = params[0]; */
char const * message = params[1];
char * message = params[1];
(void) lsession;
(void) event;
(void) origin;
@ -149,7 +160,9 @@ event_channel(irc_session_t * lsession,
{ return; }
printf("<%s> %s\n", current_username, message);
/* Detects any respecified names */
/* message += parse_secondary_username(message); */
#ifdef SECONDARY_NAMES_BOT
message += parse_secondary_username(message);
#endif /* SECONDARY_NAMES_BOT */
/* Parse commands */
if (*message == PREFIX_COMMAND_CHAR &&
message[1] != '\0')
@ -158,9 +171,53 @@ event_channel(irc_session_t * lsession,
current_username = NULL;
}
/* 'abc' SINGLE
'def ' SINGLE
'ghi jkl' MULTI */
int name_sort(const map_t * a,
const map_t * b)
{
return strcmp(a->key, b->key);
}
DECL void
parse_command_init(void)
{
size_t i;
static const char * commands[] =
{
"n", /* 0 */
"remind", /* 1 */
"y", /* 2 */
"help", /* 3 */
"magic", /* 4 */
"dice", /* 5 */
"reroll", /* 6 */
"poll", /* 7 */
"stop", /* 8 */
NULL
};
map_t * s;
for (i = 0; commands[i]; ++i)
{
s = (map_t *) malloc(sizeof(map_t));
s->key = strdup(commands[i]);
s->val = i;
HASH_ADD_STR(map, key, s);
}
HASH_SORT(map, name_sort);
}
DECL void
parse_command_free(void)
{
map_t * s, * tmp;
HASH_ITER(hh, map, s, tmp) {
HASH_DEL(map, s);
free((void*)s->key);
free(s);
}
}
#define DICE_DEFAULT 6
#define ARGMASK 16
DECL int
has_arg(char const * cmd)
@ -169,12 +226,12 @@ has_arg(char const * cmd)
while (isalnum(*cmd))
{
if (*cmd == '\0')
{ break; }
{ return 0; }
++cmd;
}
while (*cmd != '\0')
{
if (!isspace(*cmd))
if (isspace(*cmd))
{ return cmd - start; }
++cmd;
}
@ -182,117 +239,98 @@ has_arg(char const * cmd)
}
DECL void
parse_command(char const * cmd)
parse_command(char * cmd)
{
static int vote_count;
static int vote_count, vote;
int dice = DICE_DEFAULT;
size_t len = has_arg(cmd);
size_t i = 0;
char * msgswp = NULL;
/* size_t len = strlen(cmd); */
if (!(i = has_arg(cmd)))
char x;
char * arg = NULL;
char * msgswp;
map_t * s;
/* x = cmd[len]; */
/* fprintf(stderr, "%ld\n", len); */
/* cmd[len] = cmd[len] != '\0' ? '\0' : cmd[len]; */
/* HASH_FIND_STR(map, cmd, s); */
/* fprintf(stderr, "cmd: "); */
/* while (cmd[i]) */
/* { */
/* x = cmd[len]; */
/* cmd[len] = cmd[len] ? cmd[len] : '\0'; */
/* fprintf(stderr, "%c:%d ", cmd[i], cmd[i]); */
/* ++i; */
/* } */
/* cmd[len] = x; */
/* putchar('\n'); */
x = cmd[len];
if (len &&
cmd[len] != 0)
{ cmd[len] = '\0'; }
HASH_FIND_STR(map, cmd, s);
cmd[len] = x;
if (cmd[len])
{
printf("NARG Handling '%s'\n", cmd);
/* NO ARGUMENTS */
if (strncmp(cmd, "remind", 6) == 0)
arg = cmd + len;
}
if (arg) { fprintf(stderr, "arg: '%s'\n", arg); }
if (s)
{
if (arg) {s->val |= ARGMASK; }
switch (s->val)
{
case 0 : /* n */
case 2 : /* y */
vote = s->val - 1; /* I had to, man */
if (--vote_count)
{ ircmsg(creds.channel, "Votes remaining: %d", vote_count); }
else
{ ircmsg(creds.channel,
"poll: %s",
vote == 0 ? "UNDECIDED" :
vote > 0 ? "PASSED" :
"REJECTED"); }
break;
case 1 : /* remind */
msgswp = remind(current_username);
ircmsg(creds.channel, "%s: %s", current_username, msgswp);
}
else if (strncmp(cmd, "help", 4) == 0)
{ ircmsg(creds.channel, help_msg); }
else if (strncmp(cmd, "magic", 5) == 0)
{ ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % 100) + 1); }
#ifndef NO_VULN_COMMANDS
else if (strncmp(cmd, "dump", 4) == 0)
{
ircmsg(creds.channel, "%s: All projects:", current_username);
msgswp = dump();
ircmsg(creds.channel, msgswp);
}
#endif /* !NO_VULN_COMMANDS */
else if (strncmp(cmd, "reroll", 6) == 0)
{
break;
case 3 : /* help */
ircmsg(creds.channel, help_msg);
break;
case 4 : /* magic */
break;
case 5 | 16 :
dice = atoi(arg);
/* fallthrough */
case 5 : /* dice */
ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % dice) + 1);
break;
case 6 : /* reroll */
purge_assignments(current_username);
random_assign(current_username);
ircmsg(creds.channel, "%s: %s", current_username, remind(current_username));
}
else if (strncmp(cmd, "stop", 4) == 0)
{
break;
case 7 | ARGMASK : /* poll */
vote = 0;
vote_count = atoi(arg);
if (!vote_count)
case 7 : { ircmsg(creds.channel, "!poll NUMBER_OF_VOTES, What you're voting on"); }
else
{ ircmsg(creds.channel, "poll: start, vote with !y or !n"); }
break;
case 8 : /* stop */
if (vote_count)
{
ircmsg(creds.channel, "poll: stop");
vote_count = 0;
}
break;
default:
fprintf(stderr, "Unhandled match.\n");
}
}
else /* HAS ARGUMENTS */
{
printf("ARG Handling '%s'\n", cmd);
static int yes, no;
char const * const arg = cmd + i;
/* fprintf(stderr, "argoff: %p; i: %ld; arg: %sEOA\n", cmd + i + 1, i, arg); */
#ifndef NO_VULN_COMMANDS
if (strncmp(cmd, "raw", 3) == 0)
{
printf("RAW\n");
ircmsg(creds.channel, "%s: Executing SQL `%s'.", current_username, arg);
msgswp = raw(arg);
ircmsg(creds.channel, msgswp);
} else
#endif /* !NO_VULN_COMMANDS */
#if 0
if (strncmp(cmd, "repo", 4) == 0)
{
/* ircmsg(creds.channel, "%s: Setting project repository...", current_username); */
set_repo(creds.channel, arg);
msgswp = remind(creds.channel);
ircmsg(creds.channel, "%s: %s", current_username, msgswp);
}
#endif /* 0 */
if (strncmp(cmd, "magic", 5) == 0)
{ ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % atoi(arg)) + 1); }
else if (strncmp(cmd, "echo", 3) == 0)
{ ircmsg(creds.channel, "%s", arg); }
else if (strncmp(cmd, "poll", 4) == 0)
{
yes = no = 0;
vote_count = atoi(arg);
if (!vote_count)
{ ircmsg(creds.channel, "!poll NUMBER_OF_VOTES What your voting on ..."); }
else
{ ircmsg(creds.channel, "poll: start"); }
}
else if (strncmp(cmd, "vote", 4) == 0)
{
/* fprintf(stderr, "y%d n%d vote_count %d\n", yes, no, vote_count); */
if (vote_count)
{
switch (*arg)
{
case 'Y': case 'y': ++yes; break;
case 'N': case 'n': ++no; break;
default: ircmsg(creds.channel, "Unknown: '%c', use y/n", *arg); goto stop;
}
if (--vote_count)
{ ircmsg(creds.channel, "Votes remaining: %d", vote_count); }
else
{ ircmsg(creds.channel, "poll: %s", MAX(yes,no) ? "PASSED" : "REJECTED"); }
}
}
}
stop:
free(msgswp);
}
/* mutates current_username and returns positional offset to the first character that isn't related to the uname */
DECL size_t
parse_secondary_username(char const * msg)
{
int ret = 0;
#define SECONDARY_NAMES_BOT "cnile"
if (strcmp(current_username,SECONDARY_NAMES_BOT) == 0)
if (*msg == '<')
{ while (msg[++ret] != '\0' ||
msg[ret] != '>'); }
fprintf(stderr, "msg[ret] = %c", msg[ret]);
return ret;
}

View File

@ -1,5 +1,28 @@
/* main.c */
#define DECL static
#define VARDECL static
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include <libircclient.h>
#include <sqlite3.h>
#include <uthash.h>
#include "error.h"
#include "irccolors.h"
#include "config.h"
#include "stmt.c"
#include "api.c"
#include "irc.c"
#define VERSION_STRING "2"
/* Parses the format username[:password]@server[:port]
@ -43,6 +66,7 @@ rope(void)
if (session)
{ irc_destroy_session(session); }
api_rope();
parse_command_free();
}
/* All possible failures / successes wipe the password from memory. */
@ -51,9 +75,14 @@ init(void)
{
int ret = 0;
srand(time(NULL));
parse_command_init();
memset(&callbacks, 0, sizeof(callbacks));
callbacks.event_connect = event_connect;
callbacks.event_channel = event_channel;
callbacks.event_channel = (void (*)(struct irc_session_s *,
const char *,
const char *,
const char **,
unsigned int)) event_channel;
if(!api_init())
{
session = irc_create_session(&callbacks);

View File

@ -1,22 +0,0 @@
#define DECL static
#define VARDECL static
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include <libircclient.h>
#include <sqlite3.h>
#include "error.h"
#include "irccolors.h"
#include "config.h"
#include "stmt.c"
#include "api.c"
#include "irc.c"
#include "main.c"