diff --git a/include/parse.h b/include/parse.h index 26efe7a..ef5de1f 100644 --- a/include/parse.h +++ b/include/parse.h @@ -17,6 +17,7 @@ DECL char * raw(char const * const sql); DECL char * remind(char * who); DECL char * slurp(char const * fn); DECL int is_admin(char const * user); +DECL void parse_admins(char * admin_string); DECL int parse_pair(char const * buf, size_t const len); DECL void creds_free_password(void); DECL void creds_free_rest(void); diff --git a/src/parse.c b/src/parse.c index b739e25..05a87ac 100644 --- a/src/parse.c +++ b/src/parse.c @@ -26,7 +26,7 @@ #include "help.h" #include "parse.h" -#define PARAMS_COUNT 5 +#define PARAMS_COUNT 6 enum cred_param_ids_e { @@ -34,7 +34,8 @@ enum cred_param_ids_e PASSWORD, CHANNEL, SERVER, - PORT + PORT, + ADMINS }; char const * cred_names[] = @@ -43,7 +44,8 @@ char const * cred_names[] = "password", "channel", "server", - "port" + "port", + "admins" }; size_t const cred_names_len[] = @@ -52,7 +54,8 @@ size_t const cred_names_len[] = 8, 7, 6, - 4 + 4, + 6 }; creds_t creds = {0}; @@ -189,6 +192,10 @@ parse_pair(char const * buf, size_t len) case CHANNEL: creds.channel = strndup(buf,x); break; case SERVER: creds.server = strndup(buf,x); break; case PORT: creds.port = atoi(buf); break; + + case ADMINS: + parse_admins(strndup(buf,x)); + break; } if (x + 2 < len) { buf += x + 1; } @@ -203,6 +210,39 @@ parse_pair(char const * buf, size_t len) return 0; } +/* WARNING: admin_string WILL be changed */ +DECL void +parse_admins(char * admin_string) +{ + #define ADMIN_LIST_INIT_SIZE 8 + /* prealloc with 8 */ + size_t current_array_size = ADMIN_LIST_INIT_SIZE; + + size_t i = 0; + char * token = NULL; + + admins = calloc(ADMIN_LIST_INIT_SIZE, sizeof(char *)); + + while ((token = strtok(admin_string, " "))) + { + if (++i > current_array_size) + { + /* double the space */ + current_array_size *= 2; + admins = realloc(admins, current_array_size); + } + + admins[i - 1] = strdup(token); + } + + /* set up array end marker for proper clean-up later */ + if (i + 1 > current_array_size) + { + admins = realloc(admins, current_array_size + 1); + } + admins[i] = NULL; +} + DECL int is_admin(char const * user) {