Plan 9 from Bell Labs’s /usr/web/sources/contrib/mycroftiv/unreleased/listfs/dbfuncs.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].