New module gip: Gateway IPc module.
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 27 Mar 1995 08:24:57 +0000 (08:24 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 27 Mar 1995 08:24:57 +0000 (08:24 +0000)
New module gw-db: Gateway hash-db module (user information table).

util/Makefile
util/gip.c [new file with mode: 0644]
util/gipc.c [new file with mode: 0644]
util/gips.c [new file with mode: 0644]
util/gw-db.c [new file with mode: 0644]
util/gwdbtest.c [new file with mode: 0644]

index 3e34da0..6141629 100644 (file)
@@ -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 (file)
index 0000000..9604f34
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <gip.h>
+
+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 (file)
index 0000000..8116745
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <gip.h>
+
+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 (file)
index 0000000..8c92960
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <gip.h>
+
+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 (file)
index 0000000..5bbe23f
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <gw-db.h>
+
+#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; i<DB_HASH; i++)
+           db->hash_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 (file)
index 0000000..e2f91fc
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <gw-db.h>
+
+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);
+}