From 7f82cd9b726f69f01c243833058e438c4e22b84f Mon Sep 17 00:00:00 2001 From: Epoch Qwert Date: Mon, 15 Sep 2014 02:46:47 -0500 Subject: did the TODO of making builtins use a hashtable. added two commands for dealing with them. if you want you can override builtins for security reasons? :) added a small program for doing tail -f for systems that may not have tail -f --- TODO | 2 + libhashtable/example.c | 2 + libhashtable/genheader.sh | 3 + libhashtable/hashtable.h | 16 +-- libhashtable/libhashtable.c | 24 ++-- scripts/startup | 1 + segfault.c | 333 +++++++++++++++++++++++--------------------- tailf.c | 27 ++++ 8 files changed, 228 insertions(+), 180 deletions(-) create mode 100755 libhashtable/genheader.sh create mode 100644 tailf.c diff --git a/TODO b/TODO index 760b05f..5b38e30 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ o convert aliases from a linked list to a hash-table with linked lists in each bucket. so O(whatever), much fast, many speed, wow. o fix the ugly stuff that is casted to void in returns. + o make segfault use a hashtable for builtins too --- ^^^ done ^^^ --- @@ -8,3 +9,4 @@ it can put a speed limit on that kind of stuff. (but why would the bot get an fd from the runit function?) o make the source code smaller or something. + diff --git a/libhashtable/example.c b/libhashtable/example.c index bc42a67..919d75c 100644 --- a/libhashtable/example.c +++ b/libhashtable/example.c @@ -19,5 +19,7 @@ int main(int argc,char *argv[]) { free(name); } printf("PATH='%s'\n",ht_getvalue(&ht,"PATH")); + //if you want to get a whole entry struct use ht_getnode(); + //getentry() just returns the first struct in the linked list in that bucket. return 0; } diff --git a/libhashtable/genheader.sh b/libhashtable/genheader.sh new file mode 100755 index 0000000..3995579 --- /dev/null +++ b/libhashtable/genheader.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cat libhashtable.c | head -n 22 | tail -n 16 > hashtable.h +cat libhashtable.c | grep '(.*) *{' | egrep -v 'if|for|while' | sed 's/ {/;/' >> hashtable.h diff --git a/libhashtable/hashtable.h b/libhashtable/hashtable.h index 820d230..f0e2a15 100644 --- a/libhashtable/hashtable.h +++ b/libhashtable/hashtable.h @@ -1,23 +1,23 @@ -struct entry {//linked list node. +struct entry {/*linked list node.*/ char *original; - char *target; - struct entry *prev;// doubly linked list. why? + void *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 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 + 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 hash(char *key);/*maybe use a seeded rand()? :) Thanks FreeArtMan*/ void inittable(struct hashtable *ht,int tsize); -int ht_setkey(struct hashtable *ht,char *key,char *value); +int ht_setkey(struct hashtable *ht,char *key,void *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); +void *ht_getvalue(struct hashtable *ht,char *msg); diff --git a/libhashtable/libhashtable.c b/libhashtable/libhashtable.c index c4ac2d3..e89d0cd 100644 --- a/libhashtable/libhashtable.c +++ b/libhashtable/libhashtable.c @@ -6,7 +6,7 @@ /* struct entry {//linked list node. char *original; - char *target; + void *target; struct entry *prev;// doubly linked list. why? struct entry *next; }; @@ -22,11 +22,8 @@ struct hashtable { }; */ -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(); +unsigned short hash(char *key) {//maybe use a seeded rand()? :) Thanks FreeArtMan + return (strlen(key)<<8)+(key[0]<<4)+key[1]; } void inittable(struct hashtable *ht,int tsize) { @@ -44,7 +41,7 @@ void inittable(struct hashtable *ht,int tsize) { } //this seems too complicated. -int ht_setkey(struct hashtable *ht,char *key,char *value) { +int ht_setkey(struct hashtable *ht,char *key,void *value) { unsigned short h=hash(key); struct entry *tmp; int i; @@ -63,8 +60,9 @@ int ht_setkey(struct hashtable *ht,char *key,char *value) { } 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; + //free(tmp->target);//WHY? no. + //if(!(tmp->target=strdup(value))) return 2; + tmp->target=value;//can't strdup for non-strings. do it yourself. return 0; } if(ht->bucket[h]->ll == NULL) { @@ -72,7 +70,8 @@ int ht_setkey(struct hashtable *ht,char *key,char *value) { 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; + //if(!(ht->bucket[h]->ll->target=strdup(value))) return 5; + ht->bucket[h]->ll->target=value; } else { //go to the end and add another entry to the ll. for(tmp=ht->bucket[h]->ll;tmp->next;tmp=tmp->next); @@ -80,7 +79,8 @@ int ht_setkey(struct hashtable *ht,char *key,char *value) { tmp->next->prev=tmp; tmp=tmp->next; if(!(tmp->original=strdup(key))) return 7; - if(!(tmp->target=strdup(value))) return 8; + //if(!(tmp->target=strdup(value))) return 8; + tmp->target=value; tmp->next=0; } return 0; @@ -109,7 +109,7 @@ struct entry *ht_getnode(struct hashtable *ht,char *msg) { } //you'll probably want to use me. -char *ht_getvalue(struct hashtable *ht,char *msg) { +void *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/scripts/startup b/scripts/startup index 28aeb10..7068ab4 100644 --- a/scripts/startup +++ b/scripts/startup @@ -1,4 +1,5 @@ !alias !rc !eval /home/segfault/scripts/rawcommand %s !alias !eval !leettail 22%s !alias !c !eval /home/segfault/scripts/command %s +!leettail 50/home/segfault/scripts/cmd_out !raw join #default diff --git a/segfault.c b/segfault.c index 7425a04..e4819d2 100644 --- a/segfault.c +++ b/segfault.c @@ -23,7 +23,7 @@ #define RAWLOG "./files/rawlog" #define LOG "./files/log" #define MAXTAILS 400 //just to have it more than the system default. -#define BS 502 +#define BS 4096 // !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 @@ -66,6 +66,7 @@ int lines_sent; unsigned long oldtime; struct hashtable alias; +struct hashtable builtin; struct user { char *nick; @@ -87,7 +88,7 @@ struct tail { char *shitlist[] = { 0 }; void message_handler(int fd,char *from,struct user *user,char *msg,int redones); -void c_untail(int fd,char *from, char *file); +void c_untail(int fd,char *from, char *file,struct user *user,...); void mywrite(int fd,char *b) { int r; @@ -241,7 +242,7 @@ void extra_handler(int fd) { if(feof(tailf[i].fp)) {//ended up being a HELL of a lot easier... maybe fix it sometime. clearerr(tailf[i].fp); if(tailf[i].opt & TAILO_CLOSE) {//use for eval - c_untail(fd,tailf[i].to,tailf[i].file); + c_untail(fd,tailf[i].to,tailf[i].file,0); return; } } @@ -255,7 +256,15 @@ void extra_handler(int fd) { fseek(tailf[i].fp,tmpo,SEEK_SET);//??? } if(tailf[i].lines != -1) { - if(fgets(tmp,BS-1,tailf[i].fp) ) {//for some reason using sizeof(tmp) didn't work. >_> + if(fgets(tmp,BS-1,tailf[i].fp) == NULL) {//for some reason using sizeof(tmp) didn't work. >_> + if(tailf[i].lines != 0 && (tailf[i].opt & TAILO_ENDMSG)) { + privmsg(fd,tailf[i].to,"---------- TAILO_ENDMSG border ----------"); + } + //snprintf(tmp2,sizeof(tmp)-1,"tailf[%d] (%s): errno: %d, ferror: %d",i,tailf[i].file,errno,ferror(tailf[i].fp)); + //privmsg(fd,tailf[i].to,tmp2); + tailf[i].lines=0; + } + else { tailf[i].lines++; mmerp=0; if(strchr(tmp,'\r')) *strchr(tmp,'\r')=0; @@ -282,11 +291,6 @@ void extra_handler(int fd) { tailf[i].lines=-1; //lock it. privmsg(fd,tailf[i].to,"--more--"); } - } else { - if(tailf[i].lines != 0 && (tailf[i].opt & TAILO_ENDMSG)) { - privmsg(fd,tailf[i].to,"---------- TAILO_ENDMSG border ----------"); - } - tailf[i].lines=0; } } else { //don't PM in here. shows a LOT of shit. @@ -295,7 +299,6 @@ void extra_handler(int fd) { } } - void file_tail(int fd,char *from,char *file,char *args,char opt,struct user *user) { int i,j; int fdd; @@ -329,13 +332,12 @@ void file_tail(int fd,char *from,char *file,char *args,char opt,struct user *use if(!(opt & TAILO_BEGIN)) { eofp(tailf[i].fp); } - tailf[i].to=malloc(strlen(from)+1); + tailf[i].to=strdup(from); if(!tailf[i].to) { mywrite(fd,"QUIT :malloc error 3!!!\r\n"); return; } - strcpy(tailf[i].to,from); - tailf[i].file=malloc(strlen(file)+1); + tailf[i].file=strdup(file); if(!tailf[i].file) { mywrite(fd,"QUIT :malloc error 4!!!\r\n"); return; @@ -358,17 +360,16 @@ void file_tail(int fd,char *from,char *file,char *args,char opt,struct user *use } } tailf[i].lines=0; - strcpy(tailf[i].file,file); } } -void c_botup(int fd,char *from) { +void c_botup(int fd,char *from,...) { char tmp[256]; snprintf(tmp,sizeof(tmp)-1,"botup: %lu",(unsigned long int)time(0)-start_time); privmsg(fd,from,tmp); } -void c_leettail(int fd,char *from,char *file,struct user *user) { +void c_leettail(int fd,char *from,char *file,struct user *user,...) { short a=file[0]-'0'; short b=file[1]-'0'; short c=(a*10)+(b); @@ -380,14 +381,19 @@ void c_leettail(int fd,char *from,char *file,struct user *user) { file_tail(fd,from,file+2,args,c,user); } -void c_changetail(int fd,char *from,char *line) { - char *merp; +void c_changetail(int fd,char *from,char *line,struct user *user,...) { + char *merp=0; int i; + char *mode=0; //if(line == 0) return mywrite(fd,"QUIT :line == 0 in changetail\r\n"); //if(from == 0) return mywrite(fd,"QUIT :from == 0 in changetail\r\n"); if((merp=strchr(line,' '))) { *merp=0; merp++; + if((mode=strchr(merp,' '))) { + *mode=0; + mode++; + } } for(i=0;ill;m;m=m->next) { + if(strcasestr(m->original,line) || *line=='*') { + snprintf(tmp,sizeof(tmp)-1," %s -> %p",m->original,m->target); + privmsg(fd,from,tmp); + j++; + } + k++; + } + } + snprintf(tmp,sizeof(tmp)-1,"found %d of %d in builtins",j,k); + privmsg(fd,from,tmp); +} + +void c_aliases_h(int fd,char *from,char *line,...) { char tmp[512]; struct entry *m; int i,j=0,k=0; @@ -437,17 +492,13 @@ 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); } -/* -struct entry *getalias_h(char *msg) { - return leetgetalias(getkey_h(msg),msg); -} -*/ -void c_alias_h(int fd,char *from,char *line) { + +void c_alias_h(int fd,char *from,char *line,...) { char tmps[512]; char *derp=strchr(line,' '); struct entry *tmp; if(!derp) { - if((tmp=ht_getentry(&alias,line)) != NULL) { + if((tmp=ht_getnode(&alias,line)) != NULL) { privmsg(fd,from,tmp->target); } else { snprintf(tmps,sizeof(tmps),"'%s' not an alias.",line); @@ -457,12 +508,13 @@ void c_alias_h(int fd,char *from,char *line) { } *derp=0; derp++; - ht_setkey(&alias,line,derp); + if((tmp=ht_getnode(&alias,line))) { + free(tmp->target); + } + ht_setkey(&alias,line,strdup(derp)); } -//hash table version - -void c_kill(int fd,char *from,char *line) { +void c_kill(int fd,char *from,char *line,...) { char *csig=line; char *cpid=strchr(line,' '); int sig,pid; @@ -483,19 +535,19 @@ void c_kill(int fd,char *from,char *line) { } } -void c_pid(int fd,char *from) { +void c_pid(int fd,char *from,...) { char tmp[512]; snprintf(tmp,sizeof(tmp)-1,"pid: %d",getpid()); privmsg(fd,from,tmp); } -void c_id(int fd,char *from) { +void c_id(int fd,char *from,...) { char tmp[512]; snprintf(tmp,sizeof(tmp)-1,"u:%d g:%d eu:%d eg:%d",getuid(),getgid(),geteuid(),getegid()); privmsg(fd,from,tmp); } -void c_leetuntail(int fd,char *from,char *line) { +void c_leetuntail(int fd,char *from,char *line,...) { char *frm=line; char *file=0; int frmN=0; @@ -523,7 +575,7 @@ void c_leetuntail(int fd,char *from,char *line) { //snprintf(tmp,sizeof(tmp)-1,"%s from %s not being tailed.",file,frm); //privmsg(fd,from,tmp); } else { - c_untail(fd,frm,file); + c_untail(fd,frm,file,0); } } else { frmN=atoi(frm); @@ -542,7 +594,7 @@ void c_leetuntail(int fd,char *from,char *line) { } } -void c_tailunlock(int fd,char *from,char *file) { +void c_tailunlock(int fd,char *from,char *file,...) { int i; for(i=0;inick); + myuser->nick=strdup(msg); + irc_nick(fd,myuser->nick); +} + +void (*func)(int fd,...); void message_handler(int fd,char *from,struct user *user,char *msg,int redones) { struct entry *m; - char *tmp2; + char *command; + char *args; char tmp[512]; int len; int sz; @@ -784,112 +848,37 @@ void message_handler(int fd,char *from,struct user *user,char *msg,int redones) } } } - if(*msg == trigger_char) *msg='!'; - if(*msg != '!') { - return; - } + //if(*msg == trigger_char) *msg='!'; + //if(*msg != '!') { + // return; + //} //this section could probably be made a LOT shorter with //an array of structs that contain command and function pointer. //... 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))) { + command=strdup(msg); + if(command[0] == trigger_char) { + command++; + } else { + return; + } + //privmsg(fd,from,command); + if((args=strchr(command,' '))) { *args=0; args++; } - if(builtin[hash(command)]) { - builtin[hash(command)]->value(args); - } -#else - if(!strncmp(msg,"!leetsetout ",12)) { - c_leetsetout(fd,from,msg+12); - } - else if(!strncmp(msg,"!whoareyou",10) && !msg[10]) { - privmsg(fd,from,myuser->nick); - } - else if(!strncmp(msg,"!whoami",7) && !msg[7]) { - privmsg(fd,from,user->nick); - } - else if(!strncmp(msg,"!whereami",9) && !msg[9]) { - privmsg(fd,from,from); - } - else if(!strncmp(msg,"!resetout",9) && !msg[9]) { - c_resetout(fd,from); - } - else if(!strncmp(msg,"!botup",6) && !msg[6]) { - c_botup(fd,from); - } - else if(!strncmp(msg,"!linelimit",10) && (!msg[10] || msg[10] == ' ')) { - c_linelimit(fd,from,*(msg+10)?msg+11:0); - } - else if(!strncmp(msg,"!nick ",6) && msg[6]) { - free(myuser->nick); - myuser->nick=strdup(msg+6); - irc_nick(fd,myuser->nick); - } - else if(!strncmp(msg,"!tailunlock ",12)) { - c_tailunlock(fd,from,msg+12); - } - else if(!strncmp(msg,"!changetail ",12)) { - c_changetail(fd,from,msg+12); - } - else if(!strncmp(msg,"!tails",6) && !msg[6]) { - c_tails(fd,from); - } - else if(!strncmp(msg,"!record ",8)) { - c_record(fd,from,msg+8); - } - else if(!strncmp(msg,"!rawrecord ",11)) { - c_rawrecord(fd,from,msg+11); - } - else if(!strncmp(msg,"!leettail ",10)) { - c_leettail(fd,from,msg+10,user); - } - else if(!strncmp(msg,"!leetuntail ",12)) { - c_leetuntail(fd,from,msg+12); - } - else if(!strncmp(msg,"!leetappend ",12)) { - c_leetappend(fd,from,msg+12); - } - else if(!strncmp(msg,"!untail ",8)) { - c_untail(fd,from,msg+8); - } - else if(!strncmp(msg,"!raw ",5)) { - tmp2=malloc(strlen(msg)-5+4); - snprintf(tmp2,strlen(msg)-5+3,"%s\r\n",msg+5); - mywrite(fd,tmp2); - free(tmp2); - } - else if(!strncmp(msg,"!say ",5)) { - privmsg(fd,from,msg+5); - } - else if(!strncmp(msg,"!id",3) && !msg[3]) { - c_id(fd,from); - } - else if(!strncmp(msg,"!pid",4) && !msg[4]) { - c_pid(fd,from); - } - else if(!strncmp(msg,"!kill ",6)) { - c_kill(fd,from,msg+6); - } - else if(!strncmp(msg,"!alias ",7)) { - c_alias_h(fd,from,msg+7); - } -/* else if(!strncmp(msg,"!rmalias ",9)) { - c_rmalias(fd,from,msg+9); //need to make a hashtable version - }*/ - else if(!strncmp(msg,"!aliases",8) && (!msg[8] || msg[8] == ' ')) { - c_aliases_h(fd,from,*(msg+8)?msg+9:0); + if((func=ht_getvalue(&builtin,command))) { + // privmsg(fd,from,"found it in builtins HT."); + // snprintf(tmp,sizeof(tmp)-1,"c_pid: %p c_pid_returned: %p",c_pid,func); + // privmsg(fd,from,tmp); + func(fd,from,args,user); } -#endif else if(redones < 5) { debug_time(fd,from,"checking aliases..."); - if((m=ht_getentry(&alias,msg)) != NULL) { + command--;// :> + if((m=ht_getnode(&alias,command)) != 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); @@ -899,7 +888,7 @@ void message_handler(int fd,char *from,struct user *user,char *msg,int redones) } debug_time(fd,from,"finished checking aliases. not found."); redo=0; - snprintf(tmp,sizeof(tmp),"unknown command: %s",msg); + snprintf(tmp,sizeof(tmp),"unknown command: '%s' with args '%s'",command,args); privmsg(fd,from,tmp); } if(redones >5) { @@ -1013,6 +1002,30 @@ int main(int argc,char *argv[]) { struct passwd *pwd; char *s,*p; int c; + inittable(&builtin,TSIZE); + ht_setkey(&builtin,"builtin",c_builtin); + ht_setkey(&builtin,"builtins",c_builtins); + ht_setkey(&builtin,"raw",c_raw); + ht_setkey(&builtin,"leetsetout",c_leetsetout); + ht_setkey(&builtin,"resetout",c_resetout); + ht_setkey(&builtin,"botup",c_botup); + ht_setkey(&builtin,"linelimit",c_linelimit); + ht_setkey(&builtin,"nick",c_nick); + ht_setkey(&builtin,"tailunlock",c_tailunlock); + ht_setkey(&builtin,"changetail",c_changetail); + ht_setkey(&builtin,"tails",c_tails); + ht_setkey(&builtin,"record",c_record); + ht_setkey(&builtin,"rawrecord",c_rawrecord); + ht_setkey(&builtin,"leettail",c_leettail); + ht_setkey(&builtin,"leetuntail",c_leetuntail); + ht_setkey(&builtin,"leetappend",c_leetappend); + ht_setkey(&builtin,"untail",c_untail); + ht_setkey(&builtin,"say",c_say); + ht_setkey(&builtin,"id",c_id); + ht_setkey(&builtin,"pid",c_pid); + ht_setkey(&builtin,"kill",c_kill); + ht_setkey(&builtin,"alias",c_alias_h); + ht_setkey(&builtin,"aliases",c_aliases_h); mode_magic=0; trigger_char='!'; redirect_to_fd=-1; diff --git a/tailf.c b/tailf.c new file mode 100644 index 0000000..389e6a0 --- /dev/null +++ b/tailf.c @@ -0,0 +1,27 @@ +#include + +int main(int argc,char *argv[]) { + short in; + FILE *fp; + if(argc>1) { + if(!(fp=fopen(argv[1],"r"))) { + printf("file not found.\n"); + return 1; + } + while(1) { + if((in=fgetc(fp)) == -1) { + if(feof(fp)) { + clearerr(fp); + } else { + printf("unknown error from fgetc()"); + return 2; + } + } else { + printf("%c",in); + fflush(stdout); + } + } + } else { + printf("usage: tailf filename\n"); + } +} -- cgit v1.2.3