📄 mal_session.c
字号:
#line 54 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"#include "mal_config.h"#include "mal_session.h"#include "mal_instruction.h" /* for pushEndInstruction() */#include "mal_interpreter.h" /* for showErrors(), runMAL(), garbageElement(), garbageCollector() */#include "mal_linker.h" /* for initLibraries() */#include "mal_parser.h" /* for parseMAL() */#include "mal_namespace.h"#include "mal_readline.h"#include "mal_authorize.h"#include <gdk.h> /* for opendir and friends */intmalBootstrap(){ Client c; str bootfile = "mal_init", bf; c = MCinitClient((oid)0, 0, 0); c->nspace = newModule(NULL, putName("user", 4)); initLibraries(); if (defaultScenario(c)) { GDKfatal("Failed to initialise default scenario"); return 0; } bf = GDKgetenv("mal_bootstrap"); if (bf) bootfile = bf; MSinitClientPrg(c,"user", "main"); malInclude(c, bootfile, 0); mal_scope = c->nspace; pushEndInstruction(c->curprg->def); trimMalBlk(c->curprg->def); chkProgram(c->nspace, c->curprg->def); if (c->curprg->def->errors) { showErrors(); GDKfatal("Failed to initialise system"); return 0; } MALengine(c); return 1;}#line 112 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"voidMSinitClientPrg(Client cntxt, str mod, str nme){ InstrPtr p; MalBlkPtr mb; int i, cnt = 1; if (cntxt->curprg && idcmp(nme, cntxt->curprg->name) == 0) { mb = cntxt->curprg->def; for (i = 1; i < mb->stop; i++) if (mb->stmt[i]->token == REMsymbol) cnt++; if (mb->stop <= cnt + 1) { /* complete comments */ mb->typefixed = 0; mb->flowfixed = 0; mb->stop = 1; cntxt->glb = 0; return; } } cntxt->curprg = newFunction(putName(nme, strlen(nme)), FUNCTIONsymbol); mb = cntxt->curprg->def; p = getSignature(cntxt->curprg); if( mod ) setModuleId(p,mod); else setModuleScope(p, cntxt->nspace); setVarType(mb, findVariable(mb, nme), TYPE_void); insertSymbol(cntxt->nspace, cntxt->curprg); cntxt->glb = 0; assert(cntxt->curprg->def != NULL);}#line 147 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"#line 161 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"voidMSscheduleClient(str command, str challenge, bstream *fin, stream *fout){ char *user = command, *algo = NULL, *passwd = NULL, *lang = NULL; char *database = NULL, *s; int key = 0; Client c; MT_Id p; /* decode BIG/LIT:user:{cypher}passwordchal:lang:database: line */ /* byte order */ s = strchr(user, ':'); if (s) { *s = 0; stream_set_byteorder(fin->s, strcmp(user, "BIG") == 0); user = s + 1; } else { stream_printf(fout, "!incomplete challenge '%s'\n", user); stream_flush(fout); GDKfree(command); return; } /* passwd */ s = strchr(user, ':'); if (s) { *s = 0; passwd = s + 1; /* decode algorithm, i.e. {plain}mypasswordchallenge */ if (*passwd != '{') { stream_printf(fout, "!invalid password entry\n"); stream_flush(fout); GDKfree(command); return; } algo = passwd + 1; s = strchr(algo, '}'); if (!s) { stream_printf(fout, "!invalid password entry\n"); stream_flush(fout); GDKfree(command); return; } *s = 0; passwd = s + 1; } else { stream_printf(fout, "!incomplete challenge '%s'\n", user); stream_flush(fout); GDKfree(command); return; } /* lang */ s = strchr(passwd, ':'); if (s) { *s = 0; lang = s + 1; } else { stream_printf(fout, "!incomplete challenge, missing language\n"); stream_flush(fout); GDKfree(command); return; } /* database */ s = strchr(lang, ':'); if (s) { *s = 0; database = s + 1; /* we can have stuff following, make it void */ s = strchr(database, ':'); if (s) *s = 0; } if (database && database[0] != '\0' && strcmp(database, GDKgetenv("gdk_dbname")) != 0) { DIR *d; struct dirent *e; int found = 0; str buf = alloca(sizeof(char) * (PATHLENGTH + 1)); str p; int len; FILE *f; str err = NULL; str redir; buf[PATHLENGTH] = '\0'; /* scan the parent for directories */ d = opendir(".."); while ((e = readdir(d)) != NULL) { /* skip if not the database we're looking for */ if (strcmp(e->d_name, database) != 0) continue; /* ok, look for some files we're interested in, start * checking if the server is connectable */ snprintf(buf, PATHLENGTH, "../%s/.conn", e->d_name); if ((f = fopen(buf, "r")) == NULL) { err = "database not available or cannot be connected to"; break; /* we don't have to look further any more */ } if ((len = fread(buf, 1, PATHLENGTH, f)) <= 0) { /* ok, won't work */ fclose(f); err = "database cannot be connected to"; break; } buf[len] = '\0'; /* note: in theory, multiple addresses can be in this file. * We ignore this for now, and just connect to the first one */ if ((p = strchr(buf, '\n')) == NULL) { /* somehow doesn't work */ fclose(f); err = "database cannot be connected to"; break; } *p = '\0'; fclose(f); /* alloc some space */ redir = alloca(sizeof(char) * (strlen(buf) + 2)); sprintf(redir, "^%s", buf); /* see if the server supports the language we're asking for */ snprintf(buf, PATHLENGTH, "../%s/.scen", e->d_name); if ((f = fopen(buf, "r")) == NULL) { err = "language not supported"; break; } if ((len = fread(buf, 1, PATHLENGTH, f)) <= 0) { /* ok, won't work */ fclose(f); err = "database cannot be connected to"; break; } buf[len] = '\0'; while ((p = strchr(buf, '\n')) != NULL) { *p = '\0'; if (strcmp(buf, lang) == 0) { found = 1; break; } buf = p + 1; } fclose(f); if (found == 1) { stream_printf(fout, "%s%s?lang=%s&user=%s\n", redir, database, buf, user); /* flush redirect and return */ stream_flush(fout); closedir(d); GDKfree(command); return; } else { err = "language not supported"; break; } } (void) closedir(d); if (err == NULL) err = "database does not exist"; stream_printf(fout, "!redirect to database '%s': %s\n", database, err); /* flush the error to the client, and abort further execution */ stream_flush(fout); GDKfree(command); return; } else { str err; oid uid; /* access control: verify the credentials supplied by the user, * no need to check for database stuff, because that is done per * database itself (one gets a redirect) */ err = AUTHcheckCredentials(&uid, &user, &passwd, &challenge, &algo, &lang); if (err != MAL_SUCCEED) { stream_printf(fout, "!%s\n", err); stream_flush(fout); GDKfree(command); return; } c = MCinitClient(uid, fin, fout); if (c == NULL) { stream_printf(fout, "!Out of client slots\n"); stream_flush(fout); GDKfree(command); return; } c->nspace = newModule(NULL, putName("user", 4)); c->nspace->outer = mal_scope; c->sessionkey = key; if (!lang) { if ((s = defaultScenario(c))) { stream_printf(c->fdout, "!%s\n", s); stream_flush(c->fdout); c->mode = FINISHING; } } else if ((s = setScenario(c, lang)) != NULL) { stream_printf(c->fdout, "!%s\n", s); stream_flush(c->fdout); c->mode = FINISHING; } } MSinitClientPrg(c,"user", "main"); GDKfree(command); if (MT_create_thread(&p, MSserveClient, (void *) c) < 0) { showException(MAL,"initClient", "can not fork new client"); return; }}#line 400 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"voidMSresetInstructions(MalBlkPtr mb, int start){ int i; InstrPtr p; for (i = start; i < mb->stop; i++) { p = getInstrPtr(mb, i); if (p) freeInstruction(p); mb->stmt[i] = NULL; } mb->stop = start;}static int unknownType(int tpe){ return tpe == TYPE_any || (isaBatType(tpe) && ( getHeadType(tpe) == TYPE_any || getTailType(tpe) == TYPE_any ));}voidMSresetVariables(MalBlkPtr mb, MalStkPtr glb, int start){ int i, j; for (i = j = start; i < mb->vtop;) { if (isTmpVar(mb, i) || unknownType(getVarType(mb,i)) ) { clearVariable(mb, i); if (glb) { garbageElement(&glb->stk[i]); /* clean stack entry */ glb->stk[i].vtype = TYPE_int; glb->stk[i].val.ival = 0; glb->stk[i].len = 0; } i++; } else { if (i != j) { VarPtr v= getVar(mb,j); mb->var[j]= mb->var[i]; getVar(mb,i)= v; if (glb) { /* save stack state */ glb->stk[j] = glb->stk[i]; /* clean stack entry */ glb->stk[i].vtype = TYPE_int; glb->stk[i].val.ival = 0; glb->stk[i].len = 0; } } i++; j++; } } mb->vtop = j;}#line 465 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"voidMSserveClient(void *dummy){ MalBlkPtr mb; Client c = (Client) dummy; str msg = 0; if (!isAdministrator(c)) MCinitClientThread(c);#line 478 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" mb = c->curprg->def; c->glb = newGlobalStack(MAXGLOBALS + mb->vsize); c->glb->stktop = mb->vtop; c->glb->blk = mb; if (c->scenario == 0) msg = defaultScenario(c); if (msg) { showException(MAL, "serveClient", "could not initialize default scenario"); c->mode = FINISHING + 1; } else do { runScenario(c); if (c->mode == FINISHING) break; resetScenario(c); } while (c->scenario);#line 498 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" freeMalBlk(c->curprg->def); c->curprg->def = 0; if (c->mode > FINISHING) { if (isAdministrator(c)) { /* old OIDflushdelta =0; */ if (c->scenario) { exitScenario(c); } } } if (!isAdministrator(c)) MCcloseClient(c);}#line 533 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"strMALexitSession(Client c){ (void) c; return 0;}strMALexitClient(Client c){ if (c->glb) { garbageCollector(c->curprg->def, c->glb,TRUE); GDKfree(c->glb); } c->glb = 0; return 0;}strMALreader(Client c){ int r= 1; c->fdin->pos += c->yycur; c->yycur = 0; c->fdin->buf[c->fdin->pos] = 0; if( c == mal_clients){ r= readConsole(c); if (r <0 && c->fdin->eof == 0 ) r= MCreadClient(c); if( r > 0) return MAL_SUCCEED; } else if (MCreadClient(c) > 0) return MAL_SUCCEED; c->mode = FINISHING; if (c->fdin) c->fdin->buf[c->fdin->pos] = 0; else throw(MAL, "MAL.reader", "Attempt to read beyond end of file"); return MAL_SUCCEED;}strMALparser(Client c){ InstrPtr p; MalBlkRecord oldstate; c->curprg->def->errors = 0; oldstate = *c->curprg->def; prepareMalBlk(c->curprg->def, CURRENT(c)); if (parseMAL(c, c->curprg) || c->curprg->def->errors) { /* just complete it for visibility */ pushEndInstruction(c->curprg->def); /* catched errors */ showErrors(); #line 525 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" if( c->listing) printFunction(c->fdout,c->curprg->def, c->listing); resetMalBlk(c->curprg->def,oldstate.stop);/* MSresetInstructions(c->curprg->def, oldstate.stop);*/ MSresetVariables(c->curprg->def, 0, oldstate.vtop);#line 591 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" throw(SYNTAX, "MAL.parser", "Syntax errors detected"); } /* check for unfinished blocks */ if (c->blkmode) return MAL_SUCCEED; /* empty files should be skipped as well */ if (c->curprg->def->stop == 1) return MAL_SUCCEED; p = getInstrPtr(c->curprg->def, 0); if (p->token != FUNCTIONsymbol) { #line 525 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" if( c->listing) printFunction(c->fdout,c->curprg->def, c->listing); resetMalBlk(c->curprg->def,oldstate.stop);/* MSresetInstructions(c->curprg->def, oldstate.stop);*/ MSresetVariables(c->curprg->def, 0, oldstate.vtop);#line 603 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" throw(MAL, "MAL.parser", "Function signature missing"); } pushEndInstruction(c->curprg->def); trimMalBlk(c->curprg->def); chkProgram(c->nspace, c->curprg->def); if (c->curprg->def->errors) { showErrors(); #line 525 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" if( c->listing) printFunction(c->fdout,c->curprg->def, c->listing); resetMalBlk(c->curprg->def,oldstate.stop);/* MSresetInstructions(c->curprg->def, oldstate.stop);*/ MSresetVariables(c->curprg->def, 0, oldstate.vtop);#line 611 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" throw(MAL, "MAL.parser", "Semantic errors detected"); } return MAL_SUCCEED;}intMALcommentsOnly(MalBlkPtr mb){ int i; for (i = 1; i < mb->stop; i++) if (mb->stmt[i]->token != REMsymbol) return 0; return 1;}strMALengine(Client c){ Symbol prg; str msg = 0; MalBlkRecord oldstate; oldstate.stop = 0; oldstate.vtop = 0; if( c->blkmode) return MAL_SUCCEED; prg = c->curprg; if (prg == NULL) throw(MAL, "MAL.engine", "Main MAL function missing"); if (prg->def->errors > 0) { showErrors(); #line 525 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" if( c->listing) printFunction(c->fdout,c->curprg->def, c->listing); resetMalBlk(c->curprg->def,oldstate.stop);/* MSresetInstructions(c->curprg->def, oldstate.stop);*/ MSresetVariables(c->curprg->def, 0, oldstate.vtop);#line 646 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" throw(MAL, "MAL.engine", "Program contains errors"); } if (prg->def->stop == 1 || MALcommentsOnly(prg->def)) return 0; /* empty block */ if (c->glb) { if (prg->def && c->glb->stksize < prg->def->vsize) c->glb = reallocGlobalStack(c->glb, prg->def->vsize); c->glb->stktop = prg->def->vtop; c->glb->blk = prg->def; c->glb->cmd = (c->itrace && c->itrace != 'C') ? 'n' : 0; } if (c->listing) printFunction(c->fdout, c->curprg->def, c->listing);#line 666 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx" if (c->glb){ c->glb->pcup = 0; c->glb->keepAlive= TRUE; /* no garbage collection */ } if (prg->def->errors == 0) msg = (str) runMAL(c, prg->def, 1, 0, c->glb, 0); else msg = MAL_SUCCEED; if (msg) { str place = getExceptionPlace(msg); showException(getExceptionType(msg), place, getExceptionMessage(msg)); GDKfree(place); if (!c->listing) printFunction(c->fdout, c->curprg->def, c->listing); showErrors(); } resetMalBlk(prg->def,1); MSresetVariables(prg->def, c->glb, 0); prg->def->errors = 0; return msg;}#line 689 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_session.mx"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -