static int replace_cmd(void) {
	char n[MAX_FNAME], envstr[MAX_ENVSTR];
	FILE *tmp;
	int ch, eof, fd;
	int error = 0;
	entry *e;
	uid_t file_owner;
	char **envp;
	char *safename;
	int envs = 0, entries = 0;


	safename = host_specific_filename("#tmp", "XXXXXXXXXX");
	if (!safename || !glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
			safename, '/')) {
		TempFilename[0] = '\0';
		fprintf(stderr, "path too long\n");
		return (-2);
	}
	if ((fd = mkstemp(TempFilename)) == -1 || !(tmp = fdopen(fd, "w+"))) {
		perror(TempFilename);
		if (fd != -1) {
			close(fd);
			unlink(TempFilename);
		}
		TempFilename[0] = '\0';
		return (-2);
	}

	(void) signal(SIGHUP, die);
	(void) signal(SIGINT, die);
	(void) signal(SIGQUIT, die);

	/* write a signature at the top of the file.
	 *
	 * VERY IMPORTANT: make sure NHEADER_LINES agrees with this code.
	 */
	/*fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");
	 *fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
	 *fprintf(tmp, "# (Cron version %s)\n", CRON_VERSION);
	 */
#ifdef WITH_SELINUX
	if (selinux_context)
		fprintf(tmp, "SELINUX_ROLE_TYPE=%s\n", selinux_context);
#endif

	/* copy the crontab to the tmp
	 */
	rewind(NewCrontab);
	Set_LineNum(1)
		while (EOF != (ch = get_char(NewCrontab)))
		putc(ch, tmp);
	if (ftruncate(fileno(tmp), ftell(tmp)) == -1) {
		fprintf(stderr, "%s: error while writing new crontab to %s\n",
			ProgramName, TempFilename);
		fclose(tmp);
		error = -2;
		goto done;
	}
	fflush(tmp);
	rewind(tmp);
	if (ferror(tmp)) {
		fprintf(stderr, "%s: error while writing new crontab to %s\n",
			ProgramName, TempFilename);
		fclose(tmp);
		error = -2;
		goto done;
	}

	/* check the syntax of the file being installed.
	 */

	/* BUG: was reporting errors after the EOF if there were any errors
	 * in the file proper -- kludged it by stopping after first error.
	 *      vix 31mar87
	 */
	Set_LineNum(1 - NHEADER_LINES)
		CheckErrorCount = 0;
	eof = FALSE;

	envp = env_init();
	if (envp == NULL) {
		fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
		fclose(tmp);
		error = -2;
		goto done;
	}

	while (!CheckErrorCount && !eof) {
		if (!skip_comments(tmp)) {
			check_error("too many garbage characters");
			break;
		}
		switch (load_env(envstr, tmp)) {
		case ERR:
			/* check for data before the EOF */
			if (envstr[0] != '\0') {
				Set_LineNum(LineNumber + 1);
				check_error("premature EOF");
			}
			eof = TRUE;
			break;
		case FALSE:
			e = load_entry(tmp, check_error, pw, envp);
			if (e) {
				++entries;
				free_entry(e);
			}
			break;
		case TRUE:
			++envs;
			break;
		}
	}
	env_free(envp);
	if (envs > MAX_USER_ENVS) {
		fprintf(stderr, "More than %d environment variables in crontab file, can't install.\n", MAX_USER_ENVS);
		fclose(tmp);
		error = -1;
		goto done;
	}

	if (entries > MAX_USER_ENTRIES) {
		fprintf(stderr, "More than %d entries in crontab file, can't install.\n", MAX_USER_ENTRIES);
		fclose(tmp);
		error = -1;
		goto done;
	}

	if (CheckErrorCount != 0) {
		fprintf(stderr, "errors in crontab file, can't install.\n");
		fclose(tmp);
		error = -1;
		goto done;
	}

	file_owner = (getgid() == geteuid() && getgid() == getegid()) ? ROOT_UID : pw->pw_uid;

#ifdef HAVE_FCHOWN
	if (fchown(fileno(tmp), file_owner, (gid_t)-1) < OK) {
		perror("fchown");
		fclose(tmp);
		error = -2;
		goto done;
	}
#else
	if (chown(TempFilename, file_owner, (gid_t)-1) < OK) {
		perror("chown");
		fclose(tmp);
		error = -2;
		goto done;
	}
#endif

	if (fclose(tmp) == EOF) {
		perror("fclose");
		error = -2;
		goto done;
	}

	if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
		fprintf(stderr, "path too long\n");
		error = -2;
		goto done;
	}
	if (rename(TempFilename, n)) {
		fprintf(stderr, "%s: error renaming %s to %s\n",
			ProgramName, TempFilename, n);
		perror("rename");
		error = -2;
		goto done;
	}
	TempFilename[0] = '\0';
	log_it(RealUser, Pid, "REPLACE", User, 0);

	poke_daemon();

  done:
	(void) signal(SIGHUP, SIG_DFL);
	(void) signal(SIGINT, SIG_DFL);
	(void) signal(SIGQUIT, SIG_DFL);
	if (TempFilename[0]) {
		(void) unlink(TempFilename);
		TempFilename[0] = '\0';
	}
	return (error);
}