Esempio n. 1
0
/* Set tracing after a signal.
 */
void
set_tracelevel(void)
{
	if (new_tracelevel == tracelevel)
		return;

	/* If tracing entirely off, and there was no tracefile specified
	 * on the command line, then leave it off.
	 */
	if (new_tracelevel > tracelevel && ftrace == NULL) {
		if (savetracename[0] != '\0') {
			set_tracefile(savetracename,sigtrace_pat,0);
		} else if (inittracename[0] != '\0') {
				set_tracefile(inittracename,sigtrace_pat,0);
		} else {
			new_tracelevel = 0;
			return;
		}
	} else {
		tracelevel_msg(sigtrace_pat, 0);
	}
}
Esempio n. 2
0
void
set_tracefile(const char *filename,
	      const char *pat,
	      int dump)			/* -1=no dump, 0=default, 1=force */
{
	struct stat stbuf;
	FILE *n_ftrace;
	const char *fn;


	/* Allow a null filename to increase the level if the trace file
	 * is already open or if coming from a trusted source, such as
	 * a signal or the command line.
	 */
	if (filename == NULL || filename[0] == '\0') {
		filename = NULL;
		if (ftrace == NULL) {
			if (inittracename[0] == '\0') {
				msglog("missing trace file name");
				return;
			}
			fn = inittracename;
		} else {
			fn = NULL;
		}

	} else if (!strcmp(filename,"dump/../table")) {
		trace_dump();
		return;

	} else {
		/* Allow the file specified with "-T file" to be reopened,
		 * but require all other names specified over the net to
		 * match the official path.  The path can specify a directory
		 * in which the file is to be created.
		 */
		if (strcmp(filename, inittracename)
#ifdef _PATH_TRACE
		    && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1)
			|| strstr(filename,"../")
			|| 0 > stat(_PATH_TRACE, &stbuf))
#endif
		    ) {
			msglog("wrong trace file \"%s\"", filename);
			return;
		}

		/* If the new tracefile exists, it must be a regular file.
		 */
		if (stat(filename, &stbuf) >= 0 && !S_ISREG(stbuf.st_mode)) {
			msglog("wrong type (%#x) of trace file \"%s\"",
			       stbuf.st_mode, filename);
			return;
		}

		fn = filename;
	}

	if (fn != NULL) {
		n_ftrace = fopen(fn, "a");
		if (n_ftrace == NULL) {
			msglog("failed to open trace file \"%s\" %s",
			       fn, strerror(errno));
			if (fn == inittracename)
				inittracename[0] = '\0';
			return;
		}

		tmsg("switch to trace file %s", fn);

		trace_close(file_trace = 1);

		if (fn != savetracename)
			strncpy(savetracename, fn, sizeof(savetracename)-1);
		ftrace = n_ftrace;

		fflush(stdout);
		fflush(stderr);
		dup2(fileno(ftrace), STDOUT_FILENO);
		dup2(fileno(ftrace), STDERR_FILENO);
	}

	if (new_tracelevel == 0 || filename == NULL)
		new_tracelevel++;
	tracelevel_msg(pat, dump != 0 ? dump : (filename != NULL));
}
Esempio n. 3
0
void
set_tracefile(const char *filename,
    const char *pat,
    int dump)			/* -1=no dump, 0=default, 1=force */
{
	struct stat stbuf;
	struct stat stbuf2;
	FILE *n_ftrace;
	const char *fn;
	int nfd;
	boolean_t allow_create;

	/*
	 * main() calls this routine with "dump == -1".  All others
	 * call it with 0, so we take dump == -1 to mean "can create
	 * the file."
	 */
	allow_create = (dump == -1);

	/*
	 * Allow a null filename to increase the level if the trace file
	 * is already open or if coming from a trusted source, such as
	 * a signal or the command line.
	 */
	if (filename == NULL || filename[0] == '\0') {
		filename = NULL;
		if (ftrace == NULL) {
			if (inittracename[0] == '\0') {
				msglog("missing trace file name");
				return;
			}
			fn = inittracename;
		} else {
			goto set_tracelevel;
		}

	} else if (strcmp(filename, "dump/../table") == 0) {
		trace_dump();
		return;

	} else {
		/*
		 * Allow the file specified with "-T file" to be reopened,
		 * but require all other names specified over the net to
		 * match the official path.  The path can specify a directory
		 * in which the file is to be created.
		 */

		if (strcmp(filename, inittracename) != 0) {
			if (strncmp(filename, PATH_TRACE,
			    sizeof (PATH_TRACE)-1) != 0 ||
			    (strstr(filename, "../") != NULL)) {
				msglog("wrong trace file \"%s\"", filename);
				return;
			}
			if (stat(PATH_TRACE, &stbuf) == -1) {
				fn = PATH_TRACE;
				goto missing_file;
			}
			if (filename[sizeof (PATH_TRACE) - 1] != '\0' &&
			    (filename[sizeof (PATH_TRACE) - 1] != '/' ||
			    !S_ISDIR(stbuf.st_mode))) {
				goto bad_file_type;
			}
			if (S_ISDIR(stbuf.st_mode))
				allow_create = _B_TRUE;
		}

		fn = filename;
	}
	/* fn cannot be null here */

	/* If the new tracefile exists, it must be a regular file. */
	if (lstat(fn, &stbuf) == -1) {
		if (!allow_create)
			goto missing_file;
		nfd = open(fn, O_CREAT|O_EXCL|O_WRONLY, 0644);
		if (nfd != -1 && fstat(nfd, &stbuf) == -1) {
			(void) close(nfd);
			goto missing_file;
		}
	} else if (S_ISREG(stbuf.st_mode)) {
		nfd = open(fn, O_APPEND|O_WRONLY, 0644);
	} else {
		goto bad_file_type;
	}

	if (nfd == -1 || (n_ftrace = fdopen(nfd, "a")) == NULL) {
		msglog("failed to open trace file \"%s\" %s", fn,
		    rip_strerror(errno));
		if (fn == inittracename)
			inittracename[0] = '\0';
		if (nfd != -1)
			(void) close(nfd);
		return;
	}

	if (fstat(nfd, &stbuf2) == -1 || !S_ISREG(stbuf2.st_mode) ||
	    stbuf2.st_dev != stbuf.st_dev || stbuf2.st_ino != stbuf.st_ino) {
		msglog("trace file \"%s\" moved", fn);
		(void) fclose(n_ftrace);
		return;
	}

	tmsg("switch to trace file %s", fn);
	trace_close(file_trace = _B_TRUE);
	(void) dup2(nfd, STDOUT_FILENO);
	(void) dup2(nfd, STDERR_FILENO);

	if (fn != savetracename)
		(void) strlcpy(savetracename, fn, sizeof (savetracename) - 1);
	ftrace = n_ftrace;

set_tracelevel:
	if (new_tracelevel == 0 || filename == NULL)
		new_tracelevel++;
	tracelevel_msg(pat, dump != 0 ? dump : (filename != NULL));
	return;

missing_file:
	msglog("trace \"%s\" missing", fn);
	return;

bad_file_type:
	msglog("wrong type (%#x) of trace file \"%s\"", stbuf.st_mode, fn);
}