summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--libhashtable/Makefile14
-rw-r--r--libhashtable/example.c24
-rw-r--r--libhashtable/libhashtable.c115
-rw-r--r--libhashtable/libhashtable.h23
-rw-r--r--segfault.c193
6 files changed, 221 insertions, 151 deletions
diff --git a/Makefile b/Makefile
index 0806b5d..eedeed0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,9 @@
-LDFLAGS=-lirc -Llibirc
+LDFLAGS=-lirc -Llibirc -lhashtable -Llibhashtable
CFLAGS=-pedantic -Wall
all:
cd libirc && $(MAKE)
+ cd libhashtable && $(MAKE)
$(MAKE) segfault
clean:
diff --git a/libhashtable/Makefile b/libhashtable/Makefile
new file mode 100644
index 0000000..7def401
--- /dev/null
+++ b/libhashtable/Makefile
@@ -0,0 +1,14 @@
+LDFLAGS=-lhashtable -Llibhashtable
+CFLAGS=-fpic -shared -pedantic -Wall
+TARGET=libhashtable.so
+
+all: $(TARGET)
+
+$(TARGET):
+ $(CC) $(CFLAGS) -o $(TARGET) libhashtable.c
+
+clean:
+ rm -f libhashtable.so
+
+install:
+ cp $(TARGET) /usr/local/lib/$(TARGET)
diff --git a/libhashtable/example.c b/libhashtable/example.c
new file mode 100644
index 0000000..614e440
--- /dev/null
+++ b/libhashtable/example.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include "libhashtable.h"
+
+extern char **environ;
+
+int main(int argc,char *argv[]) {
+ struct hashtable ht;
+ int i;
+ char *name;
+ char *value;
+ inittable(&ht);
+ for(i=0;environ[i];i++) {
+ name=strdup(environ[i]);
+ if((value=strchr(name,'=') )){
+ *value=0;
+ value++;
+ }
+ //printf("'%s' = '%s'\n",name,value);
+ ht_setkey(&ht,name,value);
+ free(name);
+ }
+ printf("PATH='%s'\n",ht_getvalue(&ht,"PATH"));
+ return 0;
+}
diff --git a/libhashtable/libhashtable.c b/libhashtable/libhashtable.c
new file mode 100644
index 0000000..c4ac2d3
--- /dev/null
+++ b/libhashtable/libhashtable.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "hashtable.h"
+
+/*
+struct entry {//linked list node.
+ char *original;
+ char *target;
+ struct entry *prev;// doubly linked list. why?
+ struct entry *next;
+};
+
+struct hitem {//dunno why I don't just have this as a linked list.
+ struct entry *ll;
+};
+
+struct hashtable {
+ int kl;//number of keys in the table
+ struct hitem **bucket;
+ int *keys;
+};
+*/
+
+unsigned short hash(char *v) {//maybe use a seeded rand()? :) Thanks FreeArtMan
+ unsigned short h=0;
+ h=((*v)<<8)+(v?*(v+1):0);
+ srand(h);
+ return rand();
+}
+
+void inittable(struct hashtable *ht,int tsize) {
+ int i;
+ ht->bucket=malloc(sizeof(char *)*tsize);
+ ht->kl=0;
+ ht->keys=malloc(sizeof(int *)*tsize);
+ if(!ht) {
+ fprintf(stderr,"malloc error 6 in hash table.\n");
+ return;
+ }
+ for(i=0;i<tsize;i++) {
+ ht->bucket[i]=0;
+ }
+}
+
+//this seems too complicated.
+int ht_setkey(struct hashtable *ht,char *key,char *value) {
+ unsigned short h=hash(key);
+ struct entry *tmp;
+ int i;
+ for(i=0;i<ht->kl;i++) {
+ if(ht->keys[i]==h) break;
+ }
+ ht->keys[i]=h;
+ ht->kl=(ht->kl)>i+1?ht->kl:i+1;
+ if(!ht->bucket[h]) { //empty bucket!
+ //add this to the list of used buckets so we can easily
+ //use that list later for stuff.
+ if(!(ht->bucket[h]=malloc(sizeof(struct hitem)))) return 1;
+ ht->bucket[h]->ll=0;
+ //we now have a valid hashtable entry and a NULL ll in it.
+ //don't bother with the new ll entry yet...
+ }
+ if((tmp=ll_getentry(ht->bucket[h]->ll,key)) != NULL) {
+ //we found this alias in the ll. now to replace the value
+ free(tmp->target);
+ if(!(tmp->target=strdup(value))) return 2;
+ return 0;
+ }
+ if(ht->bucket[h]->ll == NULL) {
+ if(!(ht->bucket[h]->ll=malloc(sizeof(struct entry)))) return 3;
+ ht->bucket[h]->ll->next=0;
+ ht->bucket[h]->ll->prev=0;
+ if(!(ht->bucket[h]->ll->original=strdup(key))) return 4;
+ if(!(ht->bucket[h]->ll->target=strdup(value))) return 5;
+ } else {
+ //go to the end and add another entry to the ll.
+ for(tmp=ht->bucket[h]->ll;tmp->next;tmp=tmp->next);
+ if(!(tmp->next=malloc(sizeof(struct entry)))) return 6;
+ tmp->next->prev=tmp;
+ tmp=tmp->next;
+ if(!(tmp->original=strdup(key))) return 7;
+ if(!(tmp->target=strdup(value))) return 8;
+ tmp->next=0;
+ }
+ return 0;
+}
+
+struct entry *ll_getentry(struct entry *start,char *msg) {
+ struct entry *m;
+ if(!msg) return NULL;
+ if(!start) return NULL;
+ for(m=start;m;m=m->next) {
+ if(!strncmp(msg,m->original,strlen(m->original)) && (msg[strlen(m->original)]==' ' || msg[strlen(m->original)] == 0)) {//this allows !c to get called when using !c2 if !c2 is defined after !c. >_>
+ return m;
+ }
+ }
+ return NULL;
+}
+
+struct entry *ht_getentry(struct hashtable *ht,char *key) {
+ unsigned short h=hash(key);
+ if(!ht->bucket[h]) return NULL;
+ return ht->bucket[h]->ll;
+}
+
+struct entry *ht_getnode(struct hashtable *ht,char *msg) {
+ return ll_getentry(ht_getentry(ht,msg),msg);
+}
+
+//you'll probably want to use me.
+char *ht_getvalue(struct hashtable *ht,char *msg) {
+ struct entry *tmp=ll_getentry(ht_getentry(ht,msg),msg);
+ return tmp?tmp->target:0;
+}
diff --git a/libhashtable/libhashtable.h b/libhashtable/libhashtable.h
new file mode 100644
index 0000000..7899124
--- /dev/null
+++ b/libhashtable/libhashtable.h
@@ -0,0 +1,23 @@
+struct entry {//linked list node.
+ char *original;
+ char *target;
+ struct entry *prev;// doubly linked list. why?
+ struct entry *next;
+};
+
+struct hitem {//dunno why I don't just have this as a linked list.
+ struct entry *ll;
+};
+
+struct hashtable {
+ int kl;//number of keys in the table
+ struct hitem **bucket;
+ int *keys;
+};
+unsigned short hash(char *v);//maybe use a seeded rand()? :) Thanks FreeArtMan
+void inittable(struct hashtable *ht);
+int ht_setkey(struct hashtable *ht,char *key,char *value);
+struct entry *ll_getentry(struct entry *start,char *msg);
+struct entry *ht_getentry(struct hashtable *ht,char *key);
+struct entry *ht_getnode(struct hashtable *ht,char *msg);
+char *ht_getvalue(struct hashtable *ht,char *msg);
diff --git a/segfault.c b/segfault.c
index 5f1499b..7425a04 100644
--- a/segfault.c
+++ b/segfault.c
@@ -8,9 +8,12 @@
#include <fcntl.h>
#include <time.h>
#include <pwd.h>
+
#include "libirc/irc.h" //epoch's libirc. should be included with segfault.
+#include "libhashtable/hashtable.h" //epoch's also.
//might want to change some of these.
+#define TSIZE 65535
#define SERVER "127.0.0.1"
#define PORT "6667"
#define NICK "SegFault" //override with argv[0]
@@ -21,7 +24,6 @@
#define LOG "./files/log"
#define MAXTAILS 400 //just to have it more than the system default.
#define BS 502
-#define TSIZE 65536 //size of hashtable. 65k isn't bad, right?
// !c uses 56 for its tail.
// 56 == 32 + 16 + 8 == 0x38 == 0x20+0x10+0x8 == SPAM | BEGIN | MSG
#define TAILO_RAW (0x1) // r output gets sent directly to server
@@ -63,6 +65,8 @@ timer_t timer;
int lines_sent;
unsigned long oldtime;
+struct hashtable alias;
+
struct user {
char *nick;
char *name;
@@ -80,13 +84,6 @@ struct tail {
int lines;
} tailf[MAXTAILS];
-struct alias {
- char *original;
- char *target;
- struct alias *prev;// doubly linked list.
- struct alias *next;
-};
-
char *shitlist[] = { 0 };
void message_handler(int fd,char *from,struct user *user,char *msg,int redones);
@@ -417,108 +414,20 @@ void debug_time(int fd,char *from,char *msg) {
}
}
-struct alias *leetgetalias(struct alias *start,char *msg) {
- struct alias *m;
- if(!msg) return NULL;
- if(!start) return NULL;
- for(m=start;m;m=m->next) {
- if(!strncmp(msg,m->original,strlen(m->original)) && (msg[strlen(m->original)]==' ' || msg[strlen(m->original)] == 0)) {//this allows !c to get called when using !c2 if !c2 is defined after !c. >_>
- return m;
- }
- }
- return NULL;
-}
-
-unsigned short hash(char *v) {//maybe use a seeded rand()? :) Thanks FreeArtMan
- unsigned short h=0;
- h=((*v)<<8)+(v?*(v+1):0);
- srand(h);
- return rand();
-}
-
-struct hitem {//with a stick
- struct alias *ll;
-};
-
-struct hitem **hashtable;
-int htkeys[TSIZE];
-int htkl;
-
-void inittable() {
- int i;
- hashtable=malloc(sizeof(char *)*TSIZE);
- if(!hashtable) {
- fprintf(stderr,"malloc error 6 in hash table.\n");
- return;
- }
- for(i=0;i<TSIZE;i++) {
- hashtable[i]=0;
- }
-}
-
-struct alias *getkey_h(char *key) {
- unsigned short h=hash(key);
- if(!hashtable[h]) return NULL;
- return hashtable[h]->ll;
-}
-
-//this seems too complicated.
-int setkey_h(char *key,char *value) {
- unsigned short h=hash(key);
- struct alias *tmp;
- int i;
- for(i=0;i<htkl;i++) {
- if(htkeys[i]==h) break;
- }
- htkeys[i]=h;
- htkl=htkl>i+1?htkl:i+1;
- if(!hashtable[h]) { //empty bucket!
- //add this to the list of used buckets so we can easily
- //use that list later for stuff.
- if(!(hashtable[h]=malloc(sizeof(struct hitem)))) return 1;
- hashtable[h]->ll=0;
- //we now have a valid hashtable entry and a NULL ll in it.
- //don't bother with the new ll entry yet...
- }
- if((tmp=leetgetalias(hashtable[h]->ll,key)) != NULL) {
- //we found this alias in the ll. now to replace the value
- free(tmp->target);
- if(!(tmp->target=strdup(value))) return 2;
- return 0;
- }
- if(hashtable[h]->ll == NULL) {
- if(!(hashtable[h]->ll=malloc(sizeof(struct alias)))) return 3;
- hashtable[h]->ll->next=0;
- hashtable[h]->ll->prev=0;
- if(!(hashtable[h]->ll->original=strdup(key))) return 4;
- if(!(hashtable[h]->ll->target=strdup(value))) return 5;
- } else {
- //go to the end and add another entry to the ll.
- for(tmp=hashtable[h]->ll;tmp->next;tmp=tmp->next);
- if(!(tmp->next=malloc(sizeof(struct alias)))) return 6;
- tmp->next->prev=tmp;
- tmp=tmp->next;
- if(!(tmp->original=strdup(key))) return 7;
- if(!(tmp->target=strdup(value))) return 8;
- tmp->next=0;
- }
- return 0;
-}
-
void c_aliases_h(int fd,char *from,char *line) {
char tmp[512];
- struct alias *m;
+ struct entry *m;
int i,j=0,k=0;
if(!line){
privmsg(fd,from,"usage: !aliases [search-term]");
return;
}
- for(i=0;i<htkl;i++) {
- //snprintf(tmp,sizeof(tmp)-1,"aliases in bucket: %d",htkeys[i]);
+ for(i=0;i<alias.kl;i++) {
+ //snprintf(tmp,sizeof(tmp)-1,"aliases in bucket: %d",alias->keys[i]);
//privmsg(fd,from,tmp);
- for(m=hashtable[htkeys[i]]->ll;m;m=m->next) {
+ for(m=alias.bucket[alias.keys[i]]->ll;m;m=m->next) {
if(strcasestr(m->target,line) || strcasestr(m->original,line)) {
- snprintf(tmp,sizeof(tmp)-1,"%s -> %s",m->original,m->target);
+ snprintf(tmp,sizeof(tmp)-1," %s -> %s",m->original,m->target);
privmsg(fd,from,tmp);
j++;
}
@@ -528,49 +437,17 @@ void c_aliases_h(int fd,char *from,char *line) {
snprintf(tmp,sizeof(tmp)-1,"found %d of %d aliases",j,k);
privmsg(fd,from,tmp);
}
-
-//CONVERT //this is the last one that needs to be converted to
-// be used with the hashtable
/*
-void c_rmalias_h(int fd,char *from,char *line) {
-
-}
-
-void c_leetrmalias(int fd,char *from,char *line) {
- struct alias *m;
- for(m=a_start;m;m=m->next) {
- if(!strcmp(line,m->original)) {
- if(m->next == 0) {
- a_end=m->prev;
- }
- if(m->prev == 0) {
- a_start=m->next;
- free(m->target);
- free(m->original);
- free(m);
- }
- else {
- m->prev->next=m->next;
- }
- privmsg(fd,from,"alias deleted");
- return;
- }
- }
- privmsg(fd,from,"alias not found");
- return;
-}
-*/
-
-struct alias *getalias_h(char *msg) {
+struct entry *getalias_h(char *msg) {
return leetgetalias(getkey_h(msg),msg);
}
-
+*/
void c_alias_h(int fd,char *from,char *line) {
char tmps[512];
char *derp=strchr(line,' ');
- struct alias *tmp;
+ struct entry *tmp;
if(!derp) {
- if((tmp=getalias_h(line)) != NULL) {
+ if((tmp=ht_getentry(&alias,line)) != NULL) {
privmsg(fd,from,tmp->target);
} else {
snprintf(tmps,sizeof(tmps),"'%s' not an alias.",line);
@@ -580,7 +457,7 @@ void c_alias_h(int fd,char *from,char *line) {
}
*derp=0;
derp++;
- setkey_h(line,derp);
+ ht_setkey(&alias,line,derp);
}
//hash table version
@@ -858,7 +735,10 @@ void c_resetout(int fd,char *from) {
privmsg(fd,from,"output reset");
}
-/* maybe... that message hander is ugly.
+/* maybe... that message handler is ugly.
+//an array of built-ins? linked list? hash-table?
+//working on genericizing the hash-table code.
+//so probably ht for builtins.
struct builtin {
char *cmd;
void (*func)();
@@ -870,8 +750,7 @@ struct builtin[] = {
*/
void message_handler(int fd,char *from,struct user *user,char *msg,int redones) {
- printf("message handler!\n");
- struct alias *m;
+ struct entry *m;
char *tmp2;
char tmp[512];
int len;
@@ -915,6 +794,18 @@ void message_handler(int fd,char *from,struct user *user,char *msg,int redones)
//... meh. it'd just be a LITTLE bit shorter.
// this still seems horrible though. all those constants in there that are just strlen()s...
+#ifdef USE_BUILTIN_HT
+ char *command;
+ char *args;
+ command=strcpy(msg);
+ if((args=strchr(' ',msg))) {
+ *args=0;
+ args++;
+ }
+ if(builtin[hash(command)]) {
+ builtin[hash(command)]->value(args);
+ }
+#else
if(!strncmp(msg,"!leetsetout ",12)) {
c_leetsetout(fd,from,msg+12);
}
@@ -995,10 +886,10 @@ void message_handler(int fd,char *from,struct user *user,char *msg,int redones)
else if(!strncmp(msg,"!aliases",8) && (!msg[8] || msg[8] == ' ')) {
c_aliases_h(fd,from,*(msg+8)?msg+9:0);
}
-
+#endif
else if(redones < 5) {
debug_time(fd,from,"checking aliases...");
- if((m=getalias_h(msg)) != NULL) {
+ if((m=ht_getentry(&alias,msg)) != NULL) {
sz=(strlen(msg)-strlen(m->original)+strlen(m->target)+1);
redo=format_magic(fd,from,user,m->target,*(msg+strlen(m->original)+1)=='\n'?"":(msg+strlen(m->original)+1));
message_handler(fd,from,user,redo,redones+1);
@@ -1017,12 +908,12 @@ void message_handler(int fd,char *from,struct user *user,char *msg,int redones)
}
void line_handler(int fd,char *line) {//this should be built into the libary?
- printf("line: %s\n",line);
char *s=line,*t=0,*u=0;
struct user *user=malloc(sizeof(struct user));
user->nick=0;
user->name=0;
user->host=0;
+ printf("line: %s\n",line);
if(strchr(line,'\r')) *strchr(line,'\r')=0;
if(strchr(line,'\n')) *strchr(line,'\n')=0;
//:nick!name@host MERP DERP :message
@@ -1085,15 +976,18 @@ void line_handler(int fd,char *line) {//this should be built into the libary?
}
}
if(s && t && u) {
- if(!strcmp(s,"PRIVMSG") && strcmp(user->nick,myuser->nick))
- if(strcmp(user->nick,myuser->nick))
+ if(!strcmp(s,"PRIVMSG") && strcmp(user->nick,myuser->nick)) {
+ if(strcmp(user->nick,myuser->nick)) {
message_handler(fd,*t=='#'?t:user->nick,user,++u,0);
- else
+ }
+ else {
if(debug) privmsg(fd,*t=='#'?t:user->nick,"This server has an echo");
+ }
+ }
}
if(s && user->nick && t) {
if(!strcmp(s,"JOIN")) {
- irc_mode(fd,t+1,"+v",user->nick);//why t+1? it starts with :?
+ irc_mode(fd,t+1,"+o",user->nick);//why t+1? it starts with :?
}
if(!strcmp(s,"MODE") && mode_magic) {
if(u) {
@@ -1129,9 +1023,8 @@ int main(int argc,char *argv[]) {
recording=0;
recording_raw=0;
start_time=time(0);
- htkl=0;
redo=0;
- inittable();
+ inittable(&alias,TSIZE);
myuser=malloc(sizeof(struct user));
myuser->nick=strdup(argc>1?argv[1]:NICK);
myuser->name="I_dunno";