Page MenuHomeDevCentral

No OneTemporary

diff --git a/docs/AUTHORS b/docs/AUTHORS
index 0ba36dc..cf166db 100644
--- a/docs/AUTHORS
+++ b/docs/AUTHORS
@@ -1,98 +1,98 @@
'My fellow Homo Sapiens, ask not what your Darkbot can do for you, ask what you can do for your Darkbot.'
-Darkbot is a volunteer runned project being managed, maintaigned, developed and supported by an altruistic group and by the users themselves on wich all contributions are made on the willingness of their contributors who manages their time and contributions the way they find more suitable to their own duties.
+Darkbot is a volunteer runned project being managed, maintained, developed and supported by an altruistic group and by the users themselves on which all contributions are made on the willingness of their contributors who manages their time and contributions the way they find more suitable to their own duties.
-How to contribute? You could make Darkbot better by bellonging to:
+How to contribute? You could make Darkbot better by belonging to:
Database Team: Build database entries.
Support Team: Being a Helper in Support Chat Room or Web Site, Making Tutorials, HowTOs, Tips&Tricks.
Tester Team: Testing current or Beta versions of the code in your preferred Operating System.
Translators Team: Translating the main code output text.
Developing Team: Code; Developing features, correcting malfunctions. How? Check Features Requests, Unsolved Buggs, Ideas.
-Or ponctually repport any malfunction, suggest a new feature, present an idea, make a review, correct any misspeled word, donate a server for running a specialized Darkbot.
+Or punctually report any malfunction, suggest a new feature, present an idea, make a review, correct any misspelled word, donate a server for running a specialized Darkbot.
Here are the ones who in one way or other, make Darkbot possible, by contributing with their time, skills or by donating services.
**** Darkbot Contributors ****
Author/Creator
Jason Hamilton (play) <jason@superlink.net>:
Project Administrator
Luiz Castelo-Branco <LuizCB@users.sourceforge.net>: Web Building, Database Building, Documentation, User Helping, Bash Utilities Script Coding on early releases, Portuguese Translation.
Lead Developer
David Seikel (onefang) <onefang@users.sourceforge.net>: A plethora of changes, modifications, and bug fixes since version 8rc2. Cleaning, fixing, featuring/creating Darkbot's 2014 revamping - too many to mention (check GIT commits or/and docs).
Developers with major contributions,
- Ron Robbins Jr. (ron) <mircsux@users.sourceforge.net>: Developer; A plethora of changes, modifications, and bug fixes since version 6f6.
- Paul (reet2) <paul@??>: Several major changes on 6f6 for release 7. Added the quiz stuff, and original googlefu nctionality.
-The following are people who acknowledgedly colaborated with Darkbot Project by coding features, submiting code patches, translating, guidind and helping users trough their difficulties, providing web presence for Darkbot Project.
+The following are people who acknowledgedly collaborated with Darkbot Project by coding features, submiting code patches, translating, guidind and helping users trough their difficulties, providing web presence for Darkbot Project.
(by alphanumeric name/nick order)(email addresses are being checked to be updated)
**** Code Patches ****
- [K]aka: [Code] A buffer overflow issue - 5-Beta7
- bow @ undernet: AddServer fix - 4-Alpha2
- Bart Jansens: Typo correction on Dutch language / prep 7 April 10, 2000
- BLightnin @ undernet: Datasearch fix; save topic duplicates suggestion of log PRIVMSG - 5-Beta7 4-Alpha2
- Dan (ripper_) @ undernet: Several major changes - 5f21,22,23,26
- Fouton <c592030@everest.cclabs.missouri.edu>: #define SGI -f18
- gavers @ undernet: Found 'pipe' on topics issue' - 5-Beta6 5-Beta1
- Gator @ superchat: 'fclose' issue - 5f3
- Kosh @ superchat: Implementation of WIN32 port
- nak @ superchat: VHOST support - 5f11
- Neil Darlow: Code optimization patches on info and check_permban on prep 7 - 3/22/2002
- Oleg <green@crimea.edu>: " repeated server stoned" and NEED_LIB5 corrections - 5f18 5f15
- rewpaul rew @ undernet: Fixed 'pipe' on topics; Q~ variable fix suggestion on mask function; Adduser fix;
- s0meguy @ undernet: found a missing variable April v. 5f22 -- 16, 23, 2000
wildcards on topics RANDOM_STUFF OFF on 'Sleep' ON - 5-Beta6 - 5-Beta3 4-Beta2 4-Beta1
- wx @ undernet: CTCP replies fix; suggest UP command - 5-Beta1 5-Alpha4
**** Translators ****
- [SoHo] <soho@int19h.com> [NORWEGIAN]
- Asmodai <asmodai@wxs.nl> [DUTCH]
- C.Hoegl@gmx.net & marc@reymann.net [GERMAN]
- Chris_CY <chriscy@cylink.net> [GREEK]
- Cloud <burtner@usa.net> [PIG LATIN][RUSSIAN - CP1251][RUSSIAN - KOI8 ]
- daniele nicolucci <jollino@icemail.it> [ITALIAN]
- Dan <dan@ntlbusiness.com> [DUTCH] [GERMAN]
- eCHaLoTTe <echalotte@cablevision.qc.ca> [FRENCH]
- EfX <michel.efx@globetrotter.net> [FRENCH]
- Inajira <inajira@videotron.ca> [FRENCH]
- James <jamespower@263.net> [CHINISE]
- Jason Hamiltton <jason@superlink.net> [ENGLISH]
- LuizCB <LuizCBl@users.sourceforge.net> [PORTUGUESE]
- MrSiMo <mrsimo7@yahoo.fr> [ARABIC]
- Oleg Drokin <green@ccssu.crimea.ua> [RUSSIAN - CP1251]
- Otaku <otaku@unixgeek.ml.org> [LATIN]
- rapsux <bitter@ici.net> [EBONICS]
- Radu <radu.negoescu@sante.univ-nantes.fr> [ROMANIAN]
- Raider <raider@superchat.ws> [GREEK]
- speed1 <speed@edure des.edu.do> [SPANISH]
- Ybznek <sunmo@seaside.se> [SWEDISH]
**** Helpers ****
- {SID_V}
- Alex99 Alex99@??
- Andre (Syntax6)
- baphomet
- BLightnin
- derv0
- juice
- Shaky
- TuEuR
**** Web Presence and other contributions ****
- Andre (Syntax6) has hosted Darkbot Web pages and donated DNS hosting on his servers.
- Jared Smith (juice) <juicebar@users.sourceforge.net>: Managed Darkbot's Web presence while Luiz Castelo-Branco was absent.
- LaZZ for providing a web site mirror.
- mark @ undernet: License usage agreement update - 4-Beta1
- Nenemis: Suggestion on notice help join greeting info - 5-Beta3
- Zaf @ superchat: Suggestion of RANDOM_STUFF Idle - 4-Beta1
SourceForge(.net), in being our official project and web site hosting service.
... and several other anonymous contributors.
If we are missing anyone or you find any incorrection please inform the Project Administrator.
To all, Darkbot Project thanks you very much.
diff --git a/docs/TODO b/docs/TODO
index b318163..1a0128e 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -1,204 +1,204 @@
----------------------------------------------------------
The TO-DO List For Darkbot
----------------------------------------------------------
These are features that are in the planning stages, or
that haven't been completely worked out, yet. Also, any
suggestions that people have made, that are planning to
be added, will be listed here.
Features and bugs are also being tracked via the sf.net
trackers at http://sourceforge.net/projects/darkbot
----------------------------------------------------------
- Freenode uses different identd syntax n=blah@host, update
masking to use this and remove the n= part.
- Make setnick command not spit out the message in room
about changing nicks after the effect.
- Add escape character for | in topic responses so you can
output a | rather than use multiline replies. Other places
need escape character options too.
- Add option to make the bot not kick/ban people who are
logged in with access to the bot.
- Add googlesque queries to search command, so you can
- excluse words from searches.
+ exclude words from searches.
- plural functions still needs to be implemented in spots,
about half of the functions use a different parsing
mechanism that still works, because I hadn't thought of
adding a "startarg" parameter to my db_argstostr()
function before that point. i will update these later.
- chanserv_topic function needs to be a private message
command and accept channel arguments (easy, but to
remember for later).
- atoi needs to be swapped for strtol in all places
since atoi isn't as safe.
- Some kind of solution for large numbers needs to be
worked out for use with the unixtime user command.
Implementations with 32 bit instead of 64 bit longs
are limited to time representations in a range
consisting of only up to one more place value than
the current unixtime, and is a system dependant
value.
- Add some kind of escape sequence or special parsing
for topics that start with key words like "WHAT", these
words are also recognized internally by the bot for
answering questions.
- Multi-channel randomstuffs. I want to make it possible
for every channel specified in setup.ini as the home
channel, in the case of multiple home channels, has
their own randomstuff timers that output randomstuffs
according to the action going on, for each specific
channel.
- Write things to replace the stuff that Windows can't do.
Backup command, etc.
- Make the output of the MEM command more useful and friendly.
- Add internet movie database (http://www.imdb.com) and
slashdot news (http://slashdot.org) searches.
- Single login, remembered across channel part/joins etc.
- Changing the bot's nick needs some testing and tweaking.
- IPv6.
- Merge acronym, 21, lurker, syndet, pantheon, and serv
into darkbot. All are linked to from the darkbot pages.
----------------------------------------------------------
onefang's TO-DO List For Darkbot
----------------------------------------------------------
Add a show parameters command.
Deal with scripts/dbcron one way or another.
Double check the in code summaries for setup parameters.
Allow multiple command characters - SETCHAR !'~
Convert use of the obsolete gethostbyname() to getaddrinfo().
The alarm() may not be portable enough. Replace multiple alarm() calls
with a single setitimer() call. Give alarm() the benefit of the doubt
for now.
The first argument passed to the various select() calls could be better,
it's more efficient to actually calculate that.
Add a callback to the webinfo structure and otherwise restructure the
web stuff so that disabling a web command can #ifdef out all the code for
that command.
Merge all the scripts plus convertdb into darkbot so that all admin
stuff can be done from IRC, command line, or text UI.
-Make the replaceable params in responses consistant. X~ and %X.
+Make the replaceable params in responses consistent. X~ and %X.
If possible, make all !set foo=bar stuff change the current state of the
bot rather than requiring a restart.
Scripting or modules. Scripting using Lua is a really good option.
A limited subset could be used for the calc command as well.
-Find a cross pratform Windows/unix GUI toolkit we can live with and
+Find a cross platform Windows/unix GUI toolkit we can live with and
create a GUI for darkbot admin. LCB wants a web based one. I just want
to make it modular, and allow different front ends.
Make multiple random responses easier to setup.
admin: bot add foo bar | baz | some other response
user: foo is also blah
admin: bot add foo | another answer
Menu in PM. Plain one liner, colour one liner, multiple lines, colour multiple lines.
user: /msg bot menu
- >bot<: Main menu - 1) factiod comands, 2) user commands, 3) channel commands, B) backup one menu, Q) quit menu.
+ >bot<: Main menu - 1) factoid commands, 2) user commands, 3) channel commands, B) backup one menu, Q) quit menu.
user: /msg bot menu big
>bot<: Main menu -
- >bot<: 1) factiod comands
+ >bot<: 1) factoid comands
>bot<: 2) user commands
>bot<: 3) channel commands
>bot<: B) backup one menu
>bot<: Q) quit menu.
Don't give long answers in channel, only in PM. Instead, give a summary
in channel, and inform user that a longer response is available via PM.
bot: summary of foo bar. (PM "foo bar" for more.)
luser: PM "foo bar"
bot: PM "foo bar" means to send me a private message you idiot. Try this command "/msg bot foo bar".
Make the bot gender definable, defaulting to female. Allow users to
register their gender. Auto convert all relevant text to proper gender.
Add memos "tell onefang that foo", as opposed to factoid telling "tell
onefang about bah". Allow memos to yourself. Fix alarm and tie that in
as well, alarms to others and to self. Limit memos & alarms to karma
memos & alarms per hour to limit abuse.
-Allow unlogged in users to create factiods, and change these factoids, plus
+Allow unlogged in users to create factoids, and change these factoids, plus
make additions to factoids.
luser: blah is humbug.
user: blah?
bot: luser tells me that blah is humbug. luser may have been drunk at the time.
luser: known fact is wrong.
user: what is known fact?
bot: Known fact is correct. On the other hand, luser thinks that known fact is wrong.
Channel logging, and playback to PM.
wtf, add a karma system.
use it to sort the unlogged user added factoids.
bot: luser tells me that blah is humbug. Others have more to say, but I trust luser more. (PM "blah" for more.)
Use it to refer people to the highest karma person.
bot: Dunno, ask High_Karma_Dude.
Use no karma and negative karma as extra security levels. No karma = -1, negative karma = (karma / 100) - 2
Keep track of how much she has been fed, deny taking food from strangers
-(low/no karama users). This implies that botsnack become an information command.
+(low/no karma users). This implies that botsnack become an information command.
data include files.
Keep track of what database include files are not used for a while, and unload
them, keeping the questions and a pointer to the file though.
Multiple server/channel support like xchat.
Allow different data per server/channel, using includes for common stuff.
Allow different setup per server/channel.
Keep track of unanswered questions, for two reasons -
So the admin can look through it later and add factiods if needed.
If the user is still around (and given a suitable timeout) answer the
question if an answer arrives.
Implement the Porter-Stemmer algorithm to improve English-language
-searching as per the drupal module of the same name. It reduces each
+searching as per the Drupal module of the same name. It reduces each
word in the index to its basic root or stem (e.g. 'blogging' to 'blog')
so that variations on a word ('blogs', 'blogger', 'blogging', 'blog')
are considered equivalent when searching. This generally results in
more relevant results. Also, start by stripping out all punctuation.
On the other hand, question marks mean it is more likely to be a
question. Same applies to use of the W words near the beginning, they
are more likely to be questions.
Add a locale to weather codes database or search facility. Combine all
the weather commands into one. Make it return metric results.
Command to guess a users timezone, and show time in that zone.
Random greetings, random channel topics, etc.
Interface other shell commands, but be secure. In fact, setup a chroot
for arbitrary shell commands.
Allow DCC to and from a file server.
Channel protection - mass join, mass kick.
diff --git a/source/chan.c b/source/chan.c
index 4354644..be0c9a5 100644
--- a/source/chan.c
+++ b/source/chan.c
@@ -1,610 +1,610 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
#ifdef ENABLE_MATH
/* Changed input to be unsigned instead of signed. This
* suppressed warning messages when compiling on Solaris.
*/
struct chanserv_output *do_math (const char *who, char *target, char *math)
{
char number_string[STRING_SHORT] = { 0 };
char op = 0;
unsigned char input[STRING_SHORT] = { 0 };
unsigned int index = 0;
unsigned int to = 0;
unsigned int input_length = 0;
unsigned int number_length = 0;
double result = 0.0;
double number = 0.0;
strncpy (input, math, sizeof (input));
input_length = strlen (input);
for (to = 0, index = 0; index <= input_length; index++)
if (*(input + index) != ' ')
*(input + to++) = *(input + index);
input_length = strlen (input);
index = 0;
if (input[index] == '=')
index++;
else
{
number_length = 0;
if (input[index] == '+' || input[index] == '-')
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
if (*(input + index) == '.')
{
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
}
*(number_string + number_length) = '\0';
if (number_length > 0)
result = atof (number_string);
}
for (; index < input_length;)
{
op = *(input + index++);
number_length = 0;
if (input[index] == '+' || input[index] == '-')
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
if (*(input + index) == '.')
{
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
}
*(number_string + number_length) = '\0';
number = atof (number_string);
switch (op)
{
case '+':
result += number;
break;
case '-':
result -= number;
break;
case '*':
result *= number;
break;
case '/':
if (number == 0)
{
L016 (target, who);
return;
}
else
result /= number;
break;
case '%':
if ((long) number == 0)
{
L016 (target, who);
return;
}
else
result = (double) ((long) result % (long) number);
break;
default:
L017 (target, who);
return;
}
}
return chanserv_asprintf(NULL, "%f\n", result);
}
#endif
long
cf (char *host, char *nick, char *chan)
{
int f_n = 0;
if (check_access (host, chan, 0, nick) >= 3)
return 0;
f_n = f_f (host);
if (f_n == -1)
{
a_f (host);
return 0;
}
if (ood[f_n].value)
return 1;
ood[f_n].count++;
if ((time (NULL) - ood[f_n].time) > FT)
ood[f_n].count = 0;
else if ((time (NULL) - ood[f_n].time) <= FT && ood[f_n].count >= FR)
{
ood[f_n].value = true;
if (!ood[f_n].kick)
{
ood[f_n].kick = 1;
if (*chan == '#' || *chan == '&')
{
#ifdef ENABLE_CHANNEL
if (FLOOD_KICK == true)
L018 (chan, nick, FLOOD_REASON, fc, host);
else
#endif
L019 (CHAN, fc, host);
}
else
L019 (CHAN, fc, host);
}
return 1;
}
ood[f_n].time = time (NULL);
return 0;
}
/**
* Update a nick's channel greeting and user@host.
* 6/23/00 Dan:
* - All method arguments are now pointers to const data
* - Rewrote to use a for loop, and fewer variables
* - Info is only saved to disk if changes are made
*/
void
update_setinfo (const char *new_uh, const char *new_greetz, const char *nick)
{
struct helperlist *c = helperhead;
bool madeChange = false;
size_t i = 0;
for (; c != NULL; c = c->next)
{
++i;
if (!match_wild (c->uh, new_uh) == 0)
{
strncpy (c->greetz, new_greetz, sizeof (c->greetz));
strlwr (c->uh);
L020 (nick, i, c->uh, new_greetz);
madeChange = true;
}
}
if (madeChange)
{
save_changes ();
}
}
/**
* 6/23/00 Dan:
* - All variables now initialized when declared
* - Altered variable types to reflect usage
*/
void
info (const char *source, char *target)
{
FILE *fp;
clock_t starttime = 0;
char b[STRING_LONG] = { 0 };
size_t topics = 0, dup = 0;
time_t t2time = 0, c_uptime = 0;
char *ptr = NULL, *subj = NULL;
char last[STRING_LONG] = { 0 };
t2time = time (NULL);
unlink (TMP_URL);
starttime = clock ();
fp = fopen (URL2, "r");
if (NULL == fp)
{
L003 (source, URL2);
return;
}
while (fgets (b, STRING_LONG, fp))
{
topics++;
if (FIND_DUPS)
{
if(*b == '\n')
continue;
stripline (b);
subj = strtok (b, " ");
ptr = strtok (NULL, "");
strlwr (subj);
if (strcasecmp (last, subj) == 0)
{
dup++;
if (SAVE_DUPS)
db_log (BACKUP_DUP, "%s %s\n", subj, ptr);
}
else
{
db_log (TMP_URL, "%s %s\n", subj, ptr);
}
strncpy (last, subj, sizeof (last));
last[sizeof (last) - 1] = '\0';
}
}
fclose (fp);
rename (TMP_URL, URL2);
if ((FIND_DUPS) && (dup > 0))
{
L025 (target, dup);
}
c_uptime = time (NULL) - uptime;
topics -= dup;
if (c_uptime > 86400)
{
L026 (target,
dbVersion,
topics,
c_uptime / 86400,
(c_uptime / 86400 ==
1) ? "" : "s",
(c_uptime / 3600) % 24,
(c_uptime / 60) % 60, QUESTIONS,
ADDITIONS, DELETIONS,
(double) (clock () -
starttime) /
CLOCKS_PER_SEC, (((double) (clock () - starttime) / CLOCKS_PER_SEC) == 1) ? "" : "s");
}
else if (c_uptime > 3600)
{
L027 (target,
dbVersion,
topics,
c_uptime / 3600,
c_uptime / 3600 == 1 ? "" : "s",
(c_uptime / 60) % 60,
(c_uptime / 60) % 60 ==
1 ? "" : "s", QUESTIONS,
ADDITIONS, DELETIONS,
(double) (clock () -
starttime) /
CLOCKS_PER_SEC, (((double) (clock () - starttime) / CLOCKS_PER_SEC) == 1) ? "" : "s");
}
else
{
L028 (target,
dbVersion,
topics,
c_uptime / 60,
c_uptime / 60 == 1 ? "" : "s",
c_uptime % 60,
c_uptime % 60 == 1 ? "" : "s",
QUESTIONS, ADDITIONS, DELETIONS,
(double) (clock () - starttime) / CLOCKS_PER_SEC, (((double)
(clock () -
starttime) /
CLOCKS_PER_SEC) == 1) ? "" : "s");
}
//#ifdef ENABLE_STATS
// get_stats(target, NULL); */
//#endif
}
/**
* Output information about the bot's database to a target.
* 6/22 Dan:
* - Changed both method arguments to be pointers to const data,
* this is a read only method.
*/
struct chanserv_output *show_info2 (const char *target, const char *source, enum chanserv_invoke_type invoked)
{
return chanserv_asprintf(NULL, "Compiled on %s. I have processed %ld lines of text since startup...", __DATE__, NUMLINESSEEN);
}
/**
* 6/23/00 Dan:
* - All method arguments are now pointer to const
* - Return type is now time_t
* - A for loop is now used instead of a while loop
*/
time_t
return_useridle (const char *chan, const char *who, int toggle)
{ /* toggle=0 is for idle time, toggle=1 is to check if user
is in the chan */
const struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
if (!strcasecmp (who, c->nick) && !strcasecmp (chan, c->chan))
{
if (toggle == 1)
{
/* If we only care if user is present or not.. */
return 1;
}
else
return c->idle;
} /* if */
} /* for */
return 0;
}
void
process_nick (char *nick, char *newnick)
{
struct userlist *c;
c = userhead;
newnick++;
while (c)
{
if (strcasecmp (nick, c->nick) == 0)
{
strncpy (c->nick, newnick, sizeof (c->nick));
}
c = c->next;
}
// Check if it's our own bot nick being changed.
if (strcasecmp(nick, Mynick) == 0)
{
strncpy(Mynick, newnick, sizeof (Mynick));
strncpy(s_Mynick, Mynick, sizeof (s_Mynick));
snprintf(NICK_COMMA, sizeof (NICK_COMMA), "%s,", Mynick);
snprintf(COLON_NICK, sizeof (COLON_NICK), "%s:", Mynick);
snprintf(BCOLON_NICK, sizeof (BCOLON_NICK), "%s\2:\2", Mynick);
}
}
/**
* 6/23/00 Dan:
* - All method arguments are now pointer to const
* - A for loop is now used instead of a while loop
*/
struct chanserv_output *show_chaninfo (const char *nick, const char *chan, const char *target)
{
size_t totalUsers = 0, foundUsers = 0;
const struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
++totalUsers;
if (!strcasecmp (chan, c->chan))
++foundUsers;
}
return chanserv_asprintf(NULL, "I see %d users in %s (%d users total in ram)", foundUsers, chan, totalUsers);
}
/*
* This function displays a list of users that are listed in the bot's internal user
* list as being on the channel pointed to by chan, to the nick pointed to by nick.
* Each message sent to the target should be no more than about 200 characters in length.
*/
struct chanserv_output *show_chanusers (const char *nick, const char *chan)
{
struct chanserv_output *result = NULL;
struct userlist *c = userhead;
char DATA[512] = {0};
size_t foundUsers = 0, len = 0;
for (; c != NULL; c = c->next)
{
if (strcasecmp (chan, c->chan) == 0)
{
++foundUsers;
strcat(DATA, c->nick);
strcat(DATA, " ");
/* Add the length of the new nick and room for a space to the length of the current buffer. */
len += (strlen(c->nick) + 1);
if (len >= 200)
{
result = chanserv_asprintf(result, DATA);
len = 0;
DATA[0] = 0;
db_sleep (2);
}
}
}
/* If there's any leftover data in our buffer after we've reached the end of the list send that as well. */
if (len > 0)
result = chanserv_asprintf(result, "%s", DATA);
/* Even if no users were found... */
result = chanserv_asprintf(result, "End of CHANUSERS list; %d user%s found.", foundUsers, (foundUsers == 1 ? "" : "s"));
return result;
}
void
do_modes (char *source, char *data)
{
char *chan = NULL, *mode = NULL, *nick = NULL, *ptr = NULL;
long PM = 0, j = 0, i = 0;
chan = strtok (data, " ");
mode = strtok (NULL, " ");
if ((ptr = strchr (source, '!')) != NULL)
*ptr++ = '\0';
j = strlen (mode);
i = -1; /* i needs to start at 0 */
while (j > 0)
{
j--;
i++;
if (mode[i] == '+')
PM = 1;
if (mode[i] == '-')
PM = 0;
if (mode[i] == 'o')
{
nick = strtok (NULL, " ");
do_op(nick, chan, PM); /* flag this member as having been (De)OP'd/ */
continue;
}
if (mode[i] == 'v')
{ /* voice sucks, ignore it */
nick = strtok (NULL, " ");
continue;
}
if (mode[i] == 'k' || mode[i] == 'b')
{
nick = strtok (NULL, " ");
if (nick[0] == '*' && nick[1] == '!')
{
nick += 2;
}
strlwr (nick);
if (PM == 1)
scan_chan_users (chan, source, nick);
continue;
}
if (mode[i] == 'l' && PM == 1)
{ /* don't parse if -limit
- * since no parms */
+ * since no params */
nick = strtok (NULL, " ");
continue;
}
}
}
/**
* do_quit
*
* Purpose:
* 1) delete all instances when a nick matches (nick)
* 2) delete all users off a given channel
* 2) delete everything (i.e., when the bot is disconnected from irc)
*
* toggle 1 = delete user.
* toggle 2 = delete chan
* toggle 3 = everything (when I'm killed).
*/
void
do_quit (const char *nick, long toggle)
{
struct userlist *pNode = userhead;
struct userlist *pPrev = NULL;
if (toggle == 1)
{
/* delete user */
while (pNode)
{
if (strcasecmp (pNode->nick, nick) == 0)
{
/* found a match, remove it */
save_seen (pNode->nick, pNode->uh, pNode->chan);
if (pPrev != NULL)
{
pPrev->next = pNode->next;
free (pNode);
pNode = pPrev->next;
}
else
{
/* first node in the list */
userhead = pNode->next;
free (pNode);
pNode = userhead;
}
}
else
{
/* No match, continue to next node */
pPrev = pNode;
pNode = pNode->next;
}
}
}
else if (toggle == 2)
{
/* delete channel */
while (pNode)
{
if (strcasecmp (pNode->chan, nick) == 0)
{
/* found a match, remove it */
save_seen (pNode->nick, pNode->uh, pNode->chan);
if (pPrev != NULL)
{
pPrev->next = pNode->next;
free (pNode);
pNode = pPrev->next;
}
else
{
/* first node in the list */
userhead = pNode->next;
free (pNode);
pNode = userhead;
}
}
else
{
/* No match, continue to next node */
pPrev = pNode;
pNode = pNode->next;
}
}
}
else if (toggle == 3)
{
struct userlist *tempPtr = userhead;
while (pNode)
{
tempPtr = pNode->next;
free (pNode);
pNode = tempPtr;
}
}
}
long
f_f (char *host)
{
int i = 0;
for (i = 0; i < fc; i++)
if (!strcasecmp (ood[i].host, host))
return i;
return -1;
}
void
a_f (char *host)
{
if (++fc > 100)
fc = 0;
fc--;
strncpy (ood[fc].host, host, sizeof (ood[fc].host));
ood[fc].time = time (NULL);
ood[fc].count = 0;
ood[fc].value = false;
fc++;
}
void
reset_ (void)
{
int i = 0;
for (i = 0; i < fc; i++)
{
if (ood[i].value && (time (NULL) - ood[i].time) > rt)
{
ood[i].count = 0;
ood[i].time = time (NULL);
ood[i].value = false;
ood[i].kick = 0;
}
}
}
diff --git a/source/comm.c b/source/comm.c
index ee99bde..485d1b2 100644
--- a/source/comm.c
+++ b/source/comm.c
@@ -1,462 +1,462 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* Delete one or more elements from the sendq
* 1 = delete all pri/not's
* 0 = delete first in queue
* 6/23/00 Dan
* - Updated to use head and tail pointer queue
* - All variables now initialized when declared
* - Optimized the main while loop a bit, reduced amount of code
*/
void
del_sendq (long toggle)
{
struct sendq *pNode = sendqhead, *pPrev = 0;
if (NULL == sendqhead)
{
return;
}
if (toggle == 0)
{
/* Just delete the head */
pNode = sendqhead;
sendqhead = sendqhead->next;
free (pNode);
}
else
{
/* Iterate through the queue and delete each element which is
* a PRIVMSG or NOTICE
*/
for (; pNode != NULL; pPrev = pNode, pNode = pNode->next)
{
if (0 == strncmp (pNode->data, "PRI", 3) || 0 == strncmp (pNode->data, "NOT", 3))
{
/* Found one, let's delete it */
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
{
sendqhead = pNode->next;
}
free (pNode);
pNode = NULL;
break;
}
} /* for */
} /* else */
/* Update the tail pointer if needed */
if (NULL == sendqhead)
{
sendqtail = NULL;
}
}
int
get_sendq_count (long toggle)
{
struct sendq *c;
long i = 0, x = 0;
c = sendqhead;
while (c != NULL)
{
i++;
if (c->data[0] == 'P' && c->data[1] == 'R' && c->data[2] == 'I')
x++;
else if (c->data[0] == 'N' && c->data[1] == 'O' && c->data[2] == 'T')
x++;
c = c->next;
}
if (toggle == 1)
clear_sendq (i, 1);
if (toggle == 2)
return i;
if (i < OUTPUT1_COUNT)
SEND_DELAY = OUTPUT1_DELAY;
else if (i < OUTPUT2_COUNT)
SEND_DELAY = OUTPUT2_DELAY;
else
SEND_DELAY = OUTPUT3_DELAY;
if (x > OUTPUT_PURGE_COUNT)
clear_sendq (x, 0);
return i;
}
void
clear_sendq (long count, long toggle)
{
long i = 0;
i = count;
while (i > 1)
{
i--;
del_sendq (1);
}
send_tog = 1;
if (toggle != 1)
L090 (CHAN, count);
}
long
setinfo_lastcomm (char *rest)
{ /* Disallows joins to more than one channel (or the same chan)
- * to artifically raise join counters */
+ * to artificially raise join counters */
long c_uptime = 0;
if (strcasecmp (rest, slc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, slc2) == 0)
return 1;
if (strcasecmp (rest, slc3) == 0)
return 1;
if (strcasecmp (rest, slc4) == 0)
return 1;
if (*slc1 == '0')
{ /* init lastcomms */
strncpy (slc1, rest, sizeof (slc1));
slcn1 = time (NULL);
}
if (*slc2 == '0')
{
strncpy (slc2, rest, sizeof (slc2));
slcn2 = time (NULL);
}
if (*slc3 == '0')
{
strncpy (slc3, rest, sizeof (slc3));
slcn3 = time (NULL);
}
if (*slc4 == '0')
{
strncpy (slc4, rest, sizeof (slc4));
slcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - slcn1) > SLASTCOMM_TIME)
{ /* reinit old data */
slcn1 = 0;
*slc1 = '0';
}
if ((c_uptime = time (NULL) - slcn2) > SLASTCOMM_TIME)
{
slcn2 = 0;
*slc2 = '0';
}
if ((c_uptime = time (NULL) - slcn3) > SLASTCOMM_TIME)
{
slcn3 = 0;
*slc3 = '0';
}
if ((c_uptime = time (NULL) - slcn4) > SLASTCOMM_TIME)
{
slcn4 = 0;
*slc4 = '0';
}
strncpy (slc4, slc3, sizeof (slc4)); /* no matches, move em on
down */
strncpy (slc3, slc2, sizeof (slc3));
strncpy (slc2, slc1, sizeof (slc2));
strncpy (slc1, rest, sizeof (slc1));
slcn4 = slcn3;
slcn3 = slcn2;
slcn2 = slcn1;
slcn1 = time (NULL);
return 0;
}
long
do_lastcomm (char *nick, char *target, char *rest)
{
long c_uptime = 0;
if (strcasecmp (rest, lc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, lc2) == 0)
return 1;
if (strcasecmp (rest, lc3) == 0)
return 1;
if (strcasecmp (rest, lc4) == 0)
return 1;
if (*lc1 == '0')
{ /* init lastcomms */
strncpy (lc1, rest, sizeof (lc1));
lcn1 = time (NULL);
}
if (*lc2 == '0')
{
strncpy (lc2, rest, sizeof (lc2));
lcn2 = time (NULL);
}
if (*lc3 == '0')
{
strncpy (lc3, rest, sizeof (lc3));
lcn3 = time (NULL);
}
if (*lc4 == '0')
{
strncpy (lc4, rest, sizeof (lc4));
lcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - lcn1) > LASTCOMM_TIME)
{ /* reinit old data */
lcn1 = 0;
*lc1 = '0';
}
if ((c_uptime = time (NULL) - lcn2) > LASTCOMM_TIME)
{
lcn2 = 0;
*lc2 = '0';
}
if ((c_uptime = time (NULL) - lcn3) > LASTCOMM_TIME)
{
lcn3 = 0;
*lc3 = '0';
}
if ((c_uptime = time (NULL) - lcn4) > LASTCOMM_TIME)
{
lcn4 = 0;
*lc4 = '0';
}
strncpy (lc4, lc3, sizeof (lc4)); /* no matches, move em on
down */
strncpy (lc3, lc2, sizeof (lc3));
strncpy (lc2, lc1, sizeof (lc2));
strncpy (lc1, rest, sizeof (lc1));
lcn4 = lcn3;
lcn3 = lcn2;
lcn2 = lcn1;
lcn1 = time (NULL);
return 0;
}
void
prepare_bot (void)
{
int esc = 0;
while (!esc)
{
gs26 ();
printf (".: Connecting to %s:%ld\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
socketfd = create_connection (BS, VHOST, BP);
switch (socketfd)
{
case ERR_TIMED_OUT:
printf (".: Connection to %s:%ld timed out!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_CONN_REFUSED:
printf (".: Connection to %s:%ld was refused!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_NOT_ADDR:
printf ("Address not in range!\n");
exit (1);
case ERR_NO_REACH:
printf ("Address not reachable!\n");
exit (1);
default:
esc = 1;
printf
(".: Connected to %s:%ld! [%ld]\t\n", BS, BP, (long) getpid ());
fflush (stdout);
db_sleep (5);
break;
}
}
/* set the socket to BLOCK */
if (fcntl (socketfd, F_SETFL, 0) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
}
int
create_connection (char *server, char *virtualhost, long port)
{
struct sockaddr_in name;
struct hostent *hostname;
struct timeval timeout;
fd_set set;
int sock = 0, vhost = 1, sockerr = 0,
optlen = sizeof (sockerr);
if ((!virtualhost) || (strlen (virtualhost) < 1))
vhost = 0;
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
memset (&name, 0, sizeof (struct sockaddr_in));
setsockopt (sock, SOL_SOCKET, SO_LINGER, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
name.sin_family = AF_INET;
name.sin_addr.s_addr = (vhost ? inet_addr (virtualhost) : INADDR_ANY);
if ((name.sin_addr.s_addr == -1) && vhost)
{
hostname = gethostbyname (virtualhost);
if (hostname)
{
name.sin_addr = *(struct in_addr *) hostname->h_addr;
}
else
{
name.sin_addr.s_addr = INADDR_ANY;
}
}
if (bind (sock, (struct sockaddr *) &name, sizeof (struct sockaddr_in)) < 0)
{
printf ("\n");
perror ("bind");
close (sock);
exit (EXIT_FAILURE);
}
memset (&name, 0, sizeof (struct sockaddr_in));
name.sin_family = AF_INET;
name.sin_port = htons (port);
if(!(hostname = gethostbyname (server)))
{
printf ("\nCan't create the connection!\n");
// FIXME: This is obsolete, and solaris doesn't know about it.
// herror ("hostname");
exit (EXIT_FAILURE);
}
name.sin_addr = *(struct in_addr *) hostname->h_addr;
/* set the file descriptor to non blocking mode so that connect()
returns immediately.
*/
if (fcntl (sock, F_SETFL, O_NONBLOCK) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
if (connect (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
if ((errno != EINPROGRESS) && (errno != ENOENT))
{
printf ("\n");
perror ("connect");
exit (EXIT_FAILURE);
}
}
alarm (0);
while (1)
{
/* set the timeout */
timeout.tv_sec = CONNECT_WAIT_TIMEOUT;
timeout.tv_usec = 0;
/* set the file descriptor to be empty */
FD_ZERO (&set);
/* add our socket to the file descriptor set */
FD_SET (sock, &set);
/* select will let us know when our socket is ready (connected) */
switch (select (FD_SETSIZE, (fd_set *) NULL, &set, (fd_set *) NULL, &timeout))
{
/* if select returns 0, our timeout was reached */
case 0:
alarm (AIL);
return ERR_TIMED_OUT;
/* -1 means we are not connected */
case -1:
break;
/* we MIGHT be connected */
default:
/* get the socket errno so we can check if we are connected */
switch (getsockopt (sock, SOL_SOCKET, SO_ERROR, &sockerr, &optlen))
{
case -1:
alarm (AIL);
return ERR_SOCK_OPT;
case 0:
switch (sockerr)
{
case ECONNREFUSED:
alarm (AIL);
return ERR_CONN_REFUSED;
case EADDRNOTAVAIL:
alarm (AIL);
return ERR_NOT_ADDR;
case ENETUNREACH:
alarm (AIL);
return ERR_NO_REACH;
case SUCCESS:
alarm (AIL);
return sock;
}
}
}
}
}
void
register_bot (void)
{
get_sendq_count (1);
Snow ("NICK %s\n", Mynick);
strlwr (UID);
Snow ("USER %s %d %d :%s \2%d\2\n", UID, time (NULL), time (NULL), REALNAME, NUM_HELPER);
if (BPASS != NULL)
Snow ("PASS :%s\n", BPASS);
}
diff --git a/source/compat/strstr.c b/source/compat/strstr.c
index c53b501..7f20065 100644
--- a/source/compat/strstr.c
+++ b/source/compat/strstr.c
@@ -1,37 +1,37 @@
/* Simple implementation of strstr for systems without it.
This function is in the public domain. */
/*
@deftypefn Supplemental char* strstr (const char *@var{string}, const char *@var{sub})
This function searches for the substring @var{sub} in the string
@var{string}, not including the terminating null characters. A pointer
to the first occurrence of @var{sub} is returned, or @code{NULL} if the
substring is absent. If @var{sub} points to a string with zero
length, the function returns @var{string}.
@end deftypefn
*/
-/* FIXME: The above description is ANSI compiliant. This routine has not
+/* FIXME: The above description is ANSI compliant. This routine has not
been validated to comply with it. -fnf */
#include "defines.h"
char *
rpl_strstr (const char *s1, const char *s2)
{
const char *p = s1;
const size_t len = strlen (s2);
for (; (p = strchr (p, *s2)) != 0; p++)
{
if (strncmp (p, s2, len) == 0)
return (char *)p;
}
return (0);
}
diff --git a/source/defines.h b/source/defines.h
index ccca1e9..a810bea 100644
--- a/source/defines.h
+++ b/source/defines.h
@@ -1,354 +1,354 @@
/*
* Copyright (C) 2002 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
/* @configure_input@ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* defines.h
* The Internet Relay Chat Talking Robot
*
*** Darkbot Creator : Jason Hamilton (play) Jason@superlink.net
* Project Administrator : LuizCB (lcb) LuizCB@dusers.sourceforge.net
* Lead Developer : David Seikel (onefang) onefang@users.sourceforge.net
*
* Official Site: http://darkbot.sourceforge.net
* http://darkbot.sourceforge.net
*
*** For any questions, suggestions, malfunctions, etc
* Use our support area at http://darkbot.sourceforge.net
*
* *******************************---******************************* */
/*
*** NOTES - READ before you start:
- *** Lines beginning by # (hash) are peprocessor directives, they are not
+ *** Lines beginning by # (hash) are preprocessor directives, they are not
* comments. You should NOT remove them.
*** #defines should only be changed to ON, OFF, #define, #undef
* or it's value defined on the very right end.
*** Areas between " " are messages Darkbot will send. Do not remove " ".
- *** Double slash characters on de beginning of a line or slaches followed
- * or preceded by * on the beginning and end of lines envolving some
+ *** Double slash characters on de beginning of a line or slashes followed
+ * or preceded by * on the beginning and end of lines evolving some
* portion of text are comment characters combinations with help
- * information for the delelopers or users. They do not have any effect
+ * information for the developers or users. They do not have any effect
* in the behavior of the program.
*
,-----------------------------------------------------------------,
| Note that the defines bellow are the RECOMMENDED settings! |
| Modify it by changing it's values of the data. This file will |
| instruct the compiler to build the executable file. If you're |
| not sure of what to do, leave the default settings alone :) |
`-----------------------------------------------------------------' */
#define ON 1
#define OFF 0
/* ================ SYSTEM REQUIREMENTS ================ */
/*
* Change the Ansi C signal handling below if it's not in the standard place,
* usually on include/. Leave it as is if you don't know what that is. Type
* 'man signal' on your unix box for more info.
* (default = <signal.h>)
*/
//#include <signal.h>
/*
* Most BSD systems will not need this. If your bot will
* connect but don't react at all try turning this ON.
* (default = OFF)
*/
//#define NEED_LIBC5 OFF
/*
* SGI boxes (ie; IRIX system) need this
* define to run. (default = OFF)
*/
//#define SGI OFF
/*
* If you change anything on the next 5 directives be careful not to
* remove or change the position of '%s' nor anything outside quotes.
*/
#define L100(s,a,b,c,d,e,f) S("NOTICE %s :I can be triggered by various \
forms of speech, all which must be addressed to me, in one of the \
following formats: %s %s %s or even %s .... In my database, you can \
find a topic by saying my nick, <topic> . eg; \37%s nuke\37 ..... \
to do a search on a word, or partial text, just type: <mynick>, search \
<text> ... eg; \37%s search nuke\37\n",s,a,b,c,d,e,f)
#define L101(a,b,c,d) S("NOTICE %s :I can also be triggered with even more \
human formats: \37%s who is bill gates?\37 .. You can also phrase it \
in a question: \37%s where is msie?\37 ...For more info \
about me, visit http://darkbot.sourceforge.net\n",a,b,c,d)
#define L102(a,b,c,d) S("NOTICE %s :Welcome to %s, %s. Before \
asking your question, type %cHELP for a list of help topics.\n", a,b,c,d)
/* *******************************---******************************* */
/* --------------- Don't change anything else below! --------------- */
/* ***************************************************************** */
//#include <sys/cdefs.h>
//#include <sys/param.h>
//#include <pwd.h>
/* Here we sort out what to do based on some autoconf detected things. */
#if defined _WIN32 || defined __CYGWIN__ || defined __CYGWIN32__ || defined __MINGW32__
# ifndef WIN32
# define WIN32
# endif
#endif
#define _GNU_SOURCE 1
#if HAVE_ANSIDECL_H
#include <ansidecl.h>
#endif
#include <ctype.h>
#include <limits.h>
#include <stddef.h>
#if HAVE_ERRNO_H
# include <errno.h>
#endif
#ifndef errno
extern int errno;
#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <assert.h>
#if HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef WIN32
# include <windows.h>
#endif
#include <signal.h>
#include <sys/stat.h>
#include <stdio.h> /* The only one we can guarantee. */
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if ! HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# endif
# endif
# define bool _Bool
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif
#if STDC_HEADERS
# include <string.h>
# include <stdarg.h>
# include <stdlib.h>
#else
# if !HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
# if !HAVE_MEMMOVE
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#if HAVE_UNISTD_H
#include <sys/types.h>
#include <unistd.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
/* MacOS X is happier with this one AFTER timeval is declared. */
#include <sys/resource.h>
#include "stat-macros.h"
#include "minmax.h"
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# define EXIT_FAILURE 1
#endif
#if !LSTAT_FOLLOWS_SLASHED_SYMLINK
extern int rpl_lstat (const char *name, struct stat *buf);
# undef lstat
# define lstat rpl_lstat
#endif
#if !HAVE_MEMSET
# define memset rpl_memset
#endif
#if !HAVE_NANOSLEEP
# define nanosleep rpl_nanosleep
#endif
#if !HAVE_SNPRINTF
# define snprintf rpl_snprintf
#endif
#if !HAVE_STRCASECMP
# define strcasecmp rpl_strcasecmp
#endif
#if !HAVE_STRCASESTR
# define strcasestr rpl_strcasestr
#endif
#if !HAVE_STRNDUP
extern char *rpl_strndup (const char *dupMe, size_t maxBytes);
# undef strndup
# define strndup rpl_strndup
#endif
#if !HAVE_STRSPN
# define strspn rpl_strspn
#endif
#if !HAVE_STRSTR
# define strstr rpl_strstr
#endif
#if !HAVE_VPRINTF
# define vsprintf rpl_vsprintf
# define vfprintf rpl_vfprintf
#endif
#if !HAVE_LIBCRYPT
# if !HAVE_CRYPT
# define crypt rpl_crypt
# endif
#endif
/* -------------------------------------------------- */
#define FR 3 /* these two are the # of lines per secs */
#define FT 3
#define AIL 1
#define WSEC 10
#define USEC 0
#define RECHECK 45
#define DEFAULT_DBTIMERS_PATH "timers"
#define DEFAULT_LOG_DIR "logs/"
#define DEFAULT_RDB_DIR "rdb"
#ifdef ENABLE_STATS
#define DEFAULT_STATS_FILE "stats.db"
#endif
#define DEFAULT_SEEN_FILE "seen.db"
#define DEFAULT_URL2 "info2.db"
#define DUNNO_FILE "dunno"
#define WHUT_FILE "whut"
#define DEFAULT_BACKUP_DUP "backup_dups.db"
#define DEFAULT_ADD_DELETES "logs/add_delete.log"
#define TMP_URL ".info.tmp"
#define TMP_FILE ".file.tmp"
#define DEFAULT_AUTOTOPIC_F "autotopic.ini"
#define DEFAULT_HELPER_LIST "userlist.db"
#define DEFAULT_QUIZ_FILE "quiz.db"
#define DEFAULT_PERFORM "perform.ini"
#define DEFAULT_DEOP "deop.ini"
#define DEFAULT_RAND_SAY "random.ini"
#define DEFAULT_RAND_FILE "randomstuff.ini"
#define DEFAULT_RANDQ_TEMPFILE "randq.tmp"
#define DEFAULT_RAND_BACKUP_FILE "randomstuff.bak"
#define DEFAULT_SERVERS "servers.ini"
#define DEFAULT_PERMBAN "permbans.db"
#define DEFAULT_SETUP "setup.ini"
#define MAX_SEARCH_LENGTH 350
#define ERR_SOCK_OPT -1
#define ERR_TIMED_OUT -1
#define ERR_CANT_MALLOC -1
#define ERR_OPEN_SOCKET -2
#define ERR_CONN_REFUSED -2
#define ERR_NOT_ADDR -3
#define ERR_WRITE_SOCKET -3
#define ERR_NO_REACH -4
#define ERR_CANT_CONNECT -5
#define ERR_READ_SOCKET -5
#define ERR_SERVER_BUSY -6
#define ERR_NO_DOCUMENTS -6
#define ERR_NO_DATA -7
#define SUCCESS 0
#define LEGAL_TEXT "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
#define SAFE_LIST "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#define LEGAL_NICK_TEXT "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-\\|[]{}`"
#define NUMBER_LIST "1234567890"
#define MAX_NICK_LENGTH 35
#ifndef LANG /* If not defined, default to english */
#define LANG 1
#endif
#define NORMALR 0
#define WHUTR 1
#define DUNNOR 2
#define RAND_NORMAL 0
#define RAND_ACTION 1
#define RAND_RAW 2
#define RANDQ_NORMAL 0
#define RANDQ_CASE 1
#define RANDQ_RAND 2
#define RDB_NORMAL 0
#define RDB_ACTION 1
#define RDB_RAW 2
/* ////////////////////////////////////////////////////////////////////// */
#define RESERVED1 "EXPLAIN"
#define RESERVED2 "DECLARE"
#include "langs/lang.h"
diff --git a/source/tree.c b/source/tree.c
index cc69092..840263e 100644
--- a/source/tree.c
+++ b/source/tree.c
@@ -1,259 +1,259 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include <sys/types.h>
#include "tree.h"
-/* Just a quick and dirty tree implemtation that will likely get replaced by
+/* Just a quick and dirty tree implementation that will likely get replaced by
* something much saner at a later date. I wrote most of this while falling
* asleep. It will probably scare me when I wake up. B-)
*
* This was originally written for Enlightenment.
*
* The trees will be tiny.
* They only store strings.
* There is no insertion or deletion, only append.
* Append order must be maintained.
- * The trees will only ever be accessed sequentially, from begining to end.
+ * The trees will only ever be accessed sequentially, from beginning to end.
* The tree data will come in two ways, all in one big string, or a bunch of
* seperate strings, one per element. Any particular tree might have both.
*
* No duplicates in the tree,
* This is the nasty part of this tree implementation.
* Insertions involve a linear search for dupes, most of the
* time there won't be any dupes, so the tree is searched in
* it's entirety. These trees will be really small, and only created at
* the begining, so no big drama there.
* The tree may allow duplicates.
*/
Tree *tree_new(char *buffer)
{
Tree *tree;
tree = E_NEW(Tree, 1);
if ((tree) && (buffer))
{
tree->buffers = (char **)realloc(tree->buffers, (tree->buffers_size + 1) * sizeof(char *));
tree->buffers[tree->buffers_size++] = strdup(buffer);
}
return tree;
}
Tree *tree_add(Tree * tree, const char *element)
{
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + 1) * sizeof(Tree_Element));
tree->elements[tree->size].element = (char*)element;
tree->elements[tree->size++].type = TREE_ELEMENT_TYPE_STRING;
return tree;
}
Tree *tree_extend(Tree * tree, const char *element)
{
tree->buffers = (char **)realloc(tree->buffers, (tree->buffers_size + 1) * sizeof(char *));
tree->buffers[tree->buffers_size++] = strdup(element);
tree = tree_add(tree, tree->buffers[tree->buffers_size - 1]);
return tree;
}
void tree_track(Tree * tree, void *element)
{
tree->buffers = (char **)realloc(tree->buffers, (tree->buffers_size + 1) * sizeof(char *));
tree->buffers[tree->buffers_size++] = element;
}
/* OK, so we need an insert after all, and it falls into the dumb category. */
Tree *tree_insert(Tree * tree, int before, void *element, Tree_Element_Type type)
{
int i;
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + 1) * sizeof(Tree_Element));
tree->size++;
for (i = tree->size - 1; i > before; i--)
{
tree->elements[i].element = tree->elements[i - 1].element;
tree->elements[i].type = tree->elements[i - 1].type;
}
tree->elements[before].element = element;
tree->elements[before].type = type;
return tree;
}
/* OK, so we need a tree merge after all, and it falls into the dumb category. */
Tree *tree_merge(Tree * tree, int before, Tree * element)
{
int i, size;
size = element->size;
if (size)
{
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + size) * sizeof(Tree_Element));
tree->size += size;
for (i = tree->size - 1; (i > before) && ((i - size) > 0); i--)
{
tree->elements[i].element = tree->elements[i - size].element;
tree->elements[i].type = tree->elements[i - size].type;
}
for (i = 0; i < size; i++)
{
tree->elements[before + i].element = element->elements[i].element;
tree->elements[before + i].type = element->elements[i].type;
}
}
/* Careful, this might screw up the freeing order if that is important. */
size = element->buffers_size;
if (size)
{
/*
tree->buffers = (char **) realloc(tree->buffers, (tree->buffers_size + size) * sizeof(char *));
tree->buffers_size += size;
for (i = 0; i < size; i++)
{
tree->buffers[tree->buffers_size + i] = element->buffers[i];
element->buffers[i] = NULL;
}
*/
}
return tree;
}
Tree *tree_add_child(Tree * tree, Tree * element)
{
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + 1) * sizeof (Tree_Element));
tree->elements[tree->size].element = element;
tree->elements[tree->size++].type = TREE_ELEMENT_TYPE_TREE;
element->parent = tree;
return tree;
}
void tree_remove(Tree * tree, int element)
{
if (tree->size > element)
{
tree->elements[element].type = TREE_ELEMENT_TYPE_NULL;
tree->elements[element].element = NULL;
}
}
int tree_exist(Tree * tree, char *element)
{
int exist = 0;
int i;
/* This is the dumb part of the tree, a linear search. */
for (i = 0; i < tree->size; i++)
{
if ((tree->elements[i].type == TREE_ELEMENT_TYPE_STRING) && (strcmp((char *)tree->elements[i].element, element) == 0))
{
exist = 1;
break;
}
}
return exist;
}
int tree_foreach(Tree * tree, int level, int (*func) (const void *data, Tree * tree, int element, int level), const void *data)
{
int result = 0;
int i;
for (i = 0; i < tree->size; i++)
{
if (tree->elements[i].type == TREE_ELEMENT_TYPE_TREE)
{
if (tree_foreach((Tree *) tree->elements[i].element, level + 1, func, data))
result = 1;
}
else if (tree->elements[i].type == TREE_ELEMENT_TYPE_NULL)
{
/* This falls into the dumb category. */
int j = i;
int k = i;
int moved = 0;
/* Find the next non NULL element. */
while ((j < tree->size) && (tree->elements[j].type == TREE_ELEMENT_TYPE_NULL))
j++;
/* Move the next batch of non NULL up. */
while ((j < tree->size) && (tree->elements[j].type != TREE_ELEMENT_TYPE_NULL))
{
moved = 1;
tree->elements[k].type = tree->elements[j].type;
tree->elements[k].element = tree->elements[j].element;
tree->elements[j].type = TREE_ELEMENT_TYPE_NULL;
tree->elements[j].element = NULL;
j++;
k++;
}
if (moved)
i--;
else
tree->size = i;
}
else
{
if (func(data, tree, i, level))
result = 1;
}
}
return result;
}
void tree_dump(Tree * tree, int level)
{
int i;
for (i = 0; i < tree->size; i++)
{
int j;
for (j = 0; j < level; j++)
printf(".");
switch (tree->elements[i].type)
{
case TREE_ELEMENT_TYPE_NULL:
printf("NULL\n");
break;
case TREE_ELEMENT_TYPE_STRING:
printf("%s\n", (char *)tree->elements[i].element);
break;
case TREE_ELEMENT_TYPE_TREE:
printf("TREE ELEMENT TYPE\n");
tree_dump((Tree *) tree->elements[i].element, level + 1);
break;
default:
printf("UNKNOWN ELEMENT TYPE!\n");
break;
}
}
}
void tree_del(Tree * tree)
{
int i;
for (i = tree->size - 1; i >= 0; i--)
{
if (tree->elements[i].type == TREE_ELEMENT_TYPE_TREE)
tree_del((Tree *) tree->elements[i].element);
}
E_FREE(tree->elements);
for (i = tree->buffers_size - 1; i >= 0; i--)
E_FREE(tree->buffers[i]);
E_FREE(tree);
}
diff --git a/source/xmlame.c b/source/xmlame.c
index ac960cb..810b9a9 100644
--- a/source/xmlame.c
+++ b/source/xmlame.c
@@ -1,136 +1,136 @@
/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include "tree.h"
#include <fcntl.h>
#include <ctype.h>
#include <sys/stat.h>
/** xmlame.c Extensively Mocked Language Approximately Mangled for Enlightenment.
*
* This is NOT a real XML parser. It assumes the XML file is properly formed, and smallish.
*
- * The final '>' of a tag is replaced with a '\0', but it's existance can be implied.
+ * The final '>' of a tag is replaced with a '\0', but it's existence can be implied.
*/
static char *_xmlame_parse(Tree * tree, char *buffer);
Tree *xmlame_new(char *buffer)
{
return tree_new(buffer);
}
Tree *xmlame_get(char *file)
{
int size = 0;
char *buffer;
struct stat st;
Tree *tree = NULL;
if (stat(file, &st) >= 0)
size = st.st_size;
buffer = (char *)malloc(size + 1);
if (buffer)
{
int fd;
buffer[0] = '\0';
fd = open(file, O_RDONLY);
if (fd != -1)
{
if (read(fd, buffer, size) == size)
buffer[size] = '\0';
}
tree = xmlame_new(buffer);
if (tree)
{
/* Have the file name as the first item on the tree, for later reference. */
tree_extend(tree, file);
_xmlame_parse(tree, buffer);
}
}
return tree;
}
Tree *xmlame_from_string(char *data)
{
Tree *tree = NULL;
tree = xmlame_new(data);
if (tree)
_xmlame_parse(tree, data);
return tree;
}
static char *_xmlame_parse(Tree * tree, char *buffer)
{
while (*buffer != '\0')
{
char *text;
/* Skip any white space at the beginning. */
while ((*buffer != '\0') && (isspace(*buffer)))
buffer++;
text = buffer;
/* Find the beginning of a tag. */
while ((*buffer != '<') && (*buffer != '\0'))
buffer++;
/* Check for data between tags. */
if (buffer != text)
{
char t;
t = *buffer;
*buffer = '\0';
tree_extend(tree, text);
*buffer = t;
}
if (*buffer != '\0')
{
char *begin;
begin = buffer++;
/* Find the end of the tag. */
while ((*buffer != '>') && (*buffer != '\0'))
buffer++;
/* We have our tag, do something with it. */
if (*buffer != '\0')
{
*buffer++ = '\0';
if (begin[1] == '/')
{ /* The end of an element. */
tree_add(tree, begin);
break;
}
else if ((begin[1] == '!') || (begin[1] == '-') || (*(buffer - 2) == '/'))
{ /* This is a script, a comment, or a stand alone tag. */
tree_add(tree, begin);
}
else
{ /* The beginning of an element. */
Tree *new_tree;
new_tree = xmlame_new(NULL);
if (new_tree)
{
tree_add_child(tree, new_tree);
tree_add(new_tree, begin);
buffer =
_xmlame_parse(new_tree, buffer);
}
}
}
}
}
return buffer;
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Sep 18, 07:41 (18 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2990197
Default Alt Text
(60 KB)

Event Timeline