示例#1
0
文件: url.c 项目: f7753/monetdb
/* 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;
}
示例#2
0
文件: mal.c 项目: jaiminpan/Monetdb
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 */
}
示例#3
0
/*
 * 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);
}
示例#4
0
/*
 * 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;
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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;
	}
}
示例#8
0
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;
}
示例#9
0
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;
}