1 /******************************************************************************
2   Copyright (c) 1992, 1995, 1996 Xerox Corporation.  All rights reserved.
3   Portions of this code were written by Stephen White, aka ghond.
4   Use and copying of this software and preparation of derivative works based
5   upon this software are permitted.  Any distribution of this software or
6   derivative works must comply with all applicable United States export
7   control laws.  This software is made available AS IS, and Xerox Corporation
8   makes no warranty about the software, its performance or its conformity to
9   any specification.  Any person obtaining a copy of this software is requested
10   to send their name and post office or electronic mail address to:
11     Pavel Curtis
12     Xerox PARC
13     3333 Coyote Hill Rd.
14     Palo Alto, CA 94304
15     Pavel@Xerox.Com
16  *****************************************************************************/
17 
18 #ifndef DB_h
19 #define DB_h 1
20 
21 #include "config.h"
22 #include "program.h"
23 #include "structures.h"
24 
25 
26 /**** file system ****/
27 
28 extern const char *db_usage_string(void);
29 				/* Returns a string describing the database
30 				 * command-line arguments.
31 				 */
32 
33 extern int db_initialize(int *pargc, char ***pargv);
34 				/* (*pargc) and (*pargv) refer to the database
35 				 * command-line arguments and perhaps others.
36 				 * Returns true (and sets (*pargc) and (*pargv)
37 				 * to refer to any extra arguments) if the
38 				 * database args were valid.
39 				 */
40 
41 extern int db_load(void);
42 				/* Does any necessary long-running preparations
43 				 * of the database, such as loading significant
44 				 * amounts of data into memory, returning true
45 				 * iff this operation is successful.
46 				 */
47 
48 enum db_flush_type {
49     FLUSH_IF_FULL,		/* Do output only if there's `too much' changed
50 				 * data in memory now. */
51     FLUSH_ONE_SECOND,		/* Do output for up to about one second. */
52     FLUSH_ALL_NOW,		/* Do all pending output, forking the server
53 				 * if necessary. */
54     FLUSH_PANIC			/* Do all pending output; the server is going
55 				 * down in emergency mode. */
56 };
57 
58 extern int db_flush(enum db_flush_type);
59 				/* Flush some amount of the changed portion of
60 				 * the database to disk, as indicated by the
61 				 * argument.  Returns true on success.
62 				 */
63 
64 extern int32 db_disk_size(void);
65 				/* Return the total size, in bytes, of the most
66 				 * recent full representation of the database
67 				 * as one or more disk files.  Returns -1 if,
68 				 * for some reason, no such on-disk
69 				 * representation is currently available.
70 				 */
71 
72 extern void db_shutdown(void);
73 				/* Shut down the database module, flushing all
74 				 * pending database changes to disk and only
75 				 * returning after this is done.
76 				 */
77 
78 /**** objects ****/
79 
80 extern Objid db_create_object(void);
81 				/* Creates a new object with parent & location
82 				 * == #-1.  Returns new object's id number.
83 				 */
84 
85 extern Objid db_last_used_objid(void);
86 extern void db_reset_last_used_objid(void);
87 				/* The former returns the highest object number
88 				 * ever returned by db_create_object().  The
89 				 * latter resets that high-water mark to the
90 				 * highest object number referring to a
91 				 * currently-valid object.
92 				 */
93 
94 extern void db_destroy_object(Objid);
95 				/* Destroys object, freeing all associated
96 				 * storage.  The object's parent and location
97 				 * must == #-1 and it must not have any
98 				 * children or contents.
99 				 */
100 
101 extern Objid db_renumber_object(Objid);
102 				/* Renumbers object to have the lowest free
103 				 * object number.  Returns its new number.
104 				 */
105 
106 extern int valid(Objid);
107 
108 extern int db_object_bytes(Objid);
109 				/* Returns the number of bytes of memory
110 				 * currently required in order to represent the
111 				 * given object and all of its verbs and
112 				 * properties.
113 				 */
114 
115 /**** object attributes ****/
116 
117 extern Objid db_object_owner(Objid);
118 extern void db_set_object_owner(Objid oid, Objid owner);
119 
120 extern const char *db_object_name(Objid);
121 extern void db_set_object_name(Objid oid, const char *name);
122 				/* These functions do not change the reference
123 				 * count of the name they accept/return.  Thus,
124 				 * the caller should str_ref() the name if the
125 				 * reference is to be persistent.
126 				 */
127 
128 extern Objid db_object_parent(Objid);
129 extern int db_count_children(Objid);
130 extern int db_for_all_children(Objid,
131 			       int (*)(void *, Objid),
132 			       void *);
133 				/* The outcome is unspecified if any of the
134 				 * following functions are called during a call
135 				 * to db_for_all_children():
136 				 *      db_create_object()
137 				 *      db_destroy_object()
138 				 *      db_renumber_object()
139 				 *      db_change_parent()
140 				 */
141 extern int db_change_parent(Objid oid, Objid parent);
142 				/* db_change_parent() returns true (and
143 				 * actually changes the parent of OID) iff
144 				 * neither OID nor any of its descendents
145 				 * defines any properties with the same names
146 				 * as properties defined on PARENT or any of
147 				 * its ancestors.
148 				 */
149 
150 extern Objid db_object_location(Objid);
151 extern int db_count_contents(Objid);
152 extern int db_for_all_contents(Objid,
153 			       int (*)(void *, Objid),
154 			       void *);
155 				/* The outcome is unspecified if any of the
156 				 * following functions are called during a call
157 				 * to db_for_all_contects():
158 				 *      db_destroy_object()
159 				 *      db_renumber_object()
160 				 *      db_change_location()
161 				 */
162 extern void db_change_location(Objid oid, Objid location);
163 
164 /* NOTE: New flags must always be added to the end of this list, rather than
165  *     replacing one of the obsolete ones, since old databases might have
166  *       old objects around that still have that flag set.
167  */
168 typedef enum {
169     FLAG_USER, FLAG_PROGRAMMER, FLAG_WIZARD, FLAG_OBSOLETE_1,
170     FLAG_READ, FLAG_WRITE, FLAG_OBSOLETE_2, FLAG_FERTILE
171 } db_object_flag;
172 
173 extern int db_object_has_flag(Objid, db_object_flag);
174 extern void db_set_object_flag(Objid, db_object_flag);
175 extern void db_clear_object_flag(Objid, db_object_flag);
176 
177 extern int db_object_allows(Objid oid, Objid progr,
178 			    db_object_flag flag);
179 				/* Returns true iff either OID has FLAG or
180 				 * PROGR either is a wizard or owns OID; that
181 				 * is, iff PROGR's authority is sufficient to
182 				 * be allowed to do the indicated operation on
183 				 * OID.
184 				 */
185 
186 extern int is_wizard(Objid oid);
187 extern int is_programmer(Objid oid);
188 extern int is_user(Objid oid);
189 
190 extern Var db_all_users(void);
191 				/* db_all_users() does not change the reference
192 				 * count of the `users' list maintained by this
193 				 * module.  The caller should thus var_ref() it
194 				 * to make it persistent.
195 				 */
196 
197 
198 /**** properties *****/
199 
200 typedef enum {
201     PF_READ = 01,
202     PF_WRITE = 02,
203     PF_CHOWN = 04
204 } db_prop_flag;
205 
206 extern int db_add_propdef(Objid oid, const char *pname,
207 			  Var value, Objid owner,
208 			  unsigned flags);
209 				/* Returns true (and actually adds the property
210 				 * to OID) iff (1) no property named PNAME
211 				 * already exists on OID or one of its
212 				 * ancestors or descendants, and (2) PNAME does
213 				 * not name any built-in property.  This
214 				 * function does not change the reference count
215 				 * of VALUE, so the caller should var_ref() it
216 				 * if the caller's reference is to persist.
217 				 * FLAGS should be the result of ORing together
218 				 * zero or more elements of `db_prop_flag'.
219 				 */
220 
221 extern int db_rename_propdef(Objid oid, const char *old,
222 			     const char *new);
223 				/* Returns true (and actually renames the
224 				 * propdef on OID) iff (1) a propdef with the
225 				 * name OLD existed on OID, (2) no property
226 				 * named NEW already exists on OID or one of
227 				 * its ancestors or descendants, and (3) NEW
228 				 * does not name any built-in property.  If
229 				 * condition (1) holds and OLD == NEW, then
230 				 * this is a no-op that returns true.
231 				 */
232 
233 extern int db_delete_propdef(Objid, const char *);
234 				/* Returns true iff a propdef with the given
235 				 * name existed on the object (i.e., was there
236 				 * to be deleted).
237 				 */
238 
239 extern int db_count_propdefs(Objid);
240 extern int db_for_all_propdefs(Objid,
241 			       int (*)(void *, const char *),
242 			       void *);
243 				/* db_for_all_propdefs() does not change the
244 				 * reference counts of the property names
245 				 * passed to the given callback function.
246 				 * Thus, the caller should str_ref() the names
247 				 * if the references are to be persistent.
248 				 */
249 
250 enum bi_prop {
251     BP_NONE = 0,
252     BP_NAME, BP_OWNER,
253     BP_PROGRAMMER, BP_WIZARD,
254     BP_R, BP_W, BP_F,
255     BP_LOCATION, BP_CONTENTS
256 };
257 
258 typedef struct {
259     enum bi_prop built_in;	/* true iff property is a built-in one */
260     Objid definer;		/* if !built_in, the object defining prop */
261     void *ptr;			/* null iff property not found */
262 } db_prop_handle;
263 
264 extern db_prop_handle db_find_property(Objid oid, const char *name,
265 				       Var * value);
266 				/* Returns a handle on the named property of
267 				 * the given object.  If `value' is non-null,
268 				 * then the value of the named property (after
269 				 * skipping over any `clear' slots up the
270 				 * ancestor list) will be stored through it.
271 				 * For non-built-in properties, the reference
272 				 * count of the value is not changed by this
273 				 * function, so the caller should var_ref() it
274 				 * if it is to be persistent; some built-in
275 				 * properties have freshly generated values, so
276 				 * the caller should free_var() the value in
277 				 * the built-in case if it is *not* to be
278 				 * persistent.  The `ptr' in the result of this
279 				 * function will be null iff there is no such
280 				 * property on the object.  The `built_in'
281 				 * field in the result is true iff the named
282 				 * property is one built into all objects, in
283 				 * which case it specifies which such property
284 				 * it is.  The returned handle is very
285 				 * volatile; only the routines declared
286 				 * immediately below as taking a
287 				 * `db_prop_handle' argument are guaranteed to
288 				 * leave the handle intact.
289 				 */
290 
291 extern Var db_property_value(db_prop_handle);
292 extern void db_set_property_value(db_prop_handle, Var);
293 				/* For non-built-in properties, these functions
294 				 * do not change the reference count of the
295 				 * value they accept/return, so the caller
296 				 * should var_ref() the value if it is to be
297 				 * persistent.  Some built-in properties have
298 				 * freshly generated values, so the caller
299 				 * should free_var() the value in the built-in
300 				 * case if it is *not* to be persistent.
301 				 * The server will panic if
302 				 * `db_set_property_value()' is called with an
303 				 * illegal value for a built-in property.
304 				 */
305 
306 extern Objid db_property_owner(db_prop_handle);
307 extern void db_set_property_owner(db_prop_handle, Objid);
308 				/* These functions may not be called for
309 				 * built-in properties.
310 				 */
311 
312 extern unsigned db_property_flags(db_prop_handle);
313 extern void db_set_property_flags(db_prop_handle, unsigned);
314 				/* The property flags are the result of ORing
315 				 * together zero or more elements of
316 				 * `db_prop_flag', defined above.  These
317 				 * functions may not be called for built-in
318 				 * properties.
319 				 */
320 
321 extern int db_property_allows(db_prop_handle, Objid,
322 			      db_prop_flag);
323 				/* Returns true iff either the property has the
324 				 * flag or the object either is a wizard or
325 				 * owns the property; that is, iff the object's
326 				 * authority is sufficient to be allowed to do
327 				 * the indicated operation on the property.
328 				 * This function may not be called for built-in
329 				 * properties.
330 				 */
331 
332 
333 /**** verbs ****/
334 
335 typedef enum {
336     VF_READ = 01,
337     VF_WRITE = 02,
338     VF_EXEC = 04,
339     VF_DEBUG = 010
340 } db_verb_flag;
341 
342 typedef enum {
343     ASPEC_NONE, ASPEC_ANY, ASPEC_THIS
344 } db_arg_spec;
345 
346 typedef enum {
347     PREP_ANY = -2,
348     PREP_NONE = -1,
349     Other_Preps = 0		/* Others are indices into DB-internal table */
350 } db_prep_spec;
351 
352 extern db_prep_spec db_find_prep(int argc, char *argv[],
353 				 int *first, int *last);
354 				/* Look for a prepositional phrase in the
355 				 * ARGC-element sequence ARGV, returning
356 				 * PREP_NONE if none was found.  If FIRST and
357 				 * LAST are both non-null, then the indices
358 				 * of the first and last word in the phrase
359 				 * are stored through them.  If either FIRST
360 				 * or LAST is null, then the match will fail
361 				 * unless the entire sequence is a phrase.
362 				 */
363 
364 extern db_prep_spec db_match_prep(const char *);
365 				/* Try to recognize the given string as a
366 				 * prepositional phrase, returning the
367 				 * appropriate db_prep_spec on success and
368 				 * PREP_NONE on failure.  The string may be of
369 				 * the form
370 				 *      [#]<digit>+
371 				 * (an optional hash mark followed by one or
372 				 * more decimal digits).  If the number so
373 				 * represented is a legitimate index for a
374 				 * prepositional phrase in the DB-internal
375 				 * table, the corresponding db_prep_spec is
376 				 * returned, or PREP_NONE otherwise.
377 				 */
378 
379 extern const char *db_unparse_prep(db_prep_spec);
380 				/* Returns a string giving the human-readable
381 				 * name(s) for the given preposition
382 				 * specification.  The returned string may not
383 				 * be dynamically allocated, so the caller
384 				 * should str_dup() it if it is to be
385 				 * persistent.
386 				 */
387 
388 extern void db_add_verb(Objid oid, const char *vnames,
389 			Objid owner, unsigned flags,
390 			db_arg_spec dobj, db_prep_spec prep,
391 			db_arg_spec iobj);
392 				/* This function does not change the reference
393 				 * count of the NAMES string it accepts.  Thus,
394 				 * the caller should str_ref() it if it is to
395 				 * be persistent.
396 				 */
397 
398 extern int db_count_verbs(Objid);
399 extern int db_for_all_verbs(Objid,
400 			    int (*)(void *, const char *),
401 			    void *);
402 				/* db_for_all_verbs() does not change the
403 				 * reference counts of the verb names
404 				 * passed to the given callback function.
405 				 * Thus, the caller should str_ref() the names
406 				 * if the references are to be persistent.
407 				 */
408 
409 typedef struct {
410     void *ptr;
411 } db_verb_handle;
412 
413 extern db_verb_handle db_find_command_verb(Objid oid, const char *verb,
414 					 db_arg_spec dobj, unsigned prep,
415 					   db_arg_spec iobj);
416 				/* Returns a handle on the first matching
417 				 * verb found defined on OID or one of its
418 				 * ancestors.  A matching verb has a name
419 				 * matching VERB, a dobj spec equal either to
420 				 * ASPEC_ANY or DOBJ, a prep spec equal either
421 				 * to PREP_ANY or PREP, and an iobj spec equal
422 				 * either to ASPEC_ANY or IOBJ.  The `ptr' in
423 				 * the result is null iff there is no such
424 				 * verb.  The returned handle is very volatile;
425 				 * only the routines declared below as taking a
426 				 * `db_verb_handle' argument are guaranteed to
427 				 * leave the handle intact.
428 				 */
429 
430 extern db_verb_handle db_find_callable_verb(Objid oid, const char *verb);
431 				/* Returns a handle on the first verb found
432 				 * defined on OID or one of its ancestors with
433 				 * a name matching VERB (and, for now, the
434 				 * VF_EXEC flag set).  The `ptr' in the result
435 				 * is null iff there is no such verb.  The
436 				 * returned handle is very volatile; only the
437 				 * routines declared below as taking a
438 				 * `db_verb_handle' argument are guaranteed to
439 				 * leave the handle intact.
440 				 */
441 
442 extern db_verb_handle db_find_defined_verb(Objid oid, const char *verb,
443 					   int allow_numbers);
444 				/* Returns a handle on the first verb found
445 				 * defined on OID with a name matching VERB
446 				 * (or, if ALLOW_NUMBERS is true and VERB has
447 				 * the form of a decimal natural number, the
448 				 * zero-based VERB'th verb defined on OID,
449 				 * whichever comes first).  The `ptr' in the
450 				 * result is null iff there is no such verb.
451 				 * The returned handle is very volatile; only
452 				 * the routines declared below as taking a
453 				 * `db_verb_handle' argument are guaranteed to
454 				 * leave the handle intact.
455 				 */
456 
457 extern db_verb_handle db_find_indexed_verb(Objid oid, unsigned index);
458 				/* Returns a handle on the 1-based INDEX'th
459 				 * verb defined on OID.  The `ptr' in the
460 				 * result is null iff there is no such verb.
461 				 * The returned handle is very volatile; only
462 				 * the routines declared below as taking a
463 				 * `db_verb_handle' argument are guaranteed to
464 				 * leave the handle intact.
465 				 */
466 
467 extern Objid db_verb_definer(db_verb_handle);
468 				/* Returns the object on which the given verb
469 				 * is defined.
470 				 */
471 
472 extern const char *db_verb_names(db_verb_handle);
473 extern void db_set_verb_names(db_verb_handle, const char *);
474 				/* These functions do not change the reference
475 				 * count of the string they accept/return.
476 				 * Thus, the caller should str_ref() it if it
477 				 * is to be persistent.
478 				 */
479 
480 extern Objid db_verb_owner(db_verb_handle);
481 extern void db_set_verb_owner(db_verb_handle, Objid);
482 
483 extern unsigned db_verb_flags(db_verb_handle);
484 extern void db_set_verb_flags(db_verb_handle, unsigned);
485 
486 extern Program *db_verb_program(db_verb_handle);
487 extern void db_set_verb_program(db_verb_handle, Program *);
488 				/* These functions do not change the reference
489 				 * count of the program they accept/return.
490 				 * Thus, the caller should program_ref() it if
491 				 * it is to be persistent.
492 				 */
493 
494 extern void db_verb_arg_specs(db_verb_handle h,
495 			      db_arg_spec * dobj,
496 			      db_prep_spec * prep,
497 			      db_arg_spec * iobj);
498 extern void db_set_verb_arg_specs(db_verb_handle h,
499 				  db_arg_spec dobj,
500 				  db_prep_spec prep,
501 				  db_arg_spec iobj);
502 
503 extern int db_verb_allows(db_verb_handle, Objid, db_verb_flag);
504 				/* Returns true iff either the verb has the
505 				 * flag or the object either is a wizard or
506 				 * owns the verb; that is, iff the object's
507 				 * authority is sufficient to be allowed to do
508 				 * the indicated operation on the verb.
509 				 */
510 
511 extern void db_delete_verb(db_verb_handle);
512 				/* Deletes the given verb entirely.  This
513 				 * db_verb_handle may not be used again after
514 				 * this call returns.
515 				 */
516 
517 #endif				/* !DB_h */
518 
519 /*
520  * $Log: db.h,v $
521  * Revision 1.3  1998/12/14 13:17:32  nop
522  * Merge UNSAFE_OPTS (ref fixups); fix Log tag placement to fit CVS whims
523  *
524  * Revision 1.2  1997/03/03 04:18:26  nop
525  * GNU Indent normalization
526  *
527  * Revision 1.1.1.1  1997/03/03 03:45:02  nop
528  * LambdaMOO 1.8.0p5
529  *
530  * Revision 2.5  1996/05/12  21:31:37  pavel
531  * Added documentation of the memory-management policy for db_add_verb().
532  * Release 1.8.0p5.
533  *
534  * Revision 2.4  1996/02/11  00:47:04  pavel
535  * Enhanced db_find_property() to report the defining object of the found
536  * property.  Release 1.8.0beta2.
537  *
538  * Revision 2.3  1996/02/08  06:28:33  pavel
539  * Updated copyright notice for 1996.  Release 1.8.0beta1.
540  *
541  * Revision 2.2  1995/12/28  00:30:27  pavel
542  * Added db_disk_size().  Changed db_delete_verb() to unbundle how the verb is
543  * found.  Added support to db_find_defined_verb() for suppressing old
544  * numeric-string behavior.  Release 1.8.0alpha3.
545  *
546  * Revision 2.1  1995/12/11  07:56:12  pavel
547  * Added `db_object_bytes()' and `db_rename_propdef()'.  Clarified
548  * reference-counting behavior of built-in property references.
549  *
550  * Release 1.8.0alpha2.
551  *
552  * Revision 2.0  1995/11/30  05:05:11  pavel
553  * New baseline version, corresponding to release 1.8.0alpha1.
554  */
555