#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <mp.h>
#include <libsec.h>
#include "dbstructs.h"
Frlist*
initl(char* objtype, uint objsize, char* objname, void* obj, char *listname)
{
Frlist* f;
if((objtype == nil) || (objname == nil) || (obj == nil) || (listname == nil)){
fprint(2, "incorrect library call to initl\n");
return nil;
}
f = (Frlist*)malloc(sizeof(Frlist));
f->listname = strdup(listname);
f->prev = nil;
f->next = nil;
f->first = f;
f->final = f;
f->index = 0;
f->obj = obj;
f->objname = strdup(objname);
f->objtype = strdup(objtype);
f->objsize = objsize;
return f;
}
Frlist*
putl(char* objtype, uint objsize, char* objname, void* obj, Frlist* old)
{
Frlist* f;
Frlist* tmpf;
Frlist* loopcheck;
if((objtype == nil) || (objname == nil) || (obj == nil) || (old == nil)){
fprint(2, "incorrect library call to putl\n");
return nil;
}
f = (Frlist*)malloc(sizeof(Frlist));
if(old->final == old){
f->final = f;
tmpf = old->first;
loopcheck = tmpf;
while(tmpf != nil){
tmpf->final = f;
tmpf = tmpf->next;
if(tmpf == loopcheck){
fprint(2, "putl: escaped from infinite loop\n");
break;
}
}
} else {
f->final = old->final;
old->next->prev = f;
}
f->first = old->first;
f->next = old->next;
f->index = old->index + 1;
f->listname = strdup(old->listname);
f->prev = old;
f->obj = obj;
f->objname = strdup(objname);
f->objtype = strdup(objtype);
f->objsize = objsize;
old->next = f;
tmpf = f->next;
loopcheck = tmpf;
while(tmpf != nil){
tmpf->index++;
tmpf = tmpf->next;
if(tmpf == loopcheck){
fprint(2, "putl: escape from infinite loop\n");
break;
}
}
return f;
}
Frlist*
preputl(char* objtype, uint objsize, char* objname, void* obj, Frlist* old)
{
Frlist* f;
Frlist* tmpf;
if((objtype == nil) || (objname == nil) || (obj == nil) || (old == nil)){
fprint(2, "incorrect library call to preputl\n");
return nil;
}
f = (Frlist*)malloc(sizeof(Frlist));
if(old->first == old){
f->first = f;
tmpf = old->first;
while(tmpf != nil){
tmpf->first = f;
tmpf = tmpf->next;
}
} else {
f->first = old->first;
old->prev->next = f;
}
f->final = old->final;
f->next = old;
f->index = old->index;
f->listname = strdup(old->listname);
f->prev = old->prev;
f->obj = obj;
f->objname = strdup(objname);
f->objtype = strdup(objtype);
f->objsize = objsize;
old->prev = f;
tmpf = f->next;
while(tmpf != nil){
tmpf->index++;
tmpf = tmpf->next;
}
return f;
}
Frlist*
getnuml(uint num, Frlist* old)
{
Frlist* f;
f = old->first;
while(f != nil){
if(f->index == num){
return f;
}
f = f->next;
}
return nil;
}
Frlist*
reml(Frlist* f)
{
Frlist *l;
Frlist *n;
Frlist* tmpf;
if(f == nil){
fprint(2, "attempt to free nonexistent list entry\n");
return nil;
}
l = f->prev;
n = f->next;
if(f->first = f){
tmpf = f->next;
while(tmpf != nil){
tmpf->first = n;
tmpf = tmpf->next;
}
}
if(f->final = f){
tmpf = f->prev;
while(tmpf != nil){
tmpf->final = l;
tmpf = tmpf->prev;
}
}
if(l != nil){
l->next = n;
}
if(n != nil){
n->prev = l;
}
tmpf = f->next;
while(tmpf != nil){
tmpf->index--;
tmpf=tmpf->next;
}
free(f);
return n;
}
void
clearl(Frlist* f)
{
Frlist *o;
if(f == nil){
fprint(2, "attempt to clear nonexistent list\n");
return;
}
f = f->first;
o = f;
while(f != nil){
f = f->next;
free(o);
o = f;
}
free(f);
}
Htab*
htinit(void* obj, uint size, char* key, char* htabname)
{
Htab* ht;
Hent* he;
if((obj == nil) || (key == nil) || (htabname == nil)){
fprint(2, "incorrect library call to htinit\n");
return nil;
}
ht = (Htab*)malloc(sizeof(Htab));
ht->name = strdup(htabname);
ht->entries = 0;
he = (Hent*)malloc(sizeof(Hent));
he->parent = ht;
he->index = ht->entries++;
he->key = strdup(key);
he->obj = obj;
he->objsize = size;
md5((uchar*)obj, size, he->hval, nil);
he->asciihash = strdup(hashconv((char*)he->hval));
ht->entlist = initl("Hent\0", sizeof(Hent), he->key, he, htabname);
he->ent = ht->entlist;
return ht;
}
Hent*
htput(void* obj, uint size, char* key, Htab* ht)
{
Hent* he;
if((obj == nil) || (key == nil) || (ht == nil)){
fprint(2, "incorrect library call to htput\n");
return nil;
}
he = (Hent*)malloc(sizeof(Hent));
he->parent = ht;
he->index = ++ht->entries;
he->key = strdup(key);
he->obj = obj;
he->objsize = size;
md5((uchar*)obj, size, he->hval, nil);
he->asciihash = strdup(hashconv((char*)he->hval));
ht->entlist = putl("Hent", sizeof(Hent), he->key, he, ht->entlist);
he->ent = ht->entlist;
return he;
}
Hent*
htgetbykey(char* key, Htab* ht)
{
Hent* he;
Frlist* curent;
Hent* answer;
if((key == nil) || (ht == nil)){
fprint(2, "incorrect library call to htgetbykey\n");
return nil;
}
answer = nil;
curent = ht->entlist;
curent = curent->first;
while(curent != nil){
he = curent->obj;
if(strcmp(he->key, key) == 0){
answer = he;
return(answer);
}
curent = curent->next;
}
return answer;
}
Hent*
htgetbyhash(uchar hash[MD5dlen], Htab* ht)
{
Hent* he;
Frlist* curent;
Hent* answer;
if((hash == nil) || (ht == nil)){
fprint(2, "incorrect library call to htgetbyhash\n");
return nil;
}
answer = nil;
curent = ht->entlist;
curent = curent->first;
while(curent != nil){
he = curent->obj;
if(memcmp(he->hval, hash, MD5dlen) == 0){
answer = he;
return(answer);
}
curent = curent->next;
}
return answer;
}
Hent*
htgetbyindex(uint index, Htab *ht)
{
Hent* he;
Frlist* curent;
Hent* answer;
if(ht == nil){
fprint(2, "incorrect library call to htgetbyindex\n");
return nil;
}
answer = nil;
curent = ht->entlist;
curent = curent->first;
while(curent != nil){
he = curent->obj;
if(he->index == index){
answer = he;
return(answer);
}
curent = curent->next;
}
return answer;
}
Hent*
htgetbygrep(char* grepfor, Htab* ht)
{
Hent* he;
Frlist* curent;
Hent* answer;
if((grepfor == nil) || (ht == nil)){
fprint(2, "incorrect library call to htgetbyhash\n");
return nil;
}
answer = nil;
curent = ht->entlist;
curent = curent->first;
while(curent != nil){
he = curent->obj;
if(strstr((char*)he->obj, grepfor) != 0){
answer = he;
return answer;
}
curent = curent->next;
}
return answer;
}
Hent*
htdropent(Hent* old)
{
Hent* he;
Hent* new;
Frlist* entlist;
if(old == nil){
fprint(2, "attempt to drop nonextistent hash table entry\n");
return nil;
}
he = old;
entlist = old->ent;
he->parent->entries--;
he->parent->entlist = reml(entlist);
entlist = he->parent->entlist;
if(entlist == nil){
free(old);
return(nil);
}
new = entlist->obj;
while(entlist != nil){
he = entlist->obj;
he->index--;
entlist = entlist->next;
}
free(old);
return new;
}
void
htcleartab(Htab* ht)
{
Hent* he;
if(ht == nil){
fprint(2, "attempt to clear nonexistent hash table\n");
return;
}
ht->entlist = ht->entlist->first;
while(ht->entlist != nil){
he = ht->entlist->obj;
htdropent(he);
}
free(ht);
}
char*
hashconv(char* hash)
{
char *tmpmsg;
tmpmsg = hash;
for(int i = 0; i < MD5dlen; i++){
tmpmsg[i] = toascii(tmpmsg[i]);
if(isgraph(tmpmsg[i])){
continue;
}
if((int)tmpmsg[i] == 127){
tmpmsg[i] = '@';
continue;
}
tmpmsg[i] = (char)((int)(tmpmsg[i]) + 65);
}
tmpmsg[MD5dlen -1] = '\0';
return tmpmsg;
}
|