5 * Revision 1.1 1995/03/27 08:25:01 adam
6 * New module gip: Gateway IPc module.
7 * New module gw-db: Gateway hash-db module (user information table).
20 #define FILE_HEAD_LEN 128
41 static int write_head (GW_DB db)
43 char file_head_buf[FILE_HEAD_LEN];
46 if (lseek (db->fd, 0L, SEEK_SET) == -1)
48 memcpy (file_head_buf, &db->head, sizeof(db->head));
49 r = write (db->fd, file_head_buf, FILE_HEAD_LEN);
52 r = write (db->fd, db->hash_array, DB_HASH * sizeof(*db->hash_array));
58 static unsigned hash (const char *name)
63 l = l*65599 + *name++;
67 static void lock_file (int fd, int type)
71 area.l_whence = SEEK_SET;
74 fcntl (fd, F_SETLKW, &area);
77 int gw_db_lookup (GW_DB db, const char *name, int name_length,
78 void **buf, size_t *count)
80 struct db_bucket bucket;
81 unsigned l = hash (name);
87 for (pos = db->hash_array[l]; pos; pos = bucket.next)
91 if (lseek (db->fd, pos, SEEK_SET) == -1)
96 r = read (db->fd, &bucket, sizeof(bucket));
102 if (r != sizeof(bucket))
107 if (bucket.name_length <= 0 || bucket.info_length <= 0 ||
108 bucket.name_length >= 16384 || bucket.info_length >= 262144)
113 if (bucket.name_length != name_length)
115 blen = bucket.name_length + bucket.info_length;
120 if (!(dbuf = malloc (dsize)))
123 r = read (db->fd, dbuf, blen);
134 if (memcmp (name, dbuf, name_length))
137 *count = bucket.info_length;
138 *buf = malloc (*count);
144 memcpy (*buf, dbuf + name_length, *count);
152 int gw_db_insert (GW_DB db, const char *name, int name_length,
153 const void *buf, size_t count)
155 struct db_bucket n_bucket;
156 struct db_bucket bucket;
158 unsigned l = hash (name);
159 int pos = db->hash_array[l];
163 (db->head.no_of_entries)++;
164 (db->head.sequence_no)++;
165 n_bucket.name_length = name_length;
166 n_bucket.info_length = count;
167 n_pos = lseek (db->fd, 0, SEEK_END);
171 db->hash_array[l] = n_pos;
174 r = write (db->fd, &n_bucket, sizeof(n_bucket));
177 else if (r < sizeof(n_bucket))
180 r = write (db->fd, name, name_length);
183 else if (r < name_length)
186 r = write (db->fd, buf, count);
192 r_pos = lseek (db->fd, pos, SEEK_SET);
195 r = read (db->fd, &bucket, sizeof(bucket));
198 else if (r < sizeof(bucket))
202 r_pos = lseek (db->fd, pos, SEEK_SET);
205 r = write (db->fd, &bucket, sizeof(bucket));
208 else if (r < sizeof(bucket))
213 static GW_DB gw_db_free (GW_DB db)
215 free (db->hash_array);
220 GW_DB gw_db_open (const char *fname, int write_flag)
222 char file_head_buf[FILE_HEAD_LEN];
226 if (!(db = malloc (sizeof(*db))))
229 if (!(db->hash_array = malloc (DB_HASH * sizeof(*db->hash_array))))
230 return gw_db_free (db);
232 db->fd = open (fname, O_RDWR|O_CREAT, 0666);
234 db->fd = open (fname, O_RDONLY);
236 return gw_db_free (db);
237 lock_file (db->fd, write_flag ? F_WRLCK : F_RDLCK);
238 r = read (db->fd, file_head_buf, FILE_HEAD_LEN);
240 return gw_db_free (db);
241 if (r < FILE_HEAD_LEN)
246 return gw_db_free (db);
247 db->head.no_of_entries = 0;
248 db->head.sequence_no = 1;
249 for (i=0; i<DB_HASH; i++)
250 db->hash_array[i] = 0;
252 return gw_db_free (db);
256 memcpy (&db->head, file_head_buf, sizeof(db->head));
257 r = read (db->fd, db->hash_array, sizeof(*db->hash_array)*DB_HASH);
258 if (r < sizeof(*db->hash_array)*DB_HASH)
259 return gw_db_free (db);
265 int gw_db_close (GW_DB db)
271 lock_file (db->fd, F_UNLCK);
272 if (close (db->fd) == -1)
281 int gw_db_no_ent (GW_DB db)
283 return db->head.no_of_entries;
286 int gw_db_seq_no (GW_DB db)
288 return db->head.sequence_no;