home *** CD-ROM | disk | FTP | other *** search
- /*
- * DBOT Version 1.0 Author : Vincent Hayward
- * School of Electrical Engineering
- * Purdue University
- * Dir : db
- * File : dbot.c
- * Remarks : All the functions of the library are there.
- * Usage : make install
- */
-
- /*LINTLIBRARY*/
-
- #include <stdio.h>
- #include <sys/types.h>
- #include "../h/rccl.h"
- #include "../h/umac.h"
-
- #define BEGIN 0 /* seek options */
- #define RELAT 1 /* .... */
- #define ENDOF 3 /* .... */
- #define RW 2 /* open ....... */
- #define BUFS 1024 /* best r/w buf */
- #define FREE 0 /* entry not allocated */
- #define HOLE -1 /* entry removed */
- #define MAGICD 0123 /* magic number data b */
- #define LABS 16 /* label size */
-
- #define MAX 85 /* 85 * sizeof(TRID) == 2040 */
-
- typedef struct { /* transform identity */
- char label[LABS]; /* name */
- time_t ttime; /* birth date */
- long addr; /* address */
- }TRID;
-
- typedef struct { /* internal storage represention */
- float px, py, pz, ox, oy, oz, ax, ay, az;
- } DBTR, *DBTR_PTR;
-
- /*
- * core image of the file header
- */
-
- static struct head {
- int magic;
- int nb;
- TRID table[MAX];
- } hd;
-
- char *ctime();
- time_t time();
- long lseek();
-
-
-
-
- #define READS(f, p)\
- if (read(f, (char *)&p, sizeof(p)) < 0) {\
- fprintf(stderr, "read error on data base file\n");\
- return(-1);}
-
- #define WRITES(f, p)\
- if (write(f, (char *)&p, sizeof(p)) < 0) {\
- fprintf(stderr, "write error on data base file\n");\
- return(-1);}
-
- #define SEEK(f, a, n)\
- if (lseek(f, a, n) < 0) {\
- fprintf(stderr, "seek error on data base file\n");\
- return(-1);}
-
- #define ISDB(h)\
- if (h .magic != MAGICD) {\
- fprintf(stderr, "bad magic number\n");\
- return(-1);}
-
- /*
- * creates a new data base file, which contains at least a table
- * of MAX TRID records.
- * All the records are initialize with a 0 creation or change time.
- *
- * A 'FREE' teach time means free entry in table.
- * Each time an entry is added, all the addr pointers of the 'FREE'
- * entries are set to the size of the file.
- * When an entry is removed, a HOLE is created.
- * The labels are C strings and therefore cannot contain more
- * than LABS -1 chars.
- */
-
- /*
- * create an empty data base
- */
-
- makedb(name) /*::*/
- char *name;
- {
- int fd, i, j;
-
- if ((fd = creat(name, 0644)) < 0) {
- fprintf(stderr, "could'nt creat transform data base file\n");
- return(-1);
- }
- if ((fd = open(name, RW)) < 0) {
- fprintf(stderr, "open error on data base file");
- return(-1);
- }
- for (i = 0; i < MAX; ++i) {
- for (j = 0; j < LABS; ++j) {
- hd.table[i].label[j] = '\0';
- }
- hd.table[i].ttime = FREE;
- hd.table[i].addr = sizeof(hd);
- }
- hd.magic = MAGICD;
- hd.nb = 0;
- WRITES(fd, hd);
- return(fd);
- }
-
-
- /*
- * sequential search of the entries in the table
- * return
- * index in the table,
- * -2 if not found,
- * -1 if io error
- */
-
- static search(n, fd) /*##*/
- char *n;
- int fd;
- {
- int i;
-
- SEEK(fd, 0L, BEGIN);
- READS(fd, hd);
- ISDB(hd);
- for (i = 0; i < MAX; ++i) {
- if (hd.table[i].ttime == FREE || hd.table[i].ttime == HOLE) {
- continue;
- }
- if (strncmp(n, hd.table[i].label, LABS - 1) == 0) {
- return(i);
- }
- }
- return(-2);
- }
-
-
- /*
- * save a transform in the data base
- * 1) look if exits, if yes prompts the user if can change change
- * 2) tries to fill holes
- * 3) extent if no hole
- *
- * return
- * 1 if change aborted by user
- * 0 if store successful
- * -1 if io error
- */
-
- savetr(t, fd) /*::*/
- TRSF_PTR t;
- int fd;
- {
- int q, i, j;
- DBTR dbt;
- char *m;
-
- i = search(t->name, fd);
- if (i == -1) {
- fprintf(stderr, "search error\n");
- return(-1);
- }
- if (i >= 0) {
- printf("savetr : %s created : %s",
- hd.table[i].label, ctime(&hd.table[i].ttime));
- printf("change ? ");
- QUERY(q);
- if (q == 'n') {
- return(1);
- }
- (void) time(&hd.table[i].ttime);
- m = "savetr : %s changed at %s";
- }
- else {
- q = NO;
- for (i = 0; i < MAX; ++i) {
- if (hd.table[i].ttime == HOLE) {
- (void) time(&hd.table[i].ttime);
- m = "savetr : %s Added at %s";
- q = YES;
- ++hd.nb;
- break;
- }
- }
- if (!q) {
- q = NO;
- for (i = 0; i < MAX; ++i) {
- if (hd.table[i].ttime == FREE) {
- (void) time(&hd.table[i].ttime);
- m = "savetr : %s added at %s";
- q = YES;
- ++hd.nb;
- break;
- }
- }
-
- if (!q) {
- fprintf(stderr, "data base file saturated\n");
- return(-1);
- }
- for (j = 0; j < MAX; ++j) {
- if (hd.table[j].ttime == FREE) {
- hd.table[j].addr += sizeof(DBTR);
- }
- }
- }
- }
- strcpyn(hd.table[i].label, t->name, LABS);
- printf(m, hd.table[i].label, ctime(&hd.table[i].ttime));
- SEEK(fd, hd.table[i].addr, BEGIN);
- cnvtrdb(&dbt, t);
- WRITES(fd, dbt);
- SEEK(fd, 0L, BEGIN);
- WRITES(fd, hd);
- return(0);
- }
-
-
- /*
- * get a transform out of the data base
- *
- * return
- * 0 if found
- * -2 if not found
- * -1 if io error
- */
-
-
- gettr(t, fd) /*::*/
- TRSF_PTR t;
- int fd;
- {
- int i;
- DBTR dbt;
-
- i = search(t->name, fd);
- if (i == -1) {
- fprintf(stderr, "search error\n");
- return(-1);
- }
- if (i >= 0) {
- SEEK(fd, hd.table[i].addr, BEGIN);
- READS(fd, dbt);
- cnvdbtr(t, &dbt);
- printf("gettr : %s last change : %s",
- hd.table[i].label, ctime(&hd.table[i].ttime));
- return(0);
- }
- else {
- printf("gettr : %s not found\n", t->name);
- return(-2);
- }
- }
-
-
- /*
- * remove a transform out of the data base
- *
- * return
- * 0 is successful
- * -2 if not found
- * -1 if io error
- */
-
- remtr(n, fd) /*::*/
- char *n;
- int fd;
- {
- int i;
-
- i = search(n, fd);
- if (i == -1) {
- fprintf(stderr, "search error\n");
- return(-1);
- }
- if (i >= 0) {
- hd.table[i].ttime = HOLE;
- --hd.nb;
- SEEK(fd, 0L, BEGIN);
- WRITES(fd, hd);
- printf("remtr : %s removed\n", n);
- return(0);
- }
- else {
- printf("remtr : %s not found\n", n);
- return(-2);
- }
- }
-
-
-
- /*
- * print the content of the data base
- *
- * return
- * 0 if ok
- * -1 if io error
- */
-
- dumpdb(fd, v) /*::*/
- int fd;
- bool v;
- {
- TRSF tr;
- DBTR dbt;
- int i;
-
- SEEK(fd, 0L, BEGIN);
- READS(fd, hd);
- ISDB(hd);
- printf("dump : %d entries\n", hd.nb);
- for (i = 0; i < MAX; ++i) {
- if (hd.table[i].ttime != FREE && hd.table[i].ttime != HOLE) {
- printf("%d ", (hd.table[i].addr - sizeof(hd)) / sizeof(DBTR));
- printf("%s , %s", hd.table[i].label, ctime(&hd.table[i].ttime));
- if(v) {
- SEEK(fd, hd.table[i].addr, BEGIN);
- READS(fd, dbt);
- cnvdbtr(&tr, &dbt);
- printf("%8.3f %8.3f %8.3f %8.3f\n",
- tr.n.x, tr.o.x, tr.a.x, tr.p.x);
- printf("%8.3f %8.3f %8.3f %8.3f\n",
- tr.n.y, tr.o.y, tr.a.y, tr.p.y);
- printf("%8.3f %8.3f %8.3f %8.3f\n",
- tr.n.z, tr.o.z, tr.a.z, tr.p.z);
- }
- }
- }
- return(0);
- }
-
-
- /*
- * compact the data base in place, for that make a copy of it
- *
- * return
- * 0 if ok
- * -1 if io error
- */
-
-
- static struct head hdc;
-
- compactdb(name)
- char *name;
- {
- char temp[40];
- int fd, fdt;
- char bd[BUFS];
- int n;
- DBTR dbt;
- int i, j, inc;
- char *sprintf();
-
- if ((fd = open(name, RW)) < 0) {
- fprintf(stderr, "open error on data base file %s\n", name);
- return(-1);
- }
- (void) sprintf(temp, "%d.cdb", getpid());
- if ((fdt = creat(temp, 0644)) < 0) {
- fprintf(stderr, "can't creat data base file %s\n", temp);
- return(-1);
- }
- if ((fdt = open(temp, RW)) < 0) {
- fprintf(stderr, "open error on data base file %s\n", temp);
- return(-1);
- }
- SEEK(fd, 0L, BEGIN);
- while ((n = read(fd, bd, BUFS)) > 0) {
- if (write(fdt, bd, n) < 0) {
- fprintf(stderr, "can't duplicate data base file\n");
- return(-1);
- }
- }
-
- fd = makedb(name);
- SEEK(fdt, 0L, BEGIN);
- READS(fdt, hdc);
- j = 0;
- inc = 0;
- for (i = 0; i < MAX; ++i) {
- if (hdc.table[i].ttime != HOLE && hdc.table[i].ttime != FREE) {
- SEEK(fdt, hdc.table[i].addr, BEGIN);
- READS(fdt, dbt);
- WRITES(fd, dbt);
- hd.table[j].addr += inc;
- inc += sizeof(DBTR);
- hd.table[j].ttime = hdc.table[i].ttime;
- strcpyn(hd.table[j].label, hdc.table[i].label, LABS);
- ++hd.nb;
- ++j;
- }
- }
- for (;j < MAX; ++j) {
- hd.table[j].addr += inc;
- }
- SEEK(fd, 0L, BEGIN);
- WRITES(fd, hd);
- if (unlink(temp) < 0) {
- fprintf(stderr, "could'nt unlink\n");
- return(-1);
- }
- return(0);
- }
-
-
- /*
- * convert a regular transform into data base format
- */
-
- static cnvtrdb(d, t) /*##*/
- DBTR_PTR d;
- TRSF_PTR t;
- {
- d->px = t->p.x;
- d->py = t->p.y;
- d->pz = t->p.z;
- d->ax = t->a.x;
- d->ay = t->a.y;
- d->az = t->a.z;
- d->ox = t->o.x;
- d->oy = t->o.y;
- d->oz = t->o.z;
- }
-
-
- /*
- * convert a data base format transform into regular
- */
-
- static cnvdbtr(t, d) /*##*/
- DBTR_PTR d;
- TRSF_PTR t;
- {
- t->p.x = d->px;
- t->p.y = d->py;
- t->p.z = d->pz;
- t->a.x = d->ax;
- t->a.y = d->ay;
- t->a.z = d->az;
- t->o.x = d->ox;
- t->o.y = d->oy;
- t->o.z = d->oz;
- t->n.x = t->o.y * t->a.z - t->o.z * t->a.y;
- t->n.y = t->o.z * t->a.x - t->o.x * t->a.z;
- t->n.z = t->o.x * t->a.y - t->o.y * t->a.x;
- }
-
-
- /*
- * copy n chars of a string
- */
-
- static strcpyn(s1, s2, n) /*##*/
- char *s1, *s2;
- int n;
- {
- while (*s1++ = *s2++) {
- if (--n == 0) {
- *--s1 = '\0';
- return;
- }
- }
- }
-