/* COMMAND "getContent": Retrieve the file referenced * SIGNATURE: getContent(str) : str; */ str URLgetContent(str *retval, url *Str1) { stream *f; str retbuf = NULL; str oldbuf = NULL; char *buf[8096]; ssize_t len; size_t rlen; if ((f = open_urlstream(*Str1)) == NULL) throw(MAL, "url.getContent", "failed to open urlstream"); if (mnstr_errnr(f) != 0) { str err = createException(MAL, "url.getContent", "opening stream failed: %s", mnstr_error(f)); mnstr_destroy(f); *retval = NULL; return err; } rlen = 0; while ((len = mnstr_read(f, buf, 1, sizeof(buf))) > 0) { if (retbuf != NULL) { oldbuf = retbuf; retbuf = GDKrealloc(retbuf, rlen + len + 1); } else { retbuf = GDKmalloc(len + 1); } if (retbuf == NULL) { if (oldbuf != NULL) GDKfree(oldbuf); mnstr_destroy(f); throw(MAL, "url.getContent", "contents too large"); } oldbuf = NULL; (void)memcpy(retbuf + rlen, buf, len); rlen += len; } if (len < 0) { GDKfree(retbuf); throw(MAL, "url.getContent", "read error"); } retbuf[rlen] = '\0'; *retval = retbuf; return MAL_SUCCEED; }
void mal_exit(void){ str err; /* * Before continuing we should make sure that all clients * (except the console) have left the scene. */ MCstopClients(0); #if 0 { int reruns=0, go_on; do{ if ( (go_on = MCactiveClients()) ) MT_sleep_ms(1000); mnstr_printf(mal_clients->fdout,"#MALexit: %d clients still active\n", go_on); } while (++reruns < SERVERSHUTDOWNDELAY && go_on > 1); } #endif stopHeartbeat(); #ifdef HAVE_JSONSTORE stopHttpdaemon(); #endif stopMALdataflow(); stopProfiling(); RECYCLEdrop(mal_clients); /* remove any left over intermediates */ unloadLibraries(); #if 0 /* skip this to solve random crashes, needs work */ freeModuleList(mal_clients->nspace); finishNamespace(); if( mal_clients->prompt) GDKfree(mal_clients->prompt); if( mal_clients->errbuf) GDKfree(mal_clients->errbuf); if( mal_clients->bak) GDKfree(mal_clients->bak); if( mal_clients->fdin){ /* missing protection against closing stdin stream */ (void) mnstr_close(mal_clients->fdin->s); (void) bstream_destroy(mal_clients->fdin); } if( mal_clients->fdout && mal_clients->fdout != GDKstdout) { (void) mnstr_close(mal_clients->fdout); (void) mnstr_destroy(mal_clients->fdout); } #endif /* deregister everything that was registered, ignore errors */ if ((err = msab_wildRetreat()) != NULL) { fprintf(stderr, "!%s", err); free(err); } /* the server will now be shut down */ if ((err = msab_registerStop()) != NULL) { fprintf(stderr, "!%s", err); free(err); } GDKexit(0); /* properly end GDK */ }
/* * The default method to interact with the database server is to connect * using a port number. The first line received should contain * authorization information, such as user name. * * The scheduleClient receives a challenge response consisting of * endian:user:password:lang:database: */ static void exit_streams( bstream *fin, stream *fout ) { if (fout && fout != GDKstdout) { mnstr_flush(fout); mnstr_close(fout); mnstr_destroy(fout); } if (fin) (void) bstream_destroy(fin); }
/* * Locate a file with SQL commands and execute it. For the time being a 1MB * file limit is implicitly imposed. If the file can not be located in the * script library, we assume it is sufficiently self descriptive. * (Respecting the file system context where the call is executed ) */ str SQLinclude(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { stream *fd; bstream *bfd; str *name = getArgReference_str(stk, pci, 1); str msg = MAL_SUCCEED, fullname; str *expr; mvc *m; size_t sz; fullname = MSP_locate_sqlscript(*name, 0); if (fullname == NULL) fullname = *name; fd = open_rastream(fullname); if (mnstr_errnr(fd) == MNSTR_OPEN_ERROR) { mnstr_destroy(fd); throw(MAL, "sql.include", "could not open file: %s\n", *name); } sz = getFileSize(fd); if (sz > (size_t) 1 << 29) { mnstr_destroy(fd); throw(MAL, "sql.include", "file %s too large to process", fullname); } bfd = bstream_create(fd, sz == 0 ? (size_t) (128 * BLOCK) : sz); if (bstream_next(bfd) < 0) { bstream_destroy(bfd); throw(MAL, "sql.include", "could not read %s\n", *name); } expr = &bfd->buf; msg = SQLstatementIntern(cntxt, expr, "sql.include", TRUE, FALSE, NULL); bstream_destroy(bfd); m = ((backend *) cntxt->sqlcontext)->mvc; if (m->sa) sa_destroy(m->sa); m->sa = NULL; (void) mb; return msg; }
str mnstr_open_wastreamwrap(Stream *S, str *filename) { stream *s; if ((s = open_wastream(*filename)) == NULL || mnstr_errnr(s)) { int errnr = mnstr_errnr(s); if (s) mnstr_destroy(s); throw(IO, "streams.open", "could not open file '%s': %s", *filename, strerror(errnr)); } else { *(stream**)S = s; } return MAL_SUCCEED; }
str mnstr_socket_wastreamwrap(Stream *S, int *socket, str *name) { stream *s; if ((s = socket_wastream(*socket, *name)) == NULL || mnstr_errnr(s)) { int errnr = mnstr_errnr(s); if (s) mnstr_destroy(s); throw(IO, "streams.open", "could not open socket: %s", strerror(errnr)); } else { *(stream**)S = s; } return MAL_SUCCEED; }
void MCexitClient(Client c) { #ifdef MAL_CLIENT_DEBUG printf("# Exit client %d\n", c->idx); #endif MPresetProfiler(c->fdout); if (c->father == NULL) { /* normal client */ if (c->fdout && c->fdout != GDKstdout) { (void) mnstr_close(c->fdout); (void) mnstr_destroy(c->fdout); } assert(c->bak == NULL); if (c->fdin) { /* missing protection against closing stdin stream */ (void) bstream_destroy(c->fdin); } c->fdout = NULL; c->fdin = NULL; } }
str SQLinitClient(Client c) { mvc *m; str schema; str msg = MAL_SUCCEED; backend *be; bstream *bfd = NULL; stream *fd = NULL; static int maybeupgrade = 1; #ifdef _SQL_SCENARIO_DEBUG mnstr_printf(GDKout, "#SQLinitClient\n"); #endif if (SQLinitialized == 0 && (msg = SQLprelude(NULL)) != MAL_SUCCEED) return msg; MT_lock_set(&sql_contextLock); /* * Based on the initialization return value we can prepare a SQLinit * string with all information needed to initialize the catalog * based on the mandatory scripts to be executed. */ if (sqlinit) { /* add sqlinit to the fdin stack */ buffer *b = (buffer *) GDKmalloc(sizeof(buffer)); size_t len = strlen(sqlinit); bstream *fdin; buffer_init(b, _STRDUP(sqlinit), len); fdin = bstream_create(buffer_rastream(b, "si"), b->len); bstream_next(fdin); MCpushClientInput(c, fdin, 0, ""); } if (c->sqlcontext == 0) { m = mvc_create(c->idx, 0, SQLdebug, c->fdin, c->fdout); global_variables(m, "monetdb", "sys"); if (isAdministrator(c) || strcmp(c->scenario, "msql") == 0) /* console should return everything */ m->reply_size = -1; be = (void *) backend_create(m, c); } else { be = c->sqlcontext; m = be->mvc; mvc_reset(m, c->fdin, c->fdout, SQLdebug, NR_GLOBAL_VARS); backend_reset(be); } if (m->session->tr) reset_functions(m->session->tr); /* pass through credentials of the user if not console */ schema = monet5_user_set_def_schema(m, c->user); if (!schema) { _DELETE(schema); throw(PERMD, "SQLinitClient", "08004!schema authorization error"); } _DELETE(schema); /*expect SQL text first */ be->language = 'S'; /* Set state, this indicates an initialized client scenario */ c->state[MAL_SCENARIO_READER] = c; c->state[MAL_SCENARIO_PARSER] = c; c->state[MAL_SCENARIO_OPTIMIZE] = c; c->sqlcontext = be; initSQLreferences(); /* initialize the database with predefined SQL functions */ if (SQLnewcatalog == 0) { /* check whether table sys.systemfunctions exists: if * it doesn't, this is probably a restart of the * server after an incomplete initialization */ sql_schema *s = mvc_bind_schema(m, "sys"); sql_table *t = s ? mvc_bind_table(m, s, "systemfunctions") : NULL; if (t == NULL) SQLnewcatalog = 1; } if (SQLnewcatalog > 0) { char path[PATHLENGTH]; str fullname; SQLnewcatalog = 0; maybeupgrade = 0; snprintf(path, PATHLENGTH, "createdb"); slash_2_dir_sep(path); fullname = MSP_locate_sqlscript(path, 1); if (fullname) { str filename = fullname; str p, n; fprintf(stdout, "# SQL catalog created, loading sql scripts once\n"); do { p = strchr(filename, PATH_SEP); if (p) *p = '\0'; if ((n = strrchr(filename, DIR_SEP)) == NULL) { n = filename; } else { n++; } fprintf(stdout, "# loading sql script: %s\n", n); fd = open_rastream(filename); if (p) filename = p + 1; if (fd) { size_t sz; sz = getFileSize(fd); if (sz > (size_t) 1 << 29) { mnstr_destroy(fd); msg = createException(MAL, "createdb", "file %s too large to process", filename); } else { bfd = bstream_create(fd, sz == 0 ? (size_t) (128 * BLOCK) : sz); if (bfd && bstream_next(bfd) >= 0) msg = SQLstatementIntern(c, &bfd->buf, "sql.init", TRUE, FALSE, NULL); bstream_destroy(bfd); } if (m->sa) sa_destroy(m->sa); m->sa = NULL; if (msg) p = NULL; } } while (p); GDKfree(fullname); } else fprintf(stderr, "!could not read createdb.sql\n"); } else { /* handle upgrades */ if (!m->sa) m->sa = sa_create(); if (maybeupgrade) SQLupgrades(c,m); maybeupgrade = 0; } MT_lock_unset(&sql_contextLock); fflush(stdout); fflush(stderr); /* send error from create scripts back to the first client */ if (msg) { error(c->fdout, msg); handle_error(m, c->fdout, 0); sqlcleanup(m, mvc_status(m)); } return msg; }
int main(int argc, char **argv) { int port = 0; char *user = NULL; char *passwd = NULL; char *host = NULL; char *dbname = NULL; int trace = 0; int describe = 0; int functions = 0; int useinserts = 0; int c; Mapi mid; int quiet = 0; stream *out; char user_set_as_flag = 0; char *table = NULL; static struct option long_options[] = { {"host", 1, 0, 'h'}, {"port", 1, 0, 'p'}, {"database", 1, 0, 'd'}, {"describe", 0, 0, 'D'}, {"functions", 0, 0, 'f'}, {"table", 1, 0, 't'}, {"inserts", 0, 0, 'N'}, {"Xdebug", 0, 0, 'X'}, {"user", 1, 0, 'u'}, {"quiet", 0, 0, 'q'}, {"help", 0, 0, '?'}, {0, 0, 0, 0} }; parse_dotmonetdb(&user, &passwd, NULL, NULL, NULL, NULL); while ((c = getopt_long(argc, argv, "h:p:d:Dft:NXu:q?", long_options, NULL)) != -1) { switch (c) { case 'u': if (user) free(user); user = strdup(optarg); user_set_as_flag = 1; break; case 'h': host = optarg; break; case 'p': assert(optarg != NULL); port = atoi(optarg); break; case 'd': dbname = optarg; break; case 'D': describe = 1; break; case 'N': useinserts = 1; break; case 'f': if (table) usage(argv[0], -1); functions = 1; break; case 't': if (table || functions) usage(argv[0], -1); table = optarg; break; case 'q': quiet = 1; break; case 'X': trace = MAPI_TRACE; break; case '?': /* a bit of a hack: look at the option that the current `c' is based on and see if we recognize it: if -? or --help, exit with 0, else with -1 */ usage(argv[0], strcmp(argv[optind - 1], "-?") == 0 || strcmp(argv[optind - 1], "--help") == 0 ? 0 : -1); default: usage(argv[0], -1); } } if (optind == argc - 1) dbname = argv[optind]; else if (optind != argc) usage(argv[0], -1); /* when config file would provide defaults */ if (user_set_as_flag) passwd = NULL; if (user == NULL) user = simple_prompt("user", BUFSIZ, 1, prompt_getlogin()); if (passwd == NULL) passwd = simple_prompt("password", BUFSIZ, 0, NULL); mid = mapi_connect(host, port, user, passwd, "sql", dbname); if (user) free(user); if (passwd) free(passwd); if (mid == NULL) { fprintf(stderr, "failed to allocate Mapi structure\n"); exit(2); } if (mapi_error(mid)) { mapi_explain(mid, stderr); exit(2); } if (!quiet) { char *motd = mapi_get_motd(mid); if (motd) fprintf(stderr, "%s", motd); } mapi_trace(mid, trace); mapi_cache_limit(mid, 10000); out = file_wastream(stdout, "stdout"); if (out == NULL) { fprintf(stderr, "failed to allocate stream\n"); exit(2); } if (!quiet) { char buf[27]; time_t t = time(0); char *p; #ifdef HAVE_CTIME_R3 ctime_r(&t, buf, sizeof(buf)); #else #ifdef HAVE_CTIME_R ctime_r(&t, buf); #else strncpy(buf, ctime(&t), sizeof(buf)); #endif #endif if ((p = strrchr(buf, '\n')) != NULL) *p = 0; mnstr_printf(out, "-- msqldump %s %s%s %s\n", describe ? "describe" : "dump", functions ? "functions" : table ? "table " : "database", table ? table : "", buf); dump_version(mid, out, "--"); } if (functions) c = dump_functions(mid, out, NULL, NULL); else if (table) c = dump_table(mid, NULL, table, out, describe, 1, useinserts); else c = dump_database(mid, out, describe, useinserts); mnstr_flush(out); mapi_destroy(mid); if (mnstr_errnr(out)) { fprintf(stderr, "%s: %s", argv[0], mnstr_error(out)); return 1; } mnstr_destroy(out); return c; }