311 lines
10 KiB
C
311 lines
10 KiB
C
#include <stdlib.h> // something for load_config function
|
|
|
|
#define CONFIG_INIT 0 // defined for load_config()
|
|
#define RETURN_STRUCT 1 // defined for load_config()
|
|
#define NICK_CHANGE 2 // defined for load_config()
|
|
|
|
typedef struct conf_sruct {
|
|
int status;
|
|
char *server; // !
|
|
char *channel; // !
|
|
int port;
|
|
char nick[129]; // max nick length is 128 + '\0'
|
|
char *username; // !
|
|
char *realname; // !
|
|
char *password; // !
|
|
int maxNickLength;
|
|
char *logPath; // !
|
|
char *link; // ! should be enough to store link
|
|
int reJoin; // 1 - yes, 0 - no
|
|
int floodTimeOut;
|
|
} configuration;
|
|
|
|
configuration * load_config(int run, char * nick_or_path) {
|
|
/*
|
|
* if run = CONFIG_INIT (0) we load config from the file
|
|
* if run = RETURN_STRUCT (1) we return configuration structure stored in this function
|
|
* if run = NICK_CHANGE (2) we overrite 'nick' at the configuration structure
|
|
*/
|
|
int i,j;
|
|
|
|
FILE *conf;
|
|
|
|
char *st; // WHAT THE FUCKING POINTER HERE? Dark side magic forces.
|
|
char **sta[2];
|
|
static configuration C; // returning structure
|
|
|
|
char confFilePath[PATH_MAX];
|
|
|
|
int checksum = 0;
|
|
|
|
// added
|
|
char tempChar;
|
|
size_t countLinesInFile = 0;
|
|
|
|
char **fArr = NULL;
|
|
size_t eN = 0;
|
|
|
|
// --*---
|
|
if (run == CONFIG_INIT) { // the first time call
|
|
if ( (conf = fopen("/etc/loperIRCLogBot/bot.conf","r")) != NULL)
|
|
printf("Using configuration file stored at /etc/loperIRCLogBot/bot.conf\n"
|
|
"Prefere using the one, stored in this folder? Just rename or delete the one from /etc...\n");
|
|
else {
|
|
strcpy(confFilePath, nick_or_path);
|
|
strcat(confFilePath, "bot.conf"); // add bot.conf to path-to-executable
|
|
|
|
if ( (conf = fopen(confFilePath,"r")) != NULL)
|
|
printf("Using configuration file stored at %s\n"
|
|
"Please note, configuration file also could be stored at '/etc/loperIRCLogBot/bot.conf' and have higher priority\n", confFilePath);
|
|
else {
|
|
C.status = -2; //unable to open file = -2
|
|
return &C;
|
|
}
|
|
}
|
|
// count a number of lines inside file
|
|
while ((tempChar = getc(conf)) != EOF){
|
|
if (tempChar == '\n')
|
|
countLinesInFile++; // this size should be used to define 2D array for using in getline();
|
|
}
|
|
rewind(conf); // Move read pointer to the beggining of our file
|
|
#ifdef DEBUG_LOG
|
|
printf("\nFile have %zu lines\n", countLinesInFile);
|
|
#endif
|
|
// end counting
|
|
if ((fArr = (char **) malloc(countLinesInFile*sizeof(char *))) == NULL){ // allocate 2D array
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
|
|
for (i = 0; i<countLinesInFile; i++){ // from 0 to end
|
|
// fArr[i] = NULL; // initialize by NULL to avoid undefined behavior.
|
|
if (getline(&fArr[i], &eN, conf) == -1){ // Error reading or EOF. Shouldn't be EOF.
|
|
C.status = -5;
|
|
return &C;
|
|
}
|
|
#ifdef DEBUG_LOG
|
|
printf("Alloc 4 string #%d:\t%zu\n",i, eN);
|
|
#endif
|
|
eN = 0;
|
|
}
|
|
fclose(conf);
|
|
|
|
#ifdef DEBUG_LOG
|
|
printf("______Content of the file______\n");
|
|
for (i = 0; i<countLinesInFile; i++) // from 0 to end
|
|
printf("%s", fArr[i]);
|
|
printf("________________________________\n");
|
|
#endif
|
|
/////////////////////////////////////
|
|
for (i=0;i<2;i++){ // TODO: check if we allocated memory or not: NULL if not
|
|
if ((sta[i] = (char **) malloc (countLinesInFile * sizeof(char *))) == NULL){ // TODO: optimization needed. 1D array for example
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
for (j=0;j<countLinesInFile;j++){
|
|
if ((sta[i][j] = (char *) malloc(sizeof(char *))) == NULL){ // STRLEN()
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
sta[i][j][0] = '\0';
|
|
}
|
|
}
|
|
/////////////////////////////////////
|
|
|
|
// Parsing configuration file - IF STRING DOESN'T HAVE ":" - SKIP IT
|
|
for (i=0;i<countLinesInFile;i++){ // Read all recieved fields
|
|
if ( strstr(fArr[i], ":") != NULL ) {
|
|
st = strtok(fArr[i], ": \t\n"); // if we can't get ANY parameter at the string, that have ":" inside, then skip this string
|
|
if (st != NULL){
|
|
sta[0][i] = (char *) realloc (sta[0][i], (strlen(st)+1) * sizeof(char *));
|
|
#ifdef DEBUG_LOG
|
|
printf("sta[0][%d] = %zu\n", i,strlen(st)+1 );
|
|
#endif
|
|
strcpy(sta[0][i],st);
|
|
|
|
st = strtok(NULL, " \t\n"); // if we see anything before 'space' \t or \n
|
|
|
|
if (st == NULL){ // if we had a first parameter in string, (no matter was it set before ":" or after)
|
|
// and don't have the second one,
|
|
C.status = -1; // then we ruin the chain and returning error. 'Status' of incorrect config-file = "-1"
|
|
return &C;
|
|
}
|
|
else {
|
|
sta[1][i] = (char *) realloc (sta[1][i], (strlen(st)+1) * sizeof(char *));
|
|
#ifdef DEBUG_LOG
|
|
printf("sta[1][%d] = %zu\n", i,strlen(st)+1 );
|
|
#endif
|
|
strcpy(sta[1][i], st);
|
|
|
|
if ( strstr(sta[0][i], "link") != NULL ){ // if it's 'link', then add here everything user wrote
|
|
st = strtok(NULL, "\n");
|
|
if (st != NULL){
|
|
sta[1][i] = (char *) realloc (sta[1][i], (strlen(sta[1][i])+2) * sizeof(char *) + (strlen(st)+1) * sizeof(char *));
|
|
#ifdef DEBUG_LOG
|
|
printf("sta[0][%d] = %zu\n", i,strlen(st)+1 );
|
|
#endif
|
|
strcat(sta[1][i], " ");
|
|
strcat(sta[1][i], st);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i=0;i<countLinesInFile;i++){
|
|
if ( strstr(sta[0][i], "server") != NULL )
|
|
checksum |= 1<<0;
|
|
else if ( strstr(sta[0][i], "channel") != NULL )
|
|
checksum |= 1<<1;
|
|
else if ( strstr(sta[0][i], "port") != NULL )
|
|
checksum |= 1<<2;
|
|
else if ( strstr(sta[0][i], "nick") != NULL )
|
|
checksum |= 1<<3;
|
|
else if ( strstr(sta[0][i], "username") != NULL )
|
|
checksum |= 1<<4;
|
|
else if ( strstr(sta[0][i], "realname") != NULL )
|
|
checksum |= 1<<5;
|
|
else if ( strstr(sta[0][i], "password") != NULL )
|
|
checksum |= 1<<6;
|
|
else if ( strstr(sta[0][i], "maxNickLength") != NULL )
|
|
checksum |= 1<<7;
|
|
else if ( strstr(sta[0][i], "logPath") != NULL )
|
|
checksum |= 1<<8;
|
|
else if ( strstr(sta[0][i], "link") != NULL )
|
|
checksum |= 1<<9;
|
|
else if ( strstr(sta[0][i], "reJoin") != NULL )
|
|
checksum |= 1<<10;
|
|
else if ( strstr(sta[0][i], "floodTimeOut") != NULL )
|
|
checksum |= 1<<11;
|
|
|
|
}
|
|
if (checksum != 0b111111111111){
|
|
C.status = checksum; // incorrect number of settings defined
|
|
return &C;
|
|
}
|
|
else {
|
|
// Format array for return in case we're all good
|
|
|
|
C.status = 0; // OK = 0.
|
|
|
|
for (i=0; i<countLinesInFile; i++){ // Good
|
|
if ((strcmp(sta[0][i], "server")) == 0){
|
|
if ((C.server = (char *) malloc (strlen(sta[1][i])+1 * sizeof(char *))) == NULL){ // NOTE: And never free();
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.server, sta[1][i]);
|
|
}
|
|
else if ( (strcmp(sta[0][i], "port")) == 0)
|
|
C.port = atoi(sta[1][i]);
|
|
else if ( (strcmp(sta[0][i], "channel")) == 0){
|
|
if ((C.channel = (char *) malloc (strlen(sta[1][i])+1 * sizeof(char *))) == NULL){ // NOTE: And never free();
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.channel, sta[1][i]);
|
|
}
|
|
else if ( (strcmp(sta[0][i], "nick")) == 0)
|
|
strcpy(C.nick, sta[1][i]);
|
|
else if ( (strcmp(sta[0][i], "username")) == 0){
|
|
if ((C.username = (char *) malloc (strlen(sta[1][i])+1 * sizeof(char *))) == NULL){ // NOTE: And never free();
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.username, sta[1][i]);
|
|
}
|
|
else if ( (strcmp(sta[0][i], "realname")) == 0){
|
|
if ((C.realname = (char *) malloc (strlen(sta[1][i])+1 * sizeof(char *))) == NULL){ // NOTE: And never free();
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.realname, sta[1][i]);
|
|
}
|
|
else if ( (strcmp(sta[0][i], "password")) == 0){
|
|
if ((C.password = (char *) malloc (strlen(sta[1][i])+1 * sizeof(char *))) == NULL){ // NOTE: And never free();
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.password, sta[1][i]);
|
|
}
|
|
else if ( (strcmp(sta[0][i], "maxNickLength")) == 0){
|
|
C.maxNickLength = atoi(sta[1][i]);
|
|
if (C.maxNickLength > 128){
|
|
C.maxNickLength = 128; // now idiots could feel themselfs protected. Libircclient restriction IIRC set to 128 chars
|
|
}
|
|
}
|
|
else if ( (strcmp(sta[0][i], "logPath")) == 0){
|
|
if (strcmp(sta[1][i], "0") == 0){
|
|
C.logPath = (char *) malloc (strlen(nick_or_path)+1 * sizeof(char *)); // NOTE: And never free();
|
|
strcpy(C.logPath, nick_or_path);
|
|
}
|
|
else {
|
|
if (sta[1][i][0] != '/'){
|
|
C.status = -3;
|
|
return &C;
|
|
}
|
|
else{
|
|
if ((C.logPath = (char *) malloc (strlen(sta[1][i])+2 * sizeof(char *))) == NULL){ // NOTE: And never free(); +2 to include variant, when '/' is needed
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.logPath, sta[1][i]);
|
|
if ( C.logPath[strlen(C.logPath)] != '/' )
|
|
strcat (C.logPath, "/");
|
|
}
|
|
}
|
|
}
|
|
else if ( (strcmp(sta[0][i], "link")) == 0){
|
|
if((C.link = (char *) malloc (strlen(sta[1][i])+1 * sizeof(char *))) == NULL){ // NOTE: And never free();
|
|
C.status = -4;
|
|
return &C;
|
|
}
|
|
strcpy(C.link, sta[1][i]);
|
|
}
|
|
else if ( (strcmp(sta[0][i], "reJoin")) == 0){
|
|
if (strcmp(sta[1][i], "yes") == 0 || strcmp(sta[i][1], "Yes") == 0 )
|
|
C.reJoin = 1;
|
|
else
|
|
C.reJoin = 0;
|
|
}
|
|
else if ( (strcmp(sta[0][i], "floodTimeOut")) == 0)
|
|
C.floodTimeOut = atoi(sta[1][i]);
|
|
}
|
|
if (strlen(C.nick) > C.maxNickLength)
|
|
C.nick[C.maxNickLength] = '\0'; // yeah, they will love it, before set nick name longer then 128 char =(
|
|
}
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
#ifdef DEBUG_LOG
|
|
printf("____Recieved keys____"
|
|
"\n______________________\n");
|
|
for (i=0;i<countLinesInFile; i++){
|
|
printf("%s - %s\n", sta[0][i], sta[1][i]);
|
|
}
|
|
printf("______________________\n");
|
|
#endif
|
|
|
|
// Free allocated arrays
|
|
for (i=0; i<countLinesInFile; i++)
|
|
free(fArr[i]);
|
|
free(fArr);
|
|
for (i=0;i<2;i++){
|
|
for (j=0;j<countLinesInFile;j++)
|
|
free(sta[i][j]);
|
|
}
|
|
for (i=0;i<2;i++)
|
|
free(sta[i]);
|
|
//end
|
|
|
|
return &C;
|
|
}
|
|
else if ( run == RETURN_STRUCT ){
|
|
return &C; // just return already loaded structure by request
|
|
}
|
|
else if ( run == NICK_CHANGE){ // save nick recieved
|
|
strcpy(C.nick, nick_or_path);
|
|
return &C;
|
|
}
|
|
}
|