Exemple #1
0
bool Log_WriteMsg(const char *InStream, MessageType MType)
{
	char OutBuf[2048], Origin[2048], Message[2048];
	char Nick[128], Ident[128], Mask[128], *Worker = Origin;
	
	if (MType == IMSG_TOPIC) return Log_TopicLog(InStream);
	else if (MType == IMSG_MODE) return Log_ModeLog(InStream);
	
	if (!IRC_BreakdownNick(InStream, Nick, Ident, Mask) || !*Nick || !*Ident || !*Mask) return true;
		
	IRC_GetMessageData(InStream, Origin);
	
	
	if (MType != IMSG_JOIN && MType != IMSG_QUIT && MType != IMSG_NICK && MType != IMSG_PART)
	{
		Worker = strchr(Worker, ' ');
		*Worker++ = '\0';
		
		while (*Worker == ' ' ) ++Worker;
		
		if (*Worker == ':') ++Worker;
		
		strncpy(Message, Worker, sizeof Message - 1);
		Message[sizeof Message - 1] = '\0';
	}
	
	if (MType == IMSG_PART || MType == IMSG_JOIN) /*I really doubt I'll ever see that on a JOIN.*/
	{
		if ((Worker = strstr(Origin, " :"))) *Worker = '\0';
	}
	else if (MType == IMSG_KICK)
	{
		if ((Worker = strstr(Message, " :"))) *Worker = '\0';
	}

	switch (MType)
	{		
		case IMSG_PRIVMSG:
			if (!strncmp(Message, "\01ACTION", strlen("\01ACTION")))
			{
				char *Temp =  strchr(Message + 1, '\01');
				
				if (Temp) *Temp = '\0';
				
				snprintf(OutBuf, sizeof OutBuf, "(%s) **%s %s**",
						*Origin == '#' ? Origin : Nick, Nick, Message + strlen("\01ACTION "));
			}
			else snprintf(OutBuf, sizeof OutBuf, "(%s) <%s>: %s", *Origin == '#' ? Origin : Nick, Nick, Message);
			break;
		case IMSG_NOTICE:
			snprintf(OutBuf, sizeof OutBuf, "(%s) <%s> (notice): %s", *Origin == '#' ? Origin : Nick, Nick, Message);
			break;
		case IMSG_JOIN:
			snprintf(OutBuf, sizeof OutBuf, "<%s!%s@%s joined %s>", Nick, Ident, Mask, Origin);
			break;
		case IMSG_PART:
			snprintf(OutBuf, sizeof OutBuf, "<%s!%s@%s left %s>", Nick, Ident, Mask, Origin);
			break;
		case IMSG_KICK:
			snprintf(OutBuf, sizeof OutBuf, "<%s was kicked from %s by %s>", Message, Origin, Nick);
			break;
		case IMSG_NICK:
		case IMSG_QUIT:
		{
			struct ChannelTree *Worker = Channels;
			
			if (MType == IMSG_QUIT)
			{
				snprintf(OutBuf, sizeof OutBuf, "<%s!%s@%s has quit: %s>", Nick, Ident, Mask, *Origin == ':' ? Origin + 1 : Origin);
			}
			else
			{
				snprintf(OutBuf, sizeof OutBuf, "<%s is now known as %s>", Nick, Origin);
			}
			
			if (!Channels)
			{
				Log_CoreWrite(OutBuf, Nick);
				return true;
			}
			
			for (; Worker; Worker = Worker->Next)
			{
				if (IRC_UserInChannelP(Worker, Nick))
				{
					Log_CoreWrite(OutBuf, Worker->Channel);
					NoLogToConsole = true;
				}
			}
			
			NoLogToConsole = false;
			return true;
		}
		default:
			return false;
	}

	Log_CoreWrite(OutBuf, *Origin == '#' ? Origin : Nick);
	
	return true;
}
Exemple #2
0
static bool Main_GenConfig(void)
{
	FILE *Descriptor = NULL;
	char LineBuf[4096], CurChan[128], *Worker = LineBuf;
	char FileBuf[16384] = { '\0' }; /*16K max config size for generator. Should be ridiculously more than enough.*/
	register unsigned Inc = 0;
	char Nick[128], Ident[128], Mask[128];
	char OutBuf[sizeof LineBuf + 128], OutPath[256];
	struct stat FileStat;
	
	puts("Generating a config file as per your request.\n"
		"I'll need some information from you now.\n");
	
	printf("What is the hostname of the IRC server? e.g. irc.myserver.net\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	
	snprintf(OutBuf, sizeof OutBuf, "Hostname=%s\n", LineBuf);
	SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
	
	printf("What is the port number of the IRC server?\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	snprintf(OutBuf, sizeof OutBuf, "PortNum=%s\n", LineBuf);
	SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
	
	printf("What nickname do you want to give the bot?\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	snprintf(OutBuf, sizeof OutBuf, "Nick=%s\n", LineBuf);
	SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
	
	printf("What ident do you want to give the bot?\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	snprintf(OutBuf, sizeof OutBuf, "Ident=%s\n", LineBuf);
	SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
	
	printf("What do you want the 'real name' of the bot to be?\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	snprintf(OutBuf, sizeof OutBuf, "RealName=%s\n", LineBuf);
	SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
	
	printf("Please enter a list of channels separated by spaces.\n"
			"Put a comma followed by a prefix to specify a command prefix for that channel.\n--> ");
			
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	
	if (*LineBuf)
	{
		do
		{
			for (Inc = 0; Worker[Inc] != ' ' && Worker[Inc] != '\0' && Inc < sizeof CurChan - 1; ++Inc)
			{
				CurChan[Inc] = Worker[Inc];
			}
			CurChan[Inc] = '\0';
			
			snprintf(OutBuf, sizeof OutBuf, "Channel=%s\n", CurChan);
			SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
			printf("Added channel %s\n", CurChan);			
		} while ((Worker = SubStrings.Line.WhitespaceJump(Worker)));
	}
	
LLogging:
	printf("Do you want to enable logging? Please enter y or n.\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	
	switch (tolower(*LineBuf))
	{
		case 'y':
			snprintf(OutBuf, sizeof OutBuf, "Logging=true\n");
			SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
		LLogPMs:
			printf("Do you want to log private messages sent to the bot? Please enter y or n.\n--> ");
			
			fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
			
			switch (tolower(*LineBuf))
			{
				case 'y':
					snprintf(OutBuf, sizeof OutBuf, "LogPMs=true\n");
					SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
					break;
				case 'n':
					snprintf(OutBuf, sizeof OutBuf, "LogPMs=false\n");
					SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
					break;
				default:
					putchar('\n');
					goto LLogPMs;
					break;
			}
			
			break;
		case 'n':
			snprintf(OutBuf, sizeof OutBuf, "Logging=false\n");
			SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
			break;
		default:
			goto LLogging;
			break;
	}
OwnerGet:
	printf("Enter a user's vhost to be bot 'owner', which is of the format 'nick!ident@ip_or_hostmask'.\n"
			"Wildcard '*' is accepted if it denotes an entire field as wild.\n--> ");
	
	fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
	
	if (!IRC_BreakdownNick(LineBuf, Nick, Ident, Mask))
	{
		puts("That's not a valid vhost. Try again.");
		goto OwnerGet;
	
	
	}

	snprintf(OutBuf, sizeof OutBuf, "BotOwner=%s!%s@%s\n", Nick, Ident, Mask);
	SubStrings.Cat(FileBuf, OutBuf, sizeof FileBuf);
	
	printf("A config file has been generated, but now we need a place to save it.\n"
		"Enter a filename for the new config file. aqu4bot.conf is what it should be\n"
		"named if you intend to use this config file.\n--> ");
	
	fgets(OutPath, sizeof OutPath, stdin); OutPath[strlen(OutPath) - 1] = '\0';
	
	
	if (stat(OutPath, &FileStat) == 0)
	{
		Bot_SetTextColor(YELLOW);
		printf("WARNING: ");
		Bot_SetTextColor(ENDCOLOR);
		
		printf("The config file \"%s\" already exists! Overwrite it?\n"
			"Please enter y or n\n--> ", OutPath);
		
		fgets(LineBuf, sizeof LineBuf, stdin); LineBuf[strlen(LineBuf) - 1] = '\0';
		
		if (tolower(*LineBuf) != 'y')
		{
			puts("Aborting, not overwriting the config file.");
			return false;
		}
	}
	
	Bot_SetTextColor(YELLOW);
	printf("Writing config file to \"%s\"...\n", OutPath);
	Bot_SetTextColor(ENDCOLOR);
	
	if (!(Descriptor = fopen(OutPath, "w")))
	{
		Bot_SetTextColor(RED);
		puts("\nFailed to save config file!");
		Bot_SetTextColor(ENDCOLOR);
		
		puts("Make sure it's a valid location,\nand that you have permission to write there.");
		return false;
	}
	
	/*Add a bit of help at the top of the file.*/
	fprintf(Descriptor, "#aqu4bot config file generated with --genconfig option.\n\n"
			"#Other options include:\n"
			"#NickservPwd=Nickserv Password\n"
			"#Prefix=$ (The global command prefix)\n"
			"#SendDelay=8 (tenths of a second to wait between sending messages)\n"
			"#SetBotmode=true/false (some networks request you set a special mode for your IRC bots.)\n"
			"#Admin=nick!ident@mask (Add a less privileged admin who can administrate channels etc,\n"
			"#but not administrate the bot itself.)\n"
			"#NoControlCodes=true/false (some networks will not allow you bold/etc.\n");
	fwrite(FileBuf, 1, strlen(FileBuf), Descriptor);
	
	fflush(NULL); fclose(Descriptor);
	
	Bot_SetTextColor(GREEN);
	puts("Done!");
	Bot_SetTextColor(ENDCOLOR);
	
	return true;
}
Exemple #3
0
void IRC_Loop(void)
{ /*Most of the action is triggered here.*/
	char MessageBuf[2048];
	
	while (1)
	{
		if (!Net_Read(SocketDescriptor, MessageBuf, sizeof MessageBuf, true))
		{ /*No command should ever call Net_Read() besides us and the connecting stuff that comes before us.*/
			puts("\033[31mCONNECTION LOST\033[0m");
			close(SocketDescriptor);
			exit(1);
		}
		
		if (!strncmp(MessageBuf, "PING ", strlen("PING "))) IRC_Pong(MessageBuf); /*Respond to pings.*/
		
		switch (IRC_GetMessageType(MessageBuf))
		{
			char Nick[1024], Ident[1024], Mask[1024];

			case IMSG_PRIVMSG:
			{
				char MessageData[2048], *TC = NULL, Channel[1024];
				unsigned long Inc = 0;
								
				if (!IRC_BreakdownNick(MessageBuf, Nick, Ident, Mask)) continue;
				IRC_GetMessageData(MessageBuf, MessageData);
				
				if (Auth_IsBlacklisted(Nick, Ident, Mask)) continue; /*Says "you are not going to be listened to bud.*/
				
				if (strcmp(Nick, ServerInfo.Nick) != 0) Log_WriteMsg(MessageBuf, IMSG_PRIVMSG);
				
				for (; MessageData[Inc] != ' ' && MessageData[Inc] && Inc < sizeof Channel - 1; ++Inc)
				{
					Channel[Inc] = MessageData[Inc];
				}
				Channel[Inc] = '\0';
				
				TC = strchr(MessageData, ' ') + 1;
				
				if (*TC == ':') ++TC;
				
				if (*TC == 0x01)
				{ /*IRC escape code thingy...*/
					
					if (!strcmp(TC, "\01VERSION\01"))
					{
						IRC_Notice(Nick, "\01VERSION aqu4bot " BOT_VERSION "\01");
					}
					else if (!strncmp(TC, "\01PING", strlen("\01PING")))
					{
						IRC_Notice(Nick, TC);
					}
				}
				else
				{
					/*I don't feel like including time.h*/
					time_t time(time_t*);
										
					CMD_ProcessCommand(MessageBuf);
					
					if (strcmp(Nick, ServerInfo.Nick) != 0)
					{
						CMD_UpdateSeenDB(time(NULL), Nick, Channel, TC);
					}
				}
				break;
			}
			case IMSG_NOTICE:
				if (!IRC_BreakdownNick(MessageBuf, Nick, Ident, Mask)) continue;
				
				if (Auth_IsBlacklisted(Nick, Ident, Mask)) continue;
				
				if (strcmp(Nick, ServerInfo.Nick) != 0) Log_WriteMsg(MessageBuf, IMSG_NOTICE);
				
				break;				
			case IMSG_INVITE:
			{
				if (!IRC_BreakdownNick(MessageBuf, Nick, Ident, Mask)) continue;
				
				if (Auth_IsBlacklisted(Nick, Ident, Mask)) continue;
				
				if (Auth_IsAdmin(Nick, Ident, Mask, NULL))
				{
					const char *TWorker = MessageBuf;
					TWorker = strchr(TWorker, '#');
					
					if (!TWorker)
					{
						IRC_Message(Nick, "There is something wrong, and although you are an admin,"
									"your invite request is either malformed or it's my fault.");
						break;
					}
					
					IRC_Message(Nick, "Coming.");
					
					if (IRC_JoinChannel(TWorker)) IRC_AddChannelToTree(TWorker);
				}
				else
				{
					IRC_Message(Nick, "I'm sorry, I can only accept invite requests from my admins.");
				}
				break;
			}
			case IMSG_KICK:
			{
				char InBuf[2048], *Worker = InBuf;
				
				IRC_GetMessageData(MessageBuf, InBuf);
				
				Log_WriteMsg(MessageBuf, IMSG_KICK);
				
				if (!(Worker = strchr(InBuf, ' '))) break;
				
				*Worker = '\0';
				
				IRC_DelChannelFromTree(*InBuf == ':' ? InBuf + 1 : InBuf);
				break;
			}
			case IMSG_QUIT:
			{				
				if (!IRC_BreakdownNick(MessageBuf, Nick, Ident, Mask)) continue;
				
				if (!strcmp(Nick, ServerInfo.Nick))
				{
					IRC_Quit(NULL);
					IRC_ShutdownChannelTree();
					Auth_ShutdownAdmin();
					CMD_SaveSeenDB();
					Auth_ShutdownBlacklist();
					exit(0);
				}
				break;
			}
			case IMSG_JOIN:
			{
				
				if (!IRC_BreakdownNick(MessageBuf, Nick, Ident, Mask)) continue;
				
				Log_WriteMsg(MessageBuf, IMSG_JOIN);
				while (CMD_ReadTellDB(Nick));
				break;
			}
			case IMSG_PART:
				if (!IRC_BreakdownNick(MessageBuf, Nick, Ident, Mask)) continue;

				Log_WriteMsg(MessageBuf, IMSG_PART);
				break;
			case IMSG_NICK:
			{
				char NewNick[1024];

				IRC_GetMessageData(MessageBuf, NewNick);
				
				while (CMD_ReadTellDB(*NewNick == ':' ? NewNick + 1 : NewNick));
			}
			default:
				break;
		}
	}
}
Exemple #4
0
Bool Log_WriteMsg(const char *InStream, MessageType MType)
{
	FILE *Descriptor = NULL;
	char Filename[1024], OutBuf[2048], Origin[2048], Message[2048];
	char Nick[1024], Ident[1024], Mask[1024], *Worker = Origin;
	time_t Time = time(NULL);
	struct tm TimeStruct;
	char TimeString[1024];
	struct stat DirStat;
	
	if (!Logging) return true;
	
	if (!IRC_BreakdownNick(InStream, Nick, Ident, Mask) || !*Nick || !*Ident || !*Mask) return true;
		
	IRC_GetMessageData(InStream, Origin);
	
	if (*Origin != '#' && !LogPMs) return true;
	
	if (MType != IMSG_JOIN && MType != IMSG_PART)
	{
		Worker = strchr(Worker, ' ');
		*Worker++ = '\0';
		
		while (*Worker == ' ' ) ++Worker;
		
		if (*Worker == ':') ++Worker;
		
		strncpy(Message, Worker, sizeof Message - 1);
		Message[sizeof Message - 1] = '\0';
	}
	
	if (MType == IMSG_PART || MType == IMSG_JOIN) /*I really doubt I'll ever see that on a JOIN.*/
	{
		if ((Worker = strstr(Origin, " :"))) *Worker = '\0';
	}
	else if (MType == IMSG_KICK)
	{
		if ((Worker = strstr(Message, " :"))) *Worker = '\0';
	}
	
	if (stat("logs", &DirStat) != 0)
	{
		if (mkdir("logs", 0755) != 0) return false;
	}
	
	snprintf(Filename, sizeof Filename, "logs/%s.txt", *Origin == '#' ? Origin : Nick);
	
	gmtime_r(&Time, &TimeStruct);
	strftime(TimeString, sizeof TimeString, "[%Y-%m-%d %H:%M:%S UTC]", &TimeStruct);

	switch (MType)
	{		
		case IMSG_PRIVMSG:
			if (!strncmp(Message, "\01ACTION", strlen("\01ACTION")))
			{
				char *Temp =  strchr(Message + 1, '\01');
				
				if (Temp) *Temp = '\0';
				
				snprintf(OutBuf, sizeof OutBuf, "%s **%s %s**\n", TimeString, Nick, Message + strlen("\01ACTION "));
			}
			else snprintf(OutBuf, sizeof OutBuf, "%s %s: %s\n", TimeString, Nick, Message);
			break;
		case IMSG_NOTICE:
			snprintf(OutBuf, sizeof OutBuf, "%s %s (notice): %s\n", TimeString, Nick, Message);
			break;
		case IMSG_JOIN:
			snprintf(OutBuf, sizeof OutBuf, "%s <%s joined %s>\n", TimeString, Nick, Origin);
			break;
		case IMSG_PART:
			snprintf(OutBuf, sizeof OutBuf, "%s <%s left %s>\n", TimeString, Nick, Origin);
			break;
		case IMSG_KICK:
			snprintf(OutBuf, sizeof OutBuf, "%s <%s was kicked from %s by %s>\n", TimeString, Message, Origin, Nick);
			break;
		default:
			return false;
	}
	
	if (!(Descriptor = fopen(Filename, "a")))
	{
		return false;
	}
	
	fwrite(OutBuf, 1, strlen(OutBuf), Descriptor);
	fclose(Descriptor);
	
	return true;
}