From ad67147ba5d2e4287bacfcbdaac2e5d9058cb400 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 27 Mar 1995 08:24:57 +0000 Subject: [PATCH] New module gip: Gateway IPc module. New module gw-db: Gateway hash-db module (user information table). --- util/Makefile | 12 ++- util/gip.c | 94 ++++++++++++++++++ util/gipc.c | 54 +++++++++++ util/gips.c | 46 +++++++++ util/gw-db.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/gwdbtest.c | 56 +++++++++++ 6 files changed, 550 insertions(+), 2 deletions(-) create mode 100644 util/gip.c create mode 100644 util/gipc.c create mode 100644 util/gips.c create mode 100644 util/gw-db.c create mode 100644 util/gwdbtest.c diff --git a/util/Makefile b/util/Makefile index 3e34da0..6141629 100644 --- a/util/Makefile +++ b/util/Makefile @@ -2,7 +2,11 @@ # Europagate, 1995 # # $Log: Makefile,v $ -# Revision 1.8 1995/03/10 09:10:56 adam +# Revision 1.9 1995/03/27 08:24:57 adam +# New module gip: Gateway IPc module. +# New module gw-db: Gateway hash-db module (user information table). +# +# Revision 1.8 1995/03/10 09:10:56 adam # Removed dbc2709_cvt function. Makes heuristic guess for DBC2709 records. # # Revision 1.7 1995/02/22 21:32:36 adam @@ -29,8 +33,9 @@ SHELL=/bin/sh INCLUDE=-I../include CFLAGS=-g -Wall -pedantic -ansi TPROG1=iso2709dump +TPROG2=gwdbtest LIB=../lib/util.a -PO=iso2709.o iso27dis.o +PO=iso2709.o iso27dis.o gw-db.o gip.o gips.o gipc.o CPP=$(CC) -E DEFS=$(INCLUDE) -DSTUPID_ISO_DBC=1 @@ -39,6 +44,9 @@ all: $(TPROG1) $(TPROG2) $(TPROG1): $(TPROG1).o $(LIB) $(CC) $(CFLAGS) -o $(TPROG1) $(TPROG1).o $(LIB) +$(TPROG2): $(TPROG2).o $(LIB) + $(CC) $(CFLAGS) -o $(TPROG2) $(TPROG2).o $(LIB) + $(LIB): $(PO) rm -f $(LIB) ar qc $(LIB) $(PO) diff --git a/util/gip.c b/util/gip.c new file mode 100644 index 0000000..9604f34 --- /dev/null +++ b/util/gip.c @@ -0,0 +1,94 @@ +/* Gateway kernel + * Europagate, 1995 + * + * $Log: gip.c,v $ + * Revision 1.1 1995/03/27 08:24:58 adam + * New module gip: Gateway IPc module. + * New module gw-db: Gateway hash-db module (user information table). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +GIP gip_initialize (const char *name) +{ + GIP gip = malloc (sizeof(*gip)); + + if (!gip) + return NULL; + if (!(gip->name = malloc (strlen(name)+1))) + { + free (gip); + return NULL; + } + strcpy (gip->name, name); + gip->ret = mknod (gip->name, S_IFIFO|0666, 0); + gip->errno = errno; + return gip; +} + +int gip_destroy (GIP gip) +{ + assert (gip); + + free (gip->name); + free (gip); + return 0; +} + +int gip_infileno (GIP gip) +{ + return gip->rfd; +} + +int gip_errno (GIP gip) +{ + return gip->errno; +} + +int gip_read (GIP gip, char *buf, size_t count) +{ + int r, no = 0; + while (no < count) + { + r = read (gip->rfd, buf+no, count-no); + if (r == -1) + { + gip->errno = errno; + return -1; + } + no += r; + } + return 0; +} + +int gip_write (GIP gip, const char *buf, size_t count) +{ + int r, no = 0; + while (no < count) + { + r = write (gip->wfd, buf+no, count-no); + if (r == -1) + { + gip->errno = errno; + return -1; + } + no += r; + } + return 0; +} + +int gip_wline (GIP gip, const char *buf) +{ + return gip_write (gip, buf, strlen(buf)); +} + diff --git a/util/gipc.c b/util/gipc.c new file mode 100644 index 0000000..8116745 --- /dev/null +++ b/util/gipc.c @@ -0,0 +1,54 @@ +/* Gateway kernel + * Europagate, 1995 + * + * $Log: gipc.c,v $ + * Revision 1.1 1995/03/27 08:24:59 adam + * New module gip: Gateway IPc module. + * New module gw-db: Gateway hash-db module (user information table). + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +GIP gipc_initialize (const char *name) +{ + return gip_initialize (name); +} + +int gipc_destroy (GIP gip) +{ + return gip_destroy (gip); +} + +int gipc_open (GIP gip, const char *server, int sync) +{ + if (sync) + { + gip->rfd = open (gip->name, O_RDONLY); + gip->wfd = open (server, O_WRONLY); + } + else + { + gip->wfd = open (server, O_WRONLY); + gip->rfd = open (gip->name, O_RDONLY); + } + if (gip->rfd == -1) + return -1; + if (gip->wfd == -1) + return -1; + return 0; +} + +int gipc_close (GIP gip) +{ + close (gip->rfd); + close (gip->wfd); + return 0; +} diff --git a/util/gips.c b/util/gips.c new file mode 100644 index 0000000..8c92960 --- /dev/null +++ b/util/gips.c @@ -0,0 +1,46 @@ +/* Gateway kernel + * Europagate, 1995 + * + * $Log: gips.c,v $ + * Revision 1.1 1995/03/27 08:25:00 adam + * New module gip: Gateway IPc module. + * New module gw-db: Gateway hash-db module (user information table). + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +GIP gips_initialize (const char *name) +{ + return gip_initialize (name); +} + +int gips_destroy (GIP gip) +{ + return gip_destroy (gip); +} + +int gips_open (GIP gip, const char *client) +{ + gip->wfd = open (client, O_WRONLY); + gip->rfd = open (gip->name, O_RDONLY); + if (gip->rfd == -1) + return -1; + if (gip->wfd == -1) + return -1; + return 0; +} + +int gips_close (GIP gip) +{ + close (gip->rfd); + close (gip->wfd); + return 0; +} diff --git a/util/gw-db.c b/util/gw-db.c new file mode 100644 index 0000000..5bbe23f --- /dev/null +++ b/util/gw-db.c @@ -0,0 +1,290 @@ +/* Gateway utility + * Europagate, 1995 + * + * $Log: gw-db.c,v $ + * Revision 1.1 1995/03/27 08:25:01 adam + * New module gip: Gateway IPc module. + * New module gw-db: Gateway hash-db module (user information table). + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define FILE_HEAD_LEN 128 +#define DB_HASH 1997 + +struct gw_db { + struct file_head { + char magic[8]; + int no_of_entries; + int sequence_no; + } head; + int *hash_array; + int fd; + int dirty; +}; + +struct db_bucket { + int name_length; + int info_length; + int next; + int prev; +}; + +static int write_head (GW_DB db) +{ + char file_head_buf[FILE_HEAD_LEN]; + int r; + + if (lseek (db->fd, 0L, SEEK_SET) == -1) + return -1; + memcpy (file_head_buf, &db->head, sizeof(db->head)); + r = write (db->fd, file_head_buf, FILE_HEAD_LEN); + if (r == -1) + return -1; + r = write (db->fd, db->hash_array, DB_HASH * sizeof(*db->hash_array)); + if (r == -1) + return -1; + return 0; +} + +static unsigned hash (const char *name) +{ + unsigned l = 0; + + while (*name) + l = l*65599 + *name++; + return l % DB_HASH; +} + +static void lock_file (int fd, int type) +{ + struct flock area; + area.l_type = type; + area.l_whence = SEEK_SET; + area.l_start = 0L; + area.l_len = 0L; + fcntl (fd, F_SETLKW, &area); +} + +int gw_db_lookup (GW_DB db, const char *name, int name_length, + void **buf, size_t *count) +{ + struct db_bucket bucket; + unsigned l = hash (name); + char *dbuf = NULL; + int dsize = 0; + int pos; + int r; + + for (pos = db->hash_array[l]; pos; pos = bucket.next) + { + int blen; + + if (lseek (db->fd, pos, SEEK_SET) == -1) + { + free (dbuf); + return -1; + } + r = read (db->fd, &bucket, sizeof(bucket)); + if (r == -1) + { + free (dbuf); + return -1; + } + if (r != sizeof(bucket)) + { + free (dbuf); + return -2; + } + if (bucket.name_length <= 0 || bucket.info_length <= 0 || + bucket.name_length >= 16384 || bucket.info_length >= 262144) + { + free (dbuf); + return -3; + } + if (bucket.name_length != name_length) + continue; + blen = bucket.name_length + bucket.info_length; + if (blen >= dsize) + { + dsize = blen + 1024; + free (dbuf); + if (!(dbuf = malloc (dsize))) + return -1; + } + r = read (db->fd, dbuf, blen); + if (r == -1) + { + free (dbuf); + return -1; + } + else if (r < blen) + { + free (dbuf); + return -2; + } + if (memcmp (name, dbuf, name_length)) + continue; + + *count = bucket.info_length; + *buf = malloc (*count); + if (!*buf) + { + free (dbuf); + return -1; + } + memcpy (*buf, dbuf + name_length, *count); + free (dbuf); + return 1; + } + free (dbuf); + return 0; +} + +int gw_db_insert (GW_DB db, const char *name, int name_length, + const void *buf, size_t count) +{ + struct db_bucket n_bucket; + struct db_bucket bucket; + off_t n_pos, r_pos; + unsigned l = hash (name); + int pos = db->hash_array[l]; + int r; + + db->dirty = 1; + (db->head.no_of_entries)++; + (db->head.sequence_no)++; + n_bucket.name_length = name_length; + n_bucket.info_length = count; + n_pos = lseek (db->fd, 0, SEEK_END); + if (n_pos == -1) + return -1; + n_bucket.next = pos; + db->hash_array[l] = n_pos; + n_bucket.prev = 0; + + r = write (db->fd, &n_bucket, sizeof(n_bucket)); + if (r == -1) + return -1; + else if (r < sizeof(n_bucket)) + return -2; + + r = write (db->fd, name, name_length); + if (r == -1) + return -1; + else if (r < name_length) + return -2; + + r = write (db->fd, buf, count); + if (r == -1) + return -1; + else if (r < count) + return -2; + + r_pos = lseek (db->fd, pos, SEEK_SET); + if (r_pos == -1) + return -1; + r = read (db->fd, &bucket, sizeof(bucket)); + if (r == -1) + return -1; + else if (r < sizeof(bucket)) + return -2; + bucket.prev = n_pos; + + r_pos = lseek (db->fd, pos, SEEK_SET); + if (r_pos == -1) + return -1; + r = write (db->fd, &bucket, sizeof(bucket)); + if (r == -1) + return -1; + else if (r < sizeof(bucket)) + return -2; + return 0; +} + +static GW_DB gw_db_free (GW_DB db) +{ + free (db->hash_array); + free (db); + return NULL; +} + +GW_DB gw_db_open (const char *fname, int write_flag) +{ + char file_head_buf[FILE_HEAD_LEN]; + GW_DB db; + int r; + + if (!(db = malloc (sizeof(*db)))) + return NULL; + db->dirty = 0; + if (!(db->hash_array = malloc (DB_HASH * sizeof(*db->hash_array)))) + return gw_db_free (db); + if (write_flag) + db->fd = open (fname, O_RDWR|O_CREAT, 0666); + else + db->fd = open (fname, O_RDONLY); + if (db->fd == -1) + return gw_db_free (db); + lock_file (db->fd, write_flag ? F_WRLCK : F_RDLCK); + r = read (db->fd, file_head_buf, FILE_HEAD_LEN); + if (r == -1) + return gw_db_free (db); + if (r < FILE_HEAD_LEN) + { + int i; + + if (!write_flag) + return gw_db_free (db); + db->head.no_of_entries = 0; + db->head.sequence_no = 1; + for (i=0; ihash_array[i] = 0; + if (write_head (db)) + return gw_db_free (db); + } + else + { + memcpy (&db->head, file_head_buf, sizeof(db->head)); + r = read (db->fd, db->hash_array, sizeof(*db->hash_array)*DB_HASH); + if (r < sizeof(*db->hash_array)*DB_HASH) + return gw_db_free (db); + } + return db; +} + + +int gw_db_close (GW_DB db) +{ + int r = 0; + + if (db->dirty) + r = write_head (db); + lock_file (db->fd, F_UNLCK); + if (close (db->fd) == -1) + { + gw_db_free (db); + return -1; + } + gw_db_free (db); + return r; +} + +int gw_db_no_ent (GW_DB db) +{ + return db->head.no_of_entries; +} + +int gw_db_seq_no (GW_DB db) +{ + return db->head.sequence_no; +} + diff --git a/util/gwdbtest.c b/util/gwdbtest.c new file mode 100644 index 0000000..e2f91fc --- /dev/null +++ b/util/gwdbtest.c @@ -0,0 +1,56 @@ +/* Gateway db utility test + * Europagate, 1995 + * + * $Log: gwdbtest.c,v $ + * Revision 1.1 1995/03/27 08:25:02 adam + * New module gip: Gateway IPc module. + * New module gw-db: Gateway hash-db module (user information table). + * + */ + +#include +#include +#include +#include + +#include + +int main (int argc, char **argv) +{ + char word[1024]; + GW_DB gwdb; + int no; + void *buf; + size_t count; + int r; + int no_insert = 0; + + gwdb = gw_db_open ("db.test", 1); + for (no = 0; scanf ("%s", word) == 1; no++) + { + r = gw_db_lookup (gwdb, word, strlen(word), & buf, &count); + if (r== 0) + { + char info[25]; + sprintf (info, "%d", no); + if (gw_db_insert (gwdb, word, strlen(word), info, strlen (info))) + { + printf ("gw_db_insert of %s failed\n", word); + exit (1); + } + no_insert++; + } + else if (r == 1) + { + free (buf); + } + else + { + printf ("gw_db_lookup of %s failed\n", word); + exit (1); + } + } + gw_db_close (gwdb); + printf ("Lookup: %d. Insert: %d\n", no, no_insert); + exit (0); +} -- 1.7.10.4