ING_DB
This commit is contained in:
parent
d86a2ba4c1
commit
9f95488636
|
|
@ -0,0 +1,52 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
** FGETLINE -- get line from file
|
||||||
|
**
|
||||||
|
** This routine reads a single newline-terminated line from
|
||||||
|
** a file.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** buf -- the buffer in which to place the result.
|
||||||
|
** maxch -- the maximum number of characters the
|
||||||
|
** buffer can hold.
|
||||||
|
** iop -- the file from which to read the characters.
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** 0 -- end-of-file or error.
|
||||||
|
** else -- 'buf'.
|
||||||
|
*/
|
||||||
|
char *fgetline(buf, maxch, iop)
|
||||||
|
char *buf;
|
||||||
|
int maxch;
|
||||||
|
register FILE *iop;
|
||||||
|
{
|
||||||
|
register char *p;
|
||||||
|
register int n;
|
||||||
|
register int c;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
for (n = maxch; n > 0; n--)
|
||||||
|
{
|
||||||
|
c = getc(iop);
|
||||||
|
|
||||||
|
/* test for end-of-file or error */
|
||||||
|
if (c == EOF)
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
return ((char *) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test for newline */
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* insert character into buffer */
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* null-terminate the string */
|
||||||
|
*p = 0;
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** AAsyserr -- SYStem ERRor message print and abort
|
||||||
|
**
|
||||||
|
** AAsyserr acts like a printf with up to five arguments.
|
||||||
|
**
|
||||||
|
** If the first argument to AAsyserr is not zero,
|
||||||
|
** the error messages are prepended.
|
||||||
|
**
|
||||||
|
** If the extern variable 'AAproc_name' is assigned to a
|
||||||
|
** string, that string is prepended to the message.
|
||||||
|
**
|
||||||
|
** All arguments must be null-terminated.
|
||||||
|
**
|
||||||
|
** The function pointed to by 'AAexitfn' is then called.
|
||||||
|
** It is initialized to be 'exit'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *AAproc_name;
|
||||||
|
int AAccerror;
|
||||||
|
extern exit();
|
||||||
|
int (*AAexitfn)() = exit;
|
||||||
|
|
||||||
|
# ifdef P8000
|
||||||
|
AAsyserr(err, p0, p1, p2, p3, p4, p5)
|
||||||
|
# else
|
||||||
|
AAsyserr(err, p0)
|
||||||
|
# endif
|
||||||
|
register int err;
|
||||||
|
char *p0;
|
||||||
|
# ifdef P8000
|
||||||
|
char *p1;
|
||||||
|
char *p2;
|
||||||
|
char *p3;
|
||||||
|
char *p4;
|
||||||
|
char *p5;
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
register int exitvalue;
|
||||||
|
char buf[256];
|
||||||
|
extern int errno;
|
||||||
|
extern char *AAgetformat();
|
||||||
|
# ifndef P8000
|
||||||
|
register char **p;
|
||||||
|
|
||||||
|
p = &p0;
|
||||||
|
# endif
|
||||||
|
exitvalue = -1;
|
||||||
|
|
||||||
|
putchar('\n');
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (AAproc_name)
|
||||||
|
printf("%s\n", AAproc_name);
|
||||||
|
printf("\007DB\terror\t%d\n", err);
|
||||||
|
if (errno)
|
||||||
|
printf("BS\terror\t%d\n", exitvalue = errno);
|
||||||
|
if (AAccerror)
|
||||||
|
printf("ACCESS\terror\t%d\n", AAccerror);
|
||||||
|
# ifdef P8000
|
||||||
|
printf(AAgetformat(err, buf), p0, p1, p2, p3, p4, p5);
|
||||||
|
# else
|
||||||
|
printf(AAgetformat(err, buf), p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# ifdef P8000
|
||||||
|
printf(p0, p1, p2, p3, p4, p5);
|
||||||
|
# else
|
||||||
|
printf(p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||||
|
# endif
|
||||||
|
printf("\007\n");
|
||||||
|
AAunlall();
|
||||||
|
fflush(stdout);
|
||||||
|
sync();
|
||||||
|
(*AAexitfn)(exitvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *AAgetformat(err, buf)
|
||||||
|
int err;
|
||||||
|
char *buf;
|
||||||
|
{
|
||||||
|
register int c;
|
||||||
|
register char *p;
|
||||||
|
register FILE *iop;
|
||||||
|
short i;
|
||||||
|
# ifdef SETBUF
|
||||||
|
char iobufx[BUFSIZ];
|
||||||
|
# endif
|
||||||
|
extern char *AAerrfn();
|
||||||
|
|
||||||
|
/* open the appropriate error file */
|
||||||
|
if (!(iop = fopen(AAerrfn(err / 1000), "r")))
|
||||||
|
return ("");
|
||||||
|
# ifdef SETBUF
|
||||||
|
setbuf(iop, iobufx);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* read in the code and check for correct */
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
p = buf;
|
||||||
|
while ((c = getc(iop)) != '\t')
|
||||||
|
{
|
||||||
|
if (c <= 0)
|
||||||
|
/* no code exists */
|
||||||
|
goto fmt_err;
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
if (AA_atoi(buf, &i))
|
||||||
|
goto fmt_err;
|
||||||
|
if (i != err)
|
||||||
|
{
|
||||||
|
while ((c = getc(iop)) != ERRDELIM)
|
||||||
|
if (c <= 0)
|
||||||
|
goto fmt_err;
|
||||||
|
getc(iop); /* throw out the newline */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* got the correct line */
|
||||||
|
p = buf;
|
||||||
|
while ((c = getc(iop)) != ERRDELIM)
|
||||||
|
{
|
||||||
|
if (c <= 0)
|
||||||
|
{
|
||||||
|
fmt_err:
|
||||||
|
fclose(iop);
|
||||||
|
return ("");
|
||||||
|
}
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
fclose(iop);
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GETNUSER -- get line from user file based on name
|
||||||
|
**
|
||||||
|
** Given a user name as a string, this routine returns the
|
||||||
|
** corresponding line from AA_USERS into a buffer.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** name -- the name of the user
|
||||||
|
** buf -- a buf to dump the line in (declare as
|
||||||
|
** char buf[MAXLINE + 1]
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** zero -- success
|
||||||
|
** one -- failure (user not present)
|
||||||
|
*/
|
||||||
|
getnuser(name, buf)
|
||||||
|
char *name;
|
||||||
|
char buf[];
|
||||||
|
{
|
||||||
|
register int c;
|
||||||
|
register char *bp;
|
||||||
|
register FILE *userf;
|
||||||
|
# ifdef SETBUF
|
||||||
|
char userbuf[BUFSIZ];
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (!(userf = fopen(AAztack(AApath, AA_USERS), "r")))
|
||||||
|
AAsyserr(15001);
|
||||||
|
# ifdef SETBUF
|
||||||
|
setbuf(userf, userbuf);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
bp = buf;
|
||||||
|
while ((c = getc(userf)) != '\n')
|
||||||
|
{
|
||||||
|
if (c == EOF)
|
||||||
|
{
|
||||||
|
fclose(userf);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
*bp++ = c;
|
||||||
|
}
|
||||||
|
*bp++ = '\0';
|
||||||
|
bp = buf;
|
||||||
|
while ((c = *bp++) != ':')
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
fclose(userf);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
*--bp = 0;
|
||||||
|
if (AAsequal(buf, name))
|
||||||
|
{
|
||||||
|
fclose(userf);
|
||||||
|
*bp = ':';
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,225 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "buf.h"
|
||||||
|
# include "gen.h"
|
||||||
|
|
||||||
|
static char *Buf_flat;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFFER MANIPULATION ROUTINES
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** BUFPUT -- put character onto buffer
|
||||||
|
**
|
||||||
|
** The character 'c' is put onto the buffer 'bp'. If the buffer
|
||||||
|
** need be extended it is.
|
||||||
|
*/
|
||||||
|
bufput(c, bp)
|
||||||
|
int c;
|
||||||
|
register struct buf **bp;
|
||||||
|
{
|
||||||
|
register struct buf *b;
|
||||||
|
register struct buf *a;
|
||||||
|
extern struct buf *bufalloc();
|
||||||
|
|
||||||
|
if (!(b = *bp) || b->ptr >= &b->buffer[BUFSIZE])
|
||||||
|
{
|
||||||
|
/* allocate new buffer segment */
|
||||||
|
a = bufalloc(sizeof (struct buf));
|
||||||
|
a->nextb = b;
|
||||||
|
a->ptr = a->buffer;
|
||||||
|
*bp = b = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
*b->ptr++ = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFGET -- get character off of buffer
|
||||||
|
**
|
||||||
|
** The buffer is popped and the character is returned. If the
|
||||||
|
** segment is then empty, it is returned to the free list.
|
||||||
|
*/
|
||||||
|
bufget(bp)
|
||||||
|
register struct buf **bp;
|
||||||
|
{
|
||||||
|
register struct buf *b;
|
||||||
|
register int c;
|
||||||
|
|
||||||
|
if (!(b = *bp) || b->ptr == b->buffer)
|
||||||
|
return (0); /* buffer is empty -- return end of file */
|
||||||
|
|
||||||
|
c = *--(b->ptr);
|
||||||
|
|
||||||
|
/* check to see if we have emptied the (non-initial) segment */
|
||||||
|
if (b->ptr == b->buffer && b->nextb)
|
||||||
|
{
|
||||||
|
/* deallocate segment */
|
||||||
|
*bp = b->nextb;
|
||||||
|
buffree(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFPURGE -- return an entire buffer to the free list
|
||||||
|
**
|
||||||
|
** The buffer is emptied and returned to the free list. This
|
||||||
|
** routine should be called when the buffer is to no longer
|
||||||
|
** be used.
|
||||||
|
*/
|
||||||
|
bufpurge(bp)
|
||||||
|
register struct buf **bp;
|
||||||
|
{
|
||||||
|
register struct buf *b;
|
||||||
|
register struct buf *a;
|
||||||
|
|
||||||
|
b = *bp;
|
||||||
|
*bp = (struct buf *) 0;
|
||||||
|
|
||||||
|
/* return the segments to the free list */
|
||||||
|
while (b)
|
||||||
|
{
|
||||||
|
a = b->nextb;
|
||||||
|
buffree(b);
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFFLUSH -- flush a buffer
|
||||||
|
**
|
||||||
|
** The named buffer is truncated to zero length. However, the
|
||||||
|
** segments of the buffer are not returned to the system.
|
||||||
|
*/
|
||||||
|
bufflush(bp)
|
||||||
|
register struct buf **bp;
|
||||||
|
{
|
||||||
|
register struct buf *b;
|
||||||
|
|
||||||
|
if (!(b = *bp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* return second and subsequent segments to the system */
|
||||||
|
bufpurge(&b->nextb);
|
||||||
|
|
||||||
|
/* truncate this buffer to zero length */
|
||||||
|
b->ptr = b->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFCRUNCH -- flatten a series of buffers to a string
|
||||||
|
**
|
||||||
|
** The named buffer is flattenned to a conventional C string,
|
||||||
|
** null terminated. The buffer is deallocated. The string is
|
||||||
|
** allocated "somewhere" off in memory, and a pointer to it
|
||||||
|
** is returned.
|
||||||
|
*/
|
||||||
|
char *bufcrunch(buffer)
|
||||||
|
register struct buf **buffer;
|
||||||
|
{
|
||||||
|
register char *p;
|
||||||
|
extern char *bufflatten();
|
||||||
|
|
||||||
|
p = bufflatten(*buffer, 1);
|
||||||
|
*p = 0;
|
||||||
|
*buffer = (struct buf *) 0;
|
||||||
|
return (Buf_flat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *bufflatten(b, length)
|
||||||
|
register struct buf *b;
|
||||||
|
int length;
|
||||||
|
{
|
||||||
|
register char *p;
|
||||||
|
register char *q;
|
||||||
|
extern char *bufflatten();
|
||||||
|
extern struct buf *bufalloc();
|
||||||
|
|
||||||
|
/* see if we have advanced to beginning of buffer */
|
||||||
|
if (!b) /* yes, allocate the string */
|
||||||
|
return (Buf_flat = (char *) bufalloc(length));
|
||||||
|
|
||||||
|
/* no, keep moving back */
|
||||||
|
p = (char *) bufflatten(b->nextb, length + (b->ptr - b->buffer));
|
||||||
|
|
||||||
|
/* copy buffer into string */
|
||||||
|
for (q = b->buffer; q < b->ptr; )
|
||||||
|
*p++ = *q++;
|
||||||
|
|
||||||
|
/* deallocate the segment */
|
||||||
|
buffree(b);
|
||||||
|
|
||||||
|
/* process next segment */
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFALLOC -- allocate clear memory
|
||||||
|
**
|
||||||
|
** This is similar to the system alloc routine except that
|
||||||
|
** it has no error return, and memory is guaranteed to be clear
|
||||||
|
** when you return.
|
||||||
|
**
|
||||||
|
** It might be nice to rewrite this later to avoid the nasty
|
||||||
|
** memory fragmentation that alloc() tends toward.
|
||||||
|
**
|
||||||
|
** The error processing might have to be modified if used anywhere
|
||||||
|
** other than DBS.
|
||||||
|
*/
|
||||||
|
struct buf *bufalloc(size)
|
||||||
|
register int size;
|
||||||
|
{
|
||||||
|
register struct buf *p;
|
||||||
|
extern int (*AAexitfn)(); /* defined in AAsyserr.c */
|
||||||
|
extern char *malloc();
|
||||||
|
|
||||||
|
if (!(p = (struct buf *) malloc(size)))
|
||||||
|
{
|
||||||
|
printf("%sMACRO processor: Speicherueberlauf\n", ERROR);
|
||||||
|
fflush(stdout);
|
||||||
|
(*AAexitfn)(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufclear(p, size);
|
||||||
|
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFCLEAR -- clear a block of core memory
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** buf -- pointer to area
|
||||||
|
** size -- size in bytes
|
||||||
|
*/
|
||||||
|
bufclear(buf, size)
|
||||||
|
register char *buf;
|
||||||
|
register int size;
|
||||||
|
{
|
||||||
|
register char *b;
|
||||||
|
|
||||||
|
for (b = &buf[size]; buf < b; )
|
||||||
|
*buf++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** BUFFREE -- free memory
|
||||||
|
*/
|
||||||
|
buffree(ptr)
|
||||||
|
register char *ptr;
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
AAsyserr(16000);
|
||||||
|
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/bs.h"
|
||||||
|
# include "monitor.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CALL TEXT EDITOR
|
||||||
|
**
|
||||||
|
** The BS text editor is called. The actual call is to
|
||||||
|
** the macro EDITOR. If that fails, /bin/ed is called.
|
||||||
|
** This routine suppressed the autoclear function.
|
||||||
|
*/
|
||||||
|
edit()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register char *p;
|
||||||
|
register char *editfile;
|
||||||
|
extern int exit();
|
||||||
|
extern int (*AAexitfn)();
|
||||||
|
extern char *getfilename();
|
||||||
|
extern char *macro();
|
||||||
|
|
||||||
|
editfile = getfilename();
|
||||||
|
if (!*editfile)
|
||||||
|
editfile = Qbname;
|
||||||
|
|
||||||
|
Autoclear = 0;
|
||||||
|
fclose(Qryiop);
|
||||||
|
|
||||||
|
/* FORK PROCESS & INVOKE THE EDITOR */
|
||||||
|
fflush(stdout);
|
||||||
|
if ((Xwaitpid = fork()) < 0)
|
||||||
|
{
|
||||||
|
printf("CANNOT FORK\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Xwaitpid)
|
||||||
|
{
|
||||||
|
AAexitfn = exit;
|
||||||
|
setuid(getuid());
|
||||||
|
setgid(getgid());
|
||||||
|
for (i = 3; i < MAXFILES; i++)
|
||||||
|
close(i);
|
||||||
|
# ifdef MACRO
|
||||||
|
if (!(p = macro(EDITOR)))
|
||||||
|
# endif
|
||||||
|
p = BIN_ED;
|
||||||
|
if (Nodayfile >= 0)
|
||||||
|
printf(">>%s\n", p);
|
||||||
|
fflush(stdout);
|
||||||
|
execlp(p, p, editfile, (char *) 0);
|
||||||
|
if (Nodayfile >= 0)
|
||||||
|
{
|
||||||
|
printf("CANNOT EXEC\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WAIT FOR PROCESS TO DIE */
|
||||||
|
xwait();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/pipes.h"
|
||||||
|
# include "monitor.h"
|
||||||
|
|
||||||
|
/* list of fatal signals */
|
||||||
|
static char *Siglist[] =
|
||||||
|
{
|
||||||
|
"Signal 0",
|
||||||
|
"hangup",
|
||||||
|
"interrupt",
|
||||||
|
"quit",
|
||||||
|
"illegal instruction",
|
||||||
|
"trace trap",
|
||||||
|
"IOT instruction",
|
||||||
|
"EMT instruction",
|
||||||
|
"floating point exception",
|
||||||
|
"kill",
|
||||||
|
"bus error",
|
||||||
|
"segmentation violation",
|
||||||
|
"bad argument to system call",
|
||||||
|
"write on broken pipe or link with no one to read it",
|
||||||
|
"alarm clock",
|
||||||
|
"software termination signal"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** QUIT DBS
|
||||||
|
**
|
||||||
|
** This routine starts the death of the other processes. It
|
||||||
|
** then prints out the logout message, and then waits for the
|
||||||
|
** rest of the system to die. Note, however, that no relations
|
||||||
|
** are removed; this must be done using the PURGE command.
|
||||||
|
*/
|
||||||
|
quit()
|
||||||
|
{
|
||||||
|
register int ndx;
|
||||||
|
register int pidptr;
|
||||||
|
register int err;
|
||||||
|
int status;
|
||||||
|
int pidlist[50];
|
||||||
|
char buf[100];
|
||||||
|
char indexx[0400];
|
||||||
|
extern int (*AAexitfn)();
|
||||||
|
extern exit();
|
||||||
|
extern int sys_nerr;
|
||||||
|
extern char *sys_errlist[];
|
||||||
|
extern char *AAcustomer();
|
||||||
|
extern long time();
|
||||||
|
extern char *ctime();
|
||||||
|
|
||||||
|
# ifdef xMTR1
|
||||||
|
AAtTfp(1, -1, "entered QUIT\n");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* INTERCEPT ALL FURTHER INTERRUPTS */
|
||||||
|
signal(1, (int (*)()) 1);
|
||||||
|
signal(2, (int (*)()) 1);
|
||||||
|
signal(3, (int (*)()) 1);
|
||||||
|
AAexitfn = exit;
|
||||||
|
|
||||||
|
close(W_down);
|
||||||
|
|
||||||
|
# ifdef xMTR3
|
||||||
|
AAtTfp(1, 2, "unlinking %s\n", Qbname);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* REMOVE THE QUERY-BUFFER FILE */
|
||||||
|
fclose(Qryiop);
|
||||||
|
unlink(Qbname);
|
||||||
|
# ifdef MACRO
|
||||||
|
if (Trapfile)
|
||||||
|
fclose(Trapfile);
|
||||||
|
# endif
|
||||||
|
pidptr = 0;
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
/* clear out the system error index table */
|
||||||
|
for (ndx = 0; ndx < 0400; ndx++)
|
||||||
|
indexx[ndx] = 0;
|
||||||
|
|
||||||
|
/* wait for all process to terminate */
|
||||||
|
while ((ndx = wait(&status)) != -1)
|
||||||
|
{
|
||||||
|
# ifdef xMTR2
|
||||||
|
AAtTfp(1, 5, "QUIT: pid %u: 0%o/0%o\n", ndx, status >> 8, status & 0177);
|
||||||
|
# endif
|
||||||
|
pidlist[pidptr++] = ndx;
|
||||||
|
if (status & 0177)
|
||||||
|
{
|
||||||
|
printf("%u: ", ndx);
|
||||||
|
ndx = status & 0177;
|
||||||
|
if (ndx > sizeof Siglist / sizeof Siglist[0])
|
||||||
|
printf("Abnormal Termination %u", ndx);
|
||||||
|
else
|
||||||
|
printf("%s", Siglist[ndx]);
|
||||||
|
if (status & 0200)
|
||||||
|
printf(" -- Core Dumped");
|
||||||
|
putchar('\n');
|
||||||
|
err++;
|
||||||
|
indexx[0377 - ndx]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
indexx[(status >> 8) & 0377]++;
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
printf("pid list:");
|
||||||
|
for (ndx = 0; ndx < pidptr; ndx++)
|
||||||
|
printf(" %u", pidlist[ndx]);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print index of system errors */
|
||||||
|
err = 0;
|
||||||
|
for (ndx = 1; ndx <= 0377; ndx++)
|
||||||
|
{
|
||||||
|
if (!indexx[ndx])
|
||||||
|
continue;
|
||||||
|
if (ndx <= sys_nerr)
|
||||||
|
{
|
||||||
|
if (!err)
|
||||||
|
printf("\nBS error dictionary:\n");
|
||||||
|
printf("%3d: %s\n", ndx, sys_errlist[ndx]);
|
||||||
|
}
|
||||||
|
if (!err)
|
||||||
|
err = ndx;
|
||||||
|
}
|
||||||
|
if (err > 0 && err <= sys_nerr)
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
/* PRINT LOG CUE ? */
|
||||||
|
if (Nodayfile >= 0)
|
||||||
|
{
|
||||||
|
printf(LOG_1, AAversion);
|
||||||
|
time(buf);
|
||||||
|
# ifdef ESER_VMX
|
||||||
|
printf("%s\n%s", AAcustomer(), ctime(*((long *) buf)));
|
||||||
|
# else
|
||||||
|
printf("%s\n%s", AAcustomer(), ctime(buf));
|
||||||
|
# endif
|
||||||
|
if (!getuser(AAusercode, buf))
|
||||||
|
{
|
||||||
|
for (ndx = 0; buf[ndx]; ndx++)
|
||||||
|
if (buf[ndx] == ':')
|
||||||
|
break;
|
||||||
|
buf[ndx] = 0;
|
||||||
|
printf(LOG_21, buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf(LOG_22);
|
||||||
|
printf(LOG_3);
|
||||||
|
}
|
||||||
|
# ifdef xMTR1
|
||||||
|
AAtTfp(1, 3, "QUIT: exit(%d)\n", err);
|
||||||
|
# endif
|
||||||
|
AAunlall();
|
||||||
|
fflush(stdout);
|
||||||
|
exit(err);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/bs.h"
|
||||||
|
# include "monitor.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CALL BS SHELL
|
||||||
|
**
|
||||||
|
** The BS shell is called. Shell() first tries to call an
|
||||||
|
** alternate shell defined by the macro SHELL, and if it fails
|
||||||
|
** calls BIN_SH.
|
||||||
|
**
|
||||||
|
** If an argument is supplied, it is a shell file which is
|
||||||
|
** supplied to the shell.
|
||||||
|
*/
|
||||||
|
shell()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register char *shellfile;
|
||||||
|
register char *sh_arg;
|
||||||
|
extern int exit();
|
||||||
|
extern int (*AAexitfn)();
|
||||||
|
extern char *macro();
|
||||||
|
extern char *getfilename();
|
||||||
|
|
||||||
|
sh_arg = "-c";
|
||||||
|
shellfile = getfilename();
|
||||||
|
if (!*shellfile)
|
||||||
|
{
|
||||||
|
# ifdef MACRO
|
||||||
|
if (!(shellfile = macro(SHELL)))
|
||||||
|
# endif
|
||||||
|
sh_arg = "-i";
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(Qryiop);
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
if ((Xwaitpid = fork()) == -1)
|
||||||
|
{
|
||||||
|
printf("CANNOT FORK\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Xwaitpid)
|
||||||
|
{
|
||||||
|
AAexitfn = exit;
|
||||||
|
setuid(getuid());
|
||||||
|
setgid(getgid());
|
||||||
|
for (i = 3; i < MAXFILES; i++)
|
||||||
|
close(i);
|
||||||
|
if (Nodayfile >= 0)
|
||||||
|
printf(">>%s\n", shellfile? shellfile: BIN_SH);
|
||||||
|
fflush(stdout);
|
||||||
|
execlp(BIN_SH, BIN_SH, sh_arg, shellfile, (char *) 0);
|
||||||
|
if (Nodayfile >= 0)
|
||||||
|
{
|
||||||
|
printf("CANNOT EXEC\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait for shell to complete */
|
||||||
|
xwait();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "monitor.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WRITE OUT QUERY BUFFER TO BS FILE
|
||||||
|
**
|
||||||
|
** The logical buffer is written to a BS file, the name of which
|
||||||
|
** must follow the \w command.
|
||||||
|
*/
|
||||||
|
writeout()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register char *file;
|
||||||
|
register int source;
|
||||||
|
register int dest;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
extern char *getfilename();
|
||||||
|
|
||||||
|
file = getfilename();
|
||||||
|
if (!*file || *file == '-')
|
||||||
|
{
|
||||||
|
printf("%sUnakzeptabler file name `%s'\n", ERROR, file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dest = creat(file, 0644)) < 0)
|
||||||
|
{
|
||||||
|
printf("%screate WRITE file `%s'\n", ERROR, file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Nautoclear)
|
||||||
|
Autoclear = 1;
|
||||||
|
|
||||||
|
if ((source = open(Qbname, 0)) < 0)
|
||||||
|
AAsyserr(16025, Qbname);
|
||||||
|
|
||||||
|
fflush(Qryiop);
|
||||||
|
|
||||||
|
while ((i = read(source, buf, sizeof buf)) > 0)
|
||||||
|
write(dest, buf, i);
|
||||||
|
|
||||||
|
close(source);
|
||||||
|
close(dest);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/access.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** SYSTEM RELATION DESCRIPTOR CACHE DEFINITION
|
||||||
|
**
|
||||||
|
** *** TOOLED FOR QUERY MODIFICATION PROCESS ***
|
||||||
|
*/
|
||||||
|
|
||||||
|
DESC Reldes;
|
||||||
|
DESC Prodes;
|
||||||
|
DESC Intdes;
|
||||||
|
DESC Treedes;
|
||||||
|
|
||||||
|
struct desxx Desxx[] =
|
||||||
|
{
|
||||||
|
AA_REL, &Reldes, &AAdmin.adreld,
|
||||||
|
AA_PROTECT, &Prodes, (DESC *) 0,
|
||||||
|
AA_INTEG, &Intdes, (DESC *) 0,
|
||||||
|
AA_TREE, &Treedes, (DESC *) 0,
|
||||||
|
(char *) 0
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/pipes.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "../h/symbol.h"
|
||||||
|
# include "../h/catalog.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
extern QTREE *Treeroot;
|
||||||
|
extern DESC Reldes;
|
||||||
|
extern struct pipfrmt Pipe;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** D_VIEW -- define view
|
||||||
|
**
|
||||||
|
** This procedure connects the tree in with the AA_REL catalog
|
||||||
|
** and inserts the view tree into the AA_TREE catalog.
|
||||||
|
**
|
||||||
|
** The information in the pipe is expected to come as follows:
|
||||||
|
** create for view, with S_VIEW bit set so that a
|
||||||
|
** physical relation is not created.
|
||||||
|
** define tree, which will put the translation tree
|
||||||
|
** into the AA_TREE catalog.
|
||||||
|
** define view, which will connect the two together.
|
||||||
|
** The first two absolutely must be done before
|
||||||
|
** this step can be called.
|
||||||
|
*/
|
||||||
|
d_view()
|
||||||
|
{
|
||||||
|
char viewid[MAXNAME + 1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Read parameters.
|
||||||
|
** Only parameter is view name (which must match the
|
||||||
|
** name of the Resultvar).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (rdpipe(P_NORM, &Pipe, R_up, viewid, 0) > MAXNAME + 1)
|
||||||
|
AAsyserr(19019);
|
||||||
|
AApad(viewid, MAXNAME);
|
||||||
|
|
||||||
|
/* done with pipe... */
|
||||||
|
rdpipe(P_SYNC, &Pipe, R_up);
|
||||||
|
|
||||||
|
# ifdef xQTR3
|
||||||
|
/* do some extra validation */
|
||||||
|
if (!Treeroot)
|
||||||
|
AAsyserr(19020);
|
||||||
|
if (Qmode != mdDEFINE)
|
||||||
|
AAsyserr(19021, Qmode);
|
||||||
|
if (Resultvar < 0)
|
||||||
|
AAsyserr(19022, Resultvar);
|
||||||
|
if (!Rangev[Resultvar].rused || !AAbequal(Rangev[Resultvar].relid, viewid, MAXNAME))
|
||||||
|
AAsyserr(19023, Rangev[Resultvar].rused, Rangev[Resultvar].relid);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
Rangev[Resultvar].rused = FALSE;
|
||||||
|
Resultvar = -1;
|
||||||
|
Qmode = -1;
|
||||||
|
|
||||||
|
/* output tree to AA_TREE catalog */
|
||||||
|
puttree(Treeroot, viewid, AAusercode, mdVIEW);
|
||||||
|
|
||||||
|
/* clear Treeroot to detect some errors */
|
||||||
|
Treeroot = (QTREE *) 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/bs.h"
|
||||||
|
# include "../h/catalog.h"
|
||||||
|
# include "../h/pipes.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
extern struct pipfrmt Pipe;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** FILLPROTUP -- fill the protection tuple from pipe.
|
||||||
|
**
|
||||||
|
** This routine is broken off from d_prot.c so that we
|
||||||
|
** don't get symbol table overflows.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** protup -- pointer to the protection tuple to fill.
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** A bool telling whether we have PERMIT ALL TO ALL
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** Side Effects:
|
||||||
|
** The R_up pipe is flushed.
|
||||||
|
*/
|
||||||
|
fillprotup(protup)
|
||||||
|
struct protect *protup;
|
||||||
|
{
|
||||||
|
register struct protect *pt;
|
||||||
|
register int i;
|
||||||
|
register char *p;
|
||||||
|
char buf[30];
|
||||||
|
int all_pro;
|
||||||
|
short ix;
|
||||||
|
char ubuf[MAXLINE + 1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Fill in the protection tuple with the information
|
||||||
|
** from the parser, validating as we go.
|
||||||
|
**
|
||||||
|
** Also, determine if we have a PERMIT xx to ALL
|
||||||
|
** with no further qualification case. The variable
|
||||||
|
** 'all_pro' is set to reflect this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
all_pro = TRUE;
|
||||||
|
pt = protup;
|
||||||
|
|
||||||
|
/* read operation set */
|
||||||
|
if (rdpipe(P_NORM, &Pipe, R_up, buf, 0) <= 0)
|
||||||
|
AAsyserr(19030);
|
||||||
|
if (AA_atoi(buf, &ix))
|
||||||
|
AAsyserr(19031, buf);
|
||||||
|
pt->proopset = ix;
|
||||||
|
if ((ctoi(pt->proopset) & PRO_RETR) != 0)
|
||||||
|
pt->proopset |= PRO_TEST | PRO_AGGR;
|
||||||
|
|
||||||
|
/* read relation name */
|
||||||
|
if (rdpipe(P_NORM, &Pipe, R_up, buf, 0) > MAXNAME + 1)
|
||||||
|
AAsyserr(19032);
|
||||||
|
AApmove(buf, pt->prorelid, MAXNAME, ' ');
|
||||||
|
|
||||||
|
/* read relation owner */
|
||||||
|
if (rdpipe(P_NORM, &Pipe, R_up, buf, 0) != 3)
|
||||||
|
AAsyserr(19033);
|
||||||
|
AAbmove(buf, pt->prorelown, 2);
|
||||||
|
|
||||||
|
/* read user name */
|
||||||
|
rdpipe(P_NORM, &Pipe, R_up, buf, 0);
|
||||||
|
if (AAsequal(buf, "all"))
|
||||||
|
AAbmove(" ", pt->prouser, 2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* look up user in AA_USERS */
|
||||||
|
if (getnuser(buf, ubuf))
|
||||||
|
far_error(3591, -1, Resultvar, buf, (char *) 0);
|
||||||
|
for (p = ubuf; *p != ':' && *p != 0; p++)
|
||||||
|
continue;
|
||||||
|
AAbmove(++p, pt->prouser, 2);
|
||||||
|
if (p[0] == ':' || p[1] == ':' || p[2] != ':')
|
||||||
|
AAsyserr(19034, ubuf);
|
||||||
|
all_pro = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read terminal id */
|
||||||
|
rdpipe(P_NORM, &Pipe, R_up, buf, 0);
|
||||||
|
if (AAsequal(buf, "all"))
|
||||||
|
{
|
||||||
|
AAbmove(" ", pt->proterm, PROTERM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (AAbequal(buf, "tty", 3))
|
||||||
|
AApmove(&buf[3], pt->proterm, PROTERM, ' ');
|
||||||
|
else
|
||||||
|
AApmove(buf, pt->proterm, PROTERM, ' ');
|
||||||
|
all_pro = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read starting time of day */
|
||||||
|
rdpipe(P_NORM, &Pipe, R_up, buf, 0);
|
||||||
|
if (AA_atoi(buf, &ix))
|
||||||
|
AAsyserr(19035, buf);
|
||||||
|
pt->protodbgn = ix;
|
||||||
|
if (ix > 0)
|
||||||
|
all_pro = FALSE;
|
||||||
|
|
||||||
|
/* read ending time of day */
|
||||||
|
rdpipe(P_NORM, &Pipe, R_up, buf, 0);
|
||||||
|
if (AA_atoi(buf, &ix))
|
||||||
|
AAsyserr(19036, buf);
|
||||||
|
pt->protodend = ix;
|
||||||
|
if (ix < 24 * 60 - 1)
|
||||||
|
all_pro = FALSE;
|
||||||
|
|
||||||
|
/* read beginning day of week */
|
||||||
|
rdpipe(P_NORM, &Pipe, R_up, buf, 0);
|
||||||
|
i = cvt_dow(buf);
|
||||||
|
if (i < 0)
|
||||||
|
far_error(3594, -1, Resultvar, buf, (char *) 0); /* bad dow */
|
||||||
|
pt->prodowbgn = i;
|
||||||
|
if (i > 0)
|
||||||
|
all_pro = FALSE;
|
||||||
|
|
||||||
|
/* read ending day of week */
|
||||||
|
rdpipe(P_NORM, &Pipe, R_up, buf, 0);
|
||||||
|
i = cvt_dow(buf);
|
||||||
|
if (i < 0)
|
||||||
|
far_error(3594, -1, Resultvar, buf, (char *) 0); /* bad dow */
|
||||||
|
pt->prodowend = i;
|
||||||
|
if (i < 6)
|
||||||
|
all_pro = FALSE;
|
||||||
|
|
||||||
|
/* finished with pipe... */
|
||||||
|
rdpipe(P_SYNC, &Pipe, R_up);
|
||||||
|
|
||||||
|
return (all_pro);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** QRYMOD -- main driver for query modification
|
||||||
|
**
|
||||||
|
** Reads in the query tree, performs the modifications, writes
|
||||||
|
** it out, and does process syncronization with below. The
|
||||||
|
** calling routine must sync with the process above.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** root1 -- a pointer to the tree to modify.
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** A pointer to the modified tree.
|
||||||
|
*/
|
||||||
|
QTREE *qrymod(root1)
|
||||||
|
QTREE *root1;
|
||||||
|
{
|
||||||
|
register QTREE *root;
|
||||||
|
extern QTREE *view();
|
||||||
|
extern QTREE *integrity();
|
||||||
|
extern QTREE *protect();
|
||||||
|
|
||||||
|
root = root1;
|
||||||
|
|
||||||
|
# ifdef xQTR1
|
||||||
|
if (AAtTf(1, 0))
|
||||||
|
treepr(root, "->QRYMOD");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* view processing */
|
||||||
|
root = view(root);
|
||||||
|
|
||||||
|
/* integrity processing */
|
||||||
|
root = integrity(root);
|
||||||
|
|
||||||
|
/* protection processing */
|
||||||
|
root = protect(root);
|
||||||
|
|
||||||
|
return (root);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/symbol.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RANGE.C -- range table manipulation
|
||||||
|
**
|
||||||
|
** Defines:
|
||||||
|
** declare -- declare variable
|
||||||
|
** clrrange -- clear range table
|
||||||
|
** mapvars -- map varno's in a tree to unique numbers
|
||||||
|
** Remap[] -- a mapping from specified (preferred) varno's
|
||||||
|
** to actual varno's. -1 indicates no mapping.
|
||||||
|
** Presumably this cannot be set when reading an
|
||||||
|
** original query tree, but can happen easily when
|
||||||
|
** reading a tree from AA_TREE catalog.
|
||||||
|
** Rangev[] -- the range table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Remap[MAXVAR + 1];
|
||||||
|
struct rngtab Rangev[MAXVAR + 1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CLRRANGE -- clear range table(s)
|
||||||
|
**
|
||||||
|
** The range table (Rangev) and range table map (Remap) are
|
||||||
|
** initialized in one of two ways.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** prim -- if TRUE, the primary range table (Rangev)
|
||||||
|
** is cleared and Remap is set to be FULL (for
|
||||||
|
** reading in an initial query). If FALSE,
|
||||||
|
** Rangev is untouched, but Remap is cleared.
|
||||||
|
**
|
||||||
|
** Side Effects:
|
||||||
|
** Rangev[i].rused set to FALSE for all entries.
|
||||||
|
** Remap[i] set to -1 or MAXVAR + 1 for all entries.
|
||||||
|
*/
|
||||||
|
clrrange(prim)
|
||||||
|
register int prim;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXVAR + 1; i++)
|
||||||
|
{
|
||||||
|
if (prim)
|
||||||
|
{
|
||||||
|
Rangev[i].rused = FALSE;
|
||||||
|
Remap[i] = MAXVAR + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Remap[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** DECLARE -- declare a range variable
|
||||||
|
**
|
||||||
|
** A range variable is declared. If possible, the preferred varno
|
||||||
|
** stated is used (this is the one already in the tree). This
|
||||||
|
** should always be possible when reading the original tree (and
|
||||||
|
** should probably stay this way to make debugging easier). When
|
||||||
|
** not possible, a new varno is chosen, and Remap[oldvarno] is
|
||||||
|
** set to newvarno, so that the tree can later be patched up by
|
||||||
|
** 'mapvars' (below).
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** varno -- the preferred varno.
|
||||||
|
** name -- the relation name.
|
||||||
|
** stat -- the 'relstat' of this relation.
|
||||||
|
**
|
||||||
|
** Side Effects:
|
||||||
|
** Rangev and possible Remap are updated. No Rangev
|
||||||
|
** entry is ever touched if the 'rused' field
|
||||||
|
** is set.
|
||||||
|
*/
|
||||||
|
declare(varno, name, owner, stat)
|
||||||
|
int varno;
|
||||||
|
char *name;
|
||||||
|
char owner[2];
|
||||||
|
int stat;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register int vn;
|
||||||
|
register int s;
|
||||||
|
|
||||||
|
vn = varno;
|
||||||
|
s = stat;
|
||||||
|
|
||||||
|
/* check for preferred slot in range table available */
|
||||||
|
if (Rangev[vn].rused)
|
||||||
|
{
|
||||||
|
/* used: check if really redeclared */
|
||||||
|
if (Remap[vn] >= 0)
|
||||||
|
AAsyserr(19047, vn);
|
||||||
|
|
||||||
|
/* try to find another slot */
|
||||||
|
for (i = 0; i < MAXVAR + 1; i++)
|
||||||
|
if (!Rangev[i].rused)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i >= MAXVAR + 1)
|
||||||
|
{
|
||||||
|
far_error(3100, Qmode, -1, name, (char *) 0); /* too many variables */
|
||||||
|
}
|
||||||
|
|
||||||
|
Remap[vn] = i;
|
||||||
|
vn = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* declare variable in the guaranteed empty slot */
|
||||||
|
AAbmove(name, Rangev[vn].relid, MAXNAME);
|
||||||
|
AAbmove(owner, Rangev[vn].rowner, 2);
|
||||||
|
Rangev[vn].rstat = s;
|
||||||
|
Rangev[vn].rused = TRUE;
|
||||||
|
|
||||||
|
# ifdef xQTR2
|
||||||
|
AAtTfp(11, 0, "DECLARE: %d, %.12s, %.2s, 0%o into slot %d\n",
|
||||||
|
varno, name, owner, s, vn);
|
||||||
|
# endif
|
||||||
|
# ifdef xQTR3
|
||||||
|
AAtTfp(11, 1, "DECLARE: %.12s%.2s 0%o %d\n", Rangev[vn].relid,
|
||||||
|
Rangev[vn].rowner, Rangev[vn].rstat, Rangev[vn].rused);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** MAPVARS -- remap varno's to be unique in AA_TREE tree
|
||||||
|
**
|
||||||
|
** A tree is scanned for VAR nodes; when found, the
|
||||||
|
** mapping defined in Remap[] is applied. This is done so that
|
||||||
|
** varno's as defined in trees in the AA_TREE catalog will be
|
||||||
|
** unique with respect to varno's in the user's query tree. For
|
||||||
|
** example, if the view definition uses variable 1 and the user's
|
||||||
|
** query also uses variable 1, the routine 'declare' will (when
|
||||||
|
** called to define the view definition varno 1) allocate a new
|
||||||
|
** varno (e.g. 3) in a free slot in the range table, and put
|
||||||
|
** the index of the new slot into the corresponding word of Remap;
|
||||||
|
** in this example, Remap[1] == 3. This routine does the actual
|
||||||
|
** mapping in the tree.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** tree -- pointer to tree to be remapped.
|
||||||
|
**
|
||||||
|
** Side Effects:
|
||||||
|
** the tree pointed to by 'tree' is modified according
|
||||||
|
** to Remap[].
|
||||||
|
*/
|
||||||
|
mapvars(tree)
|
||||||
|
QTREE *tree;
|
||||||
|
{
|
||||||
|
register QTREE *t;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
t = tree;
|
||||||
|
# ifdef xQTR3
|
||||||
|
if (AAtTf(12, 0) && t != NULL && t->sym.type == ROOT)
|
||||||
|
{
|
||||||
|
treepr(t, "mapvars:");
|
||||||
|
for (i = 0; i < MAXVAR + 1; i++)
|
||||||
|
if (Rangev[i].rused && Remap[i] >= 0)
|
||||||
|
printf("\t%d => %d\n", i, Remap[i]);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
while (t != NULL)
|
||||||
|
{
|
||||||
|
/* map right subtree */
|
||||||
|
mapvars(t->right);
|
||||||
|
|
||||||
|
/* check this node */
|
||||||
|
if (t->sym.type == VAR)
|
||||||
|
{
|
||||||
|
i = ((VAR_NODE *) t)->varno;
|
||||||
|
if ((i = Remap[i]) >= 0)
|
||||||
|
((VAR_NODE *) t)->varno = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* map left subtree (iteratively) */
|
||||||
|
t = t->left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,329 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/catalog.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "../h/symbol.h"
|
||||||
|
# include "../h/pipes.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** READTREE.C -- query tree input procedures
|
||||||
|
**
|
||||||
|
** This file contains routines to read trees from pipes and
|
||||||
|
** catalogs.
|
||||||
|
**
|
||||||
|
** Defines:
|
||||||
|
** readqry
|
||||||
|
** readsymbol
|
||||||
|
** readtree
|
||||||
|
** pipetrrd
|
||||||
|
** relntrrd
|
||||||
|
** gettree
|
||||||
|
** Qmode
|
||||||
|
** Resultvar
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern struct pipfrmt Pipe;
|
||||||
|
extern struct pipfrmt Outpipe;
|
||||||
|
|
||||||
|
int Qmode; /* Query mode */
|
||||||
|
int Resultvar; /* Result variable number */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** READQRY
|
||||||
|
**
|
||||||
|
** Reads in query symbols from input pipe into core
|
||||||
|
** locations and sets up information needed for later
|
||||||
|
** processing.
|
||||||
|
**
|
||||||
|
** Returns ptr to root of querytree
|
||||||
|
**
|
||||||
|
** Locbuf is a 'struct srcid' since that is the largest node of
|
||||||
|
** a QMODE, SOURCEID, or RESULTVAR node.
|
||||||
|
*/
|
||||||
|
QTREE *readqry(rdfn, initialize)
|
||||||
|
int (*rdfn)(); /* tree read function */
|
||||||
|
int initialize; /* if set, initialize Qbuf */
|
||||||
|
{
|
||||||
|
register SYMBOL *s;
|
||||||
|
SRCID locbuf;
|
||||||
|
register QTREE *rtval;
|
||||||
|
register char *p;
|
||||||
|
extern xerror();
|
||||||
|
extern char *readtree();
|
||||||
|
extern QTREE *trbuild();
|
||||||
|
|
||||||
|
# ifdef xQTR1
|
||||||
|
AAtTfp(70, 0, "READQRY:\n");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (initialize)
|
||||||
|
{
|
||||||
|
/* initialize for new query block */
|
||||||
|
initbuf(Qbuf, QBUFSIZ, QBUFFULL, xerror);
|
||||||
|
clrrange(TRUE);
|
||||||
|
Resultvar = -1;
|
||||||
|
Qmode = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
clrrange(FALSE);
|
||||||
|
|
||||||
|
s = (SYMBOL *) &locbuf;
|
||||||
|
|
||||||
|
/* read symbols from input */
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
readsymbol(s, rdfn);
|
||||||
|
# ifdef xQTR1
|
||||||
|
if (AAtTfp(70, 1, "%d, %d, %d/",
|
||||||
|
s->type, s->len, ctou(s->value[0])))
|
||||||
|
{
|
||||||
|
if (s->type == SOURCEID)
|
||||||
|
printf("%.12s", ((SRCID *) s)->srcname);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
switch (s->type)
|
||||||
|
{
|
||||||
|
case QMODE:
|
||||||
|
if (Qmode != -1)
|
||||||
|
AAsyserr(19048);
|
||||||
|
Qmode = s->value[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESULTVAR:
|
||||||
|
if (Resultvar != -1)
|
||||||
|
AAsyserr(19049);
|
||||||
|
Resultvar = s->value[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOURCEID:
|
||||||
|
declare(((SRCID *) s)->srcvar, ((SRCID *) s)->srcname, ((SRCID *) s)->srcown, ((SRCID *) s)->srcstat);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TREE: /* beginning of tree, no more other stuff */
|
||||||
|
p = readtree(s, rdfn);
|
||||||
|
rtval = trbuild(p);
|
||||||
|
if (!rtval)
|
||||||
|
far_error(STACKFULL, -1, -1, (char *) 0);
|
||||||
|
return (rtval);
|
||||||
|
|
||||||
|
default:
|
||||||
|
AAsyserr(19050, s->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** READSYMBOL
|
||||||
|
** reads in one symbol from pipe into symbol struct.
|
||||||
|
*/
|
||||||
|
readsymbol(dest, rdfn)
|
||||||
|
char *dest; /* if non-zero, pts to allocated space */
|
||||||
|
int (*rdfn)(); /* tree read function */
|
||||||
|
{
|
||||||
|
register int len;
|
||||||
|
register SYMBOL *p;
|
||||||
|
extern char *need();
|
||||||
|
|
||||||
|
/* check if enough space for type and len of sym */
|
||||||
|
p = (SYMBOL *) (dest? dest: need(Qbuf, SYM_HDR_SIZ));
|
||||||
|
if ((*rdfn)(p, TYP_LEN_SIZ) < TYP_LEN_SIZ)
|
||||||
|
goto err3;
|
||||||
|
len = ctou(p->len);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
if (!dest)
|
||||||
|
{
|
||||||
|
/* this will be contiguous with above need call */
|
||||||
|
need(Qbuf, len);
|
||||||
|
}
|
||||||
|
if ((*rdfn)(p->value, len) < len)
|
||||||
|
goto err3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
err3:
|
||||||
|
AAsyserr(19051);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** READTREE
|
||||||
|
** reads in tree symbols into a buffer up to a root (end) symbol
|
||||||
|
*/
|
||||||
|
char *readtree(tresym, rdfn)
|
||||||
|
SYMBOL *tresym;
|
||||||
|
int (*rdfn)();
|
||||||
|
{
|
||||||
|
register QTREE *nod;
|
||||||
|
register char *rtval;
|
||||||
|
extern char *need();
|
||||||
|
|
||||||
|
rtval = need(Qbuf, QT_HDR_SIZ);
|
||||||
|
AAbmove(tresym, &(((QTREE *) rtval)->sym), TYP_LEN_SIZ); /* insert type and len of TREE node */
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
/* space for left & right pointers */
|
||||||
|
nod = (QTREE *) need(Qbuf, QT_PTR_SIZ);
|
||||||
|
readsymbol((char *) 0, rdfn);
|
||||||
|
# ifdef xQTR1
|
||||||
|
if (AAtTf(70, 2))
|
||||||
|
nodepr(nod, TRUE);
|
||||||
|
# endif
|
||||||
|
if (nod->sym.type == ROOT)
|
||||||
|
return (rtval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** PIPETRRD -- read tree from R_up pipe
|
||||||
|
**
|
||||||
|
** This routine looks like a rdpipe with only the last two
|
||||||
|
** parameters.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** ptr -- pointer to data area
|
||||||
|
** cnt -- byte count
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** actual number of bytes read
|
||||||
|
*/
|
||||||
|
pipetrrd(ptr, cnt)
|
||||||
|
register char *ptr;
|
||||||
|
register int cnt;
|
||||||
|
{
|
||||||
|
return (rdpipe(P_NORM, &Pipe, R_up, ptr, cnt));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RELNTRRD -- read tree from AA_TREE relation
|
||||||
|
**
|
||||||
|
** This looks exactly like the 'pipetrrd' call, except that info
|
||||||
|
** comes from the AA_TREE catalog instead of from the pipe. It
|
||||||
|
** must be initialized by calling it with a NULL pointer and
|
||||||
|
** the segment name wanted as 'treeid'.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** ptr -- NULL -- "initialize".
|
||||||
|
** else -- pointer to read area.
|
||||||
|
** cnt -- count of number of bytes to read.
|
||||||
|
** treeid -- if ptr == NULL, this is the tree id,
|
||||||
|
** otherwise this parameter is not supplied.
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** count of actual number of bytes read.
|
||||||
|
**
|
||||||
|
** Side Effects:
|
||||||
|
** static variables are adjusted correctly. Note that
|
||||||
|
** this routine can be used on only one tree
|
||||||
|
** at one time.
|
||||||
|
*/
|
||||||
|
relntrrd(ptr, cnt, treerelid, treeowner, treetype, treeid)
|
||||||
|
char *ptr;
|
||||||
|
int cnt;
|
||||||
|
char *treerelid;
|
||||||
|
char *treeowner;
|
||||||
|
char treetype;
|
||||||
|
int treeid;
|
||||||
|
{
|
||||||
|
static struct tree trseg;
|
||||||
|
static char *trp;
|
||||||
|
static short seqno;
|
||||||
|
register char *p;
|
||||||
|
register int n;
|
||||||
|
register int i;
|
||||||
|
struct tree trkey;
|
||||||
|
struct tup_id tid;
|
||||||
|
|
||||||
|
p = ptr;
|
||||||
|
n = cnt;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
/* initialize -- make buffer appear empty */
|
||||||
|
trp = &trseg.treetree[sizeof trseg.treetree];
|
||||||
|
AAbmove(treerelid, trseg.treerelid, MAXNAME);
|
||||||
|
AAbmove(treeowner, trseg.treeowner, 2);
|
||||||
|
trseg.treetype = treetype;
|
||||||
|
trseg.treeid = treeid;
|
||||||
|
seqno = 0;
|
||||||
|
opencatalog(AA_TREE, 0);
|
||||||
|
|
||||||
|
# ifdef xQTR2
|
||||||
|
AAtTfp(70, 6, "RELNTRRD: n=%.12s o=%.2s t=%d i=%d\n",
|
||||||
|
treerelid, treeowner, treetype, treeid);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fetch characters */
|
||||||
|
while (n-- > 0)
|
||||||
|
{
|
||||||
|
/* check for segment empty */
|
||||||
|
if (trp >= &trseg.treetree[sizeof trseg.treetree])
|
||||||
|
{
|
||||||
|
/* then read new segment */
|
||||||
|
AAam_clearkeys(&Treedes);
|
||||||
|
AAam_setkey(&Treedes, &trkey, trseg.treerelid, TREERELID);
|
||||||
|
AAam_setkey(&Treedes, &trkey, trseg.treeowner, TREEOWNER);
|
||||||
|
AAam_setkey(&Treedes, &trkey, &trseg.treetype, TREETYPE);
|
||||||
|
AAam_setkey(&Treedes, &trkey, &trseg.treeid, TREEID);
|
||||||
|
AAam_setkey(&Treedes, &trkey, &seqno, TREESEQ);
|
||||||
|
seqno++;
|
||||||
|
if (i = AAgetequal(&Treedes, &trkey, &trseg, &tid))
|
||||||
|
AAsyserr(19052, i);
|
||||||
|
trp = &trseg.treetree[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do actual character fetch */
|
||||||
|
*p++ = *trp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GETTREE -- get tree from AA_TREE catalog
|
||||||
|
**
|
||||||
|
** This function, given an internal treeid, fetches and builds
|
||||||
|
** that tree from the AA_TREE catalog. There is nothing exciting
|
||||||
|
** except the mapping of variables, done by mapvars().
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** treeid -- internal id of tree to fetch and build.
|
||||||
|
** init -- passed to 'readqry' to tell whether or not
|
||||||
|
** to initialize the query buffer.
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** Pointer to root of tree.
|
||||||
|
*/
|
||||||
|
QTREE *gettree(treerelid, treeowner, treetype, treeid, init)
|
||||||
|
char *treerelid;
|
||||||
|
char *treeowner;
|
||||||
|
char treetype;
|
||||||
|
int treeid;
|
||||||
|
int init;
|
||||||
|
{
|
||||||
|
register QTREE *t;
|
||||||
|
extern int relntrrd();
|
||||||
|
|
||||||
|
/* initialize relntrrd() for this treeid */
|
||||||
|
relntrrd(NULL, 0, treerelid, treeowner, treetype, treeid);
|
||||||
|
|
||||||
|
/* read and build query tree */
|
||||||
|
t = readqry(relntrrd, init);
|
||||||
|
|
||||||
|
/* remap varno's to be unique */
|
||||||
|
if (!init)
|
||||||
|
mapvars(t);
|
||||||
|
|
||||||
|
return (t);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "../h/symbol.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** TREE -- create new tree node.
|
||||||
|
**
|
||||||
|
** This is a stripped down version of the same thing in the
|
||||||
|
** parser.
|
||||||
|
**
|
||||||
|
** It only knows about lengths of zero and two.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** lptr -- the left pointer.
|
||||||
|
** rptr -- the right pointer.
|
||||||
|
** typ -- the node type.
|
||||||
|
** len -- the node length.
|
||||||
|
** value -- the node value.
|
||||||
|
**
|
||||||
|
** Returns:
|
||||||
|
** A pointer to the created node.
|
||||||
|
*/
|
||||||
|
QTREE *tree(lptr, rptr, typ, len, value)
|
||||||
|
QTREE *lptr;
|
||||||
|
QTREE *rptr;
|
||||||
|
char typ;
|
||||||
|
int len;
|
||||||
|
int value;
|
||||||
|
{
|
||||||
|
register QTREE *tptr;
|
||||||
|
extern char *need();
|
||||||
|
register int l;
|
||||||
|
|
||||||
|
l = len;
|
||||||
|
|
||||||
|
tptr = (QTREE *) need(Qbuf, l + QT_HDR_SIZ);
|
||||||
|
tptr->left = lptr;
|
||||||
|
tptr->right = rptr;
|
||||||
|
tptr->sym.type = typ;
|
||||||
|
tptr->sym.len = l;
|
||||||
|
|
||||||
|
if (l > 0)
|
||||||
|
tptr->sym.value[0] = value;
|
||||||
|
return (tptr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/symbol.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** TREEPR -- print tree for debugging
|
||||||
|
**
|
||||||
|
** This module prints a tree for debugging purposes. There are
|
||||||
|
** two interfaces: treepr prints an entire treeree, and nodepr
|
||||||
|
** prints a single node.
|
||||||
|
**
|
||||||
|
** Defines:
|
||||||
|
** treepr -- tree print interface.
|
||||||
|
** rcsvtrpr -- the recursive part to traverse the tree.
|
||||||
|
** nodepr -- node print interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern char *Qmdname[]; /* defined in util.c */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** TREEPR -- print tree for debugging
|
||||||
|
**
|
||||||
|
** This routine prints a tree for debugging.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** t -- root of tree to be printed
|
||||||
|
** label -- label to print for identifying the tree. NULL
|
||||||
|
** is OK and produces a default label.
|
||||||
|
*/
|
||||||
|
treepr(tree, label)
|
||||||
|
register QTREE *tree;
|
||||||
|
register char *label;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* print label */
|
||||||
|
putchar('\n');
|
||||||
|
if (label != (char *) 0)
|
||||||
|
printf("%s ", label);
|
||||||
|
printf("Querytree @ 0%o:\n", tree);
|
||||||
|
|
||||||
|
/* print range table */
|
||||||
|
for (i = 0; i < MAXVAR + 1; i++)
|
||||||
|
{
|
||||||
|
if (!Rangev[i].rused)
|
||||||
|
continue;
|
||||||
|
printf("range of %d is %.12s [O=%.2s, S=0%o]\n",
|
||||||
|
i, Rangev[i].relid, Rangev[i].rowner, Rangev[i].rstat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print query type */
|
||||||
|
if (Qmode >= 0)
|
||||||
|
printf("%s ", Qmdname[Qmode]);
|
||||||
|
|
||||||
|
/* print result relation if realistic */
|
||||||
|
if (Resultvar >= 0)
|
||||||
|
printf("Resultvar %d ", Resultvar);
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
/* print tree */
|
||||||
|
rcsvtrpr(tree);
|
||||||
|
|
||||||
|
/* print exciting final stuff */
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RCSVTRPR -- traverse and print tree
|
||||||
|
**
|
||||||
|
** This function does the real stuff for treepr. It recursively
|
||||||
|
** traverses the tree in postfix order, printing each node.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** tree -- the root of the tree to print.
|
||||||
|
*/
|
||||||
|
rcsvtrpr(tree)
|
||||||
|
register QTREE *tree;
|
||||||
|
{
|
||||||
|
while (tree != (QTREE *) 0)
|
||||||
|
{
|
||||||
|
rcsvtrpr(tree->left);
|
||||||
|
nodepr(tree, FALSE);
|
||||||
|
tree = tree->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** NODEPR -- print node for debugging
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** tree -- the node to print.
|
||||||
|
*/
|
||||||
|
nodepr(tree)
|
||||||
|
register QTREE *tree;
|
||||||
|
{
|
||||||
|
register int ty;
|
||||||
|
register int l;
|
||||||
|
register char *cp;
|
||||||
|
|
||||||
|
ty = tree->sym.type;
|
||||||
|
l = ctou(tree->sym.len);
|
||||||
|
|
||||||
|
printf("0%o: 0%o, 0%o/ ", tree, tree->left, tree->right);
|
||||||
|
printf("%d, %d: ", ty, l);
|
||||||
|
|
||||||
|
switch (ty)
|
||||||
|
{
|
||||||
|
case VAR:
|
||||||
|
printf("%d.%d [%d/%d]",
|
||||||
|
((VAR_NODE *) tree)->varno, ((VAR_NODE *) tree)->attno,
|
||||||
|
((VAR_NODE *) tree)->frmt, ctou(((VAR_NODE *) tree)->frml));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESDOM:
|
||||||
|
printf("%d [%d/%d]", ((RES_NODE *) tree)->resno,
|
||||||
|
((VAR_NODE *) tree)->frmt, ((VAR_NODE *) tree)->frml);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AOP:
|
||||||
|
printf("%d [%d/%d] [%d/%d]", ((RES_NODE *) tree)->resno,
|
||||||
|
((VAR_NODE *) tree)->frmt, ((VAR_NODE *) tree)->frml,
|
||||||
|
((AOP_NODE *) tree)->agfrmt, ((AOP_NODE *) tree)->agfrml);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UOP:
|
||||||
|
case BOP:
|
||||||
|
case COP:
|
||||||
|
case INT:
|
||||||
|
switch (tree->sym.len)
|
||||||
|
{
|
||||||
|
case sizeof (char):
|
||||||
|
case sizeof (short):
|
||||||
|
printf("%d", tree->sym.value[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sizeof (long):
|
||||||
|
printf("%ld", ((I4TYPE *) tree->sym.value)->i4type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLOAT:
|
||||||
|
printf("%.10f", ((I4TYPE *) tree->sym.value)->i4type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHAR:
|
||||||
|
cp = (char *) tree->sym.value;
|
||||||
|
while (l--)
|
||||||
|
{
|
||||||
|
putchar(*cp);
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TREE:
|
||||||
|
case AND:
|
||||||
|
case OR:
|
||||||
|
case QLEND:
|
||||||
|
case BYHEAD:
|
||||||
|
case ROOT:
|
||||||
|
case AGHEAD:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
AAsyserr(19053, ty);
|
||||||
|
}
|
||||||
|
printf("/\n");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# include "gen.h"
|
||||||
|
# include "../h/dbs.h"
|
||||||
|
# include "../h/aux.h"
|
||||||
|
# include "../h/pipes.h"
|
||||||
|
# include "../h/tree.h"
|
||||||
|
# include "../h/symbol.h"
|
||||||
|
# include "qrymod.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WRITETREE.C -- query tree output routines
|
||||||
|
**
|
||||||
|
** These routines write out a query tree in internal format.
|
||||||
|
**
|
||||||
|
** Defines:
|
||||||
|
** writetree
|
||||||
|
** writeqry
|
||||||
|
** writesym
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern struct pipfrmt Pipe;
|
||||||
|
extern struct pipfrmt Outpipe;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WRITETREE -- write a query tree
|
||||||
|
**
|
||||||
|
** A query tree is written to the down pipe. The parameter is
|
||||||
|
** the root of the tree to be written.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** q1 -- the root of the tree to write.
|
||||||
|
** wrfn -- the function to call to do physical
|
||||||
|
** writes.
|
||||||
|
*/
|
||||||
|
writetree(q1, wrfn)
|
||||||
|
QTREE *q1;
|
||||||
|
int (*wrfn)();
|
||||||
|
{
|
||||||
|
register QTREE *q;
|
||||||
|
register int l;
|
||||||
|
register char t;
|
||||||
|
|
||||||
|
q = q1;
|
||||||
|
|
||||||
|
/* write the subtrees */
|
||||||
|
if (q->left != NULL)
|
||||||
|
writetree(q->left, wrfn);
|
||||||
|
if (q->right != NULL)
|
||||||
|
writetree(q->right, wrfn);
|
||||||
|
|
||||||
|
/* write this node */
|
||||||
|
t = q->sym.type;
|
||||||
|
if (t == AND || t == ROOT || t == AGHEAD)
|
||||||
|
q->sym.len = 0;
|
||||||
|
(*wrfn)(&(q->sym), TYP_LEN_SIZ);
|
||||||
|
if (l = ctou(q->sym.len))
|
||||||
|
(*wrfn)(q->sym.value, l);
|
||||||
|
# ifdef xQTR1
|
||||||
|
if (AAtTf(70, 5))
|
||||||
|
nodepr(q, TRUE);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WRITEQRY -- write a whole query
|
||||||
|
**
|
||||||
|
** An entire query is written, including range table, and so
|
||||||
|
** forth.
|
||||||
|
**
|
||||||
|
** Parameters:
|
||||||
|
** root -- the root of the tree to write.
|
||||||
|
** wrfn -- the function to do the physical write.
|
||||||
|
*/
|
||||||
|
writeqry(root, wrfn)
|
||||||
|
QTREE *root;
|
||||||
|
int (*wrfn)();
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
short resvar;
|
||||||
|
SRCID sid;
|
||||||
|
|
||||||
|
/* write the query mode */
|
||||||
|
if (Qmode >= 0)
|
||||||
|
{
|
||||||
|
resvar = Qmode;
|
||||||
|
writesym(QMODE, sizeof (short), &resvar, wrfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write the range table */
|
||||||
|
for (i = 0; i < MAXVAR + 1; i++)
|
||||||
|
{
|
||||||
|
if (Rangev[i].rused)
|
||||||
|
{
|
||||||
|
((SYMBOL *) &sid)->type = SOURCEID;
|
||||||
|
((SYMBOL *) &sid)->len = SRC_SIZ;
|
||||||
|
AApmove(Rangev[i].relid, sid.srcname, MAXNAME, ' ');
|
||||||
|
sid.srcvar = i;
|
||||||
|
sid.srcstat = Rangev[i].rstat;
|
||||||
|
AAbmove(Rangev[i].rowner, sid.srcown, 2);
|
||||||
|
(*wrfn)(&sid, TYP_LEN_SIZ);
|
||||||
|
(*wrfn)(&sid.srcvar, SRC_SIZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write a possible result variable */
|
||||||
|
if (Resultvar >= 0)
|
||||||
|
{
|
||||||
|
resvar = Resultvar;
|
||||||
|
writesym(RESULTVAR, sizeof (short), &resvar, wrfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write the tree */
|
||||||
|
writetree(root, wrfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WRITESYM -- write a symbol block
|
||||||
|
**
|
||||||
|
** A single symbol entry of the is written.
|
||||||
|
** a 'value' of zero will not be written.
|
||||||
|
*/
|
||||||
|
writesym(typ, len, value, wrfn)
|
||||||
|
int typ;
|
||||||
|
int len;
|
||||||
|
char *value;
|
||||||
|
int (*wrfn)();
|
||||||
|
{
|
||||||
|
SYMBOL sym;
|
||||||
|
register char *v;
|
||||||
|
register int l;
|
||||||
|
|
||||||
|
sym.type = ctou(typ);
|
||||||
|
sym.len = l = ctou(len);
|
||||||
|
(*wrfn)(&sym, TYP_LEN_SIZ);
|
||||||
|
v = value;
|
||||||
|
if (v != 0)
|
||||||
|
(*wrfn)(v, l);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue