/* Read an existing bookmark (if one exists) */
EVT_HANDLE read_bookmark(os_channel *channel)
{
    EVT_HANDLE bookmark = NULL;
    size_t size = 0;
    FILE *fp = NULL;
    wchar_t bookmark_xml[OS_MAXSTR];

    /* If we have a stored bookmark, start from it */
    if ((fp = fopen(channel->bookmark_filename, "r")) == NULL) {
        /* Check if the error was not because the
         * file did not exist which should be logged
         */
        if (errno != ENOENT) {
            log2file(
                "%s: ERROR: Could not fopen() existing bookmark (%s) for (%s) which returned [(%d)-(%s)]",
                ARGV0,
                channel->bookmark_filename,
                channel->evt_log,
                errno,
                strerror(errno));
        }
        return (NULL);
    }

    size = fread(bookmark_xml, sizeof(wchar_t), OS_MAXSTR, fp);
    if (ferror(fp)) {
        log2file(
            "%s: ERROR: Could not fread() bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            errno,
            strerror(errno));
        fclose(fp);
        return (NULL);
    }

    fclose(fp);

    /* Make sure bookmark data was read */
    if (size == 0) {
        return (NULL);
    }

    /* Make sure bookmark is terminated properly */
    bookmark_xml[size] = L'\0';

    /* Create bookmark from saved XML */
    if ((bookmark = EvtCreateBookmark(bookmark_xml)) == NULL) {
        log2file(
            "%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        return (NULL);
    }

    return (bookmark);
}
Esempio n. 2
0
void
do_motd(dbref player, char *text)
{
    time_t lt;
    char buf[BUFFER_LEN];

    if (!*text || !Wizard(OWNER(player))) {
	spit_file(player, tp_file_motd);
	return;
    }
    if (!strcasecmp(text, "clear")) {
	unlink(tp_file_motd);
	log2file(tp_file_motd, "%s %s", "- - - - - - - - - - - - - - - - - - -",
		 "- - - - - - - - - - - - - - - - - - -");
	notify(player, "MOTD cleared.");
	return;
    }

    lt = time(NULL);
    strftime(buf, sizeof(buf), "%a %b %d %T %Z %Y", localtime(&lt));
    log2file(tp_file_motd, "%s", buf);
    add_motd_text_fmt(text);
    log2file(tp_file_motd, "%s %s", "- - - - - - - - - - - - - - - - - - -",
	     "- - - - - - - - - - - - - - - - - - -");
    notify(player, "MOTD updated.");
}
char *convert_windows_string(LPCWSTR string)
{
    char *dest = NULL;
    size_t size = 0;
    int result = 0;

    if (string == NULL) {
        return (NULL);
    }

    /* Determine size required */
    size = WideCharToMultiByte(CP_UTF8,
                               WC_ERR_INVALID_CHARS,
                               string,
                               -1,
                               NULL,
                               0,
                               NULL,
                               NULL);

    if (size == 0) {
        log2file(
            "%s: ERROR: Could not WideCharToMultiByte() when determining size which returned (%lu)",
            ARGV0,
            GetLastError());
        return (NULL);
    }

    if ((dest = calloc(size, sizeof(char))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory for WideCharToMultiByte() which returned [(%d)-(%s)]",
            ARGV0,
            errno,
            strerror(errno)
        );
        return (NULL);
    }

    result = WideCharToMultiByte(CP_UTF8,
                                 WC_ERR_INVALID_CHARS,
                                 string,
                                 -1,
                                 dest,
                                 size,
                                 NULL,
                                 NULL);

    if (result == 0) {
        log2file(
            "%s: ERROR: Could not WideCharToMultiByte() which returned (%lu)",
            ARGV0,
            GetLastError());
        free(dest);
        return (NULL);
    }

    return (dest);
}
wchar_t *convert_unix_string(char *string)
{
    wchar_t *dest = NULL;
    size_t size = 0;
    int result = 0;

    if (string == NULL) {
        return (NULL);
    }

    /* Determine size required */
    size = MultiByteToWideChar(CP_UTF8,
                               MB_ERR_INVALID_CHARS,
                               string,
                               -1,
                               NULL,
                               0);

    if (size == 0) {
        log2file(
            "%s: ERROR: Could not MultiByteToWideChar() when determining size which returned (%lu)",
            ARGV0,
            GetLastError());
        return (NULL);
    }

    if ((dest = calloc(size, sizeof(wchar_t))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory for MultiByteToWideChar() which returned [(%d)-(%s)]",
            ARGV0,
            errno,
            strerror(errno));
        return (NULL);
    }

    result = MultiByteToWideChar(CP_UTF8,
                                 MB_ERR_INVALID_CHARS,
                                 string,
                                 -1,
                                 dest,
                                 size);

    if (result == 0) {
        log2file(
            "%s: ERROR: Could not MultiByteToWideChar() which returned (%lu)",
            ARGV0,
            GetLastError());
        free(dest);
        return (NULL);
    }

    return (dest);
}
Esempio n. 5
0
void
prim_nextprop(PRIM_PROTOTYPE)
{
	/* dbref pname -- pname */
	char *pname;
	char exbuf[BUFFER_LEN];

	CHECKOP(2);
	oper2 = POP();				/* pname */
	oper1 = POP();				/* dbref */
	if (mlev < 3)
		abort_interp("Permission denied.");
	if (oper2->type != PROG_STRING)
		abort_interp("String required. (2)");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Dbref required. (1)");
	if (!valid_object(oper1))
		abort_interp("Invalid dbref. (1)");

	ref = oper1->data.objref;
	(void) strcpyn(buf, sizeof(buf), DoNullInd(oper2->data.string));

	CLEAR(oper1);
	CLEAR(oper2);

	{
		char *tmpname;

		pname = next_prop_name(ref, exbuf, sizeof(exbuf), buf);

#ifdef LOG_PROPS
		log2file("props.log", "#%d (%d) NEXTPROP: o=%d n=\"%s\" on=\"%s\"",
				 program, pc->line, ref, pname, buf);
#endif

		while (pname && !prop_read_perms(ProgUID, ref, pname, mlev)) {
			tmpname = next_prop_name(ref, exbuf, sizeof(exbuf), pname);

#ifdef LOG_PROPS
			log2file("props.log", "#%d (%d) NEXTPROP: o=%d n=\"%s\" on=\"%s\"",
					 program, pc->line, ref, tmpname, pname);
#endif

			pname = tmpname;
		}
	}
	if (pname) {
		PushString(pname);
	} else {
		PushNullStr;
	}
}
Esempio n. 6
0
void
prim_propdirp(PRIM_PROTOTYPE)
{
	/* dbref dir -- int */
	CHECKOP(2);
	oper2 = POP();				/* prop name */
	oper1 = POP();				/* dbref */
	if (mlev < 2)
		abort_interp("Permission denied.");
	if (oper1->type != PROG_OBJECT)
		abort_interp("Argument must be a dbref (1)");
	if (!valid_object(oper1))
		abort_interp("Invalid dbref (1)");
	if (oper2->type != PROG_STRING)
		abort_interp("Argument not a string. (2)");
	if (!oper2->data.string)
		abort_interp("Null string not allowed. (2)");
	ref = oper1->data.objref;
	(void) strcpyn(buf, sizeof(buf), oper2->data.string->data);
	CLEAR(oper1);
	CLEAR(oper2);

	result = is_propdir(ref, buf);

#ifdef LOG_PROPS
	log2file("props.log", "#%d (%d) PROPDIR?: o=%d n=\"%s\" v=%d",
			 program, pc->line, ref, buf, result);
#endif

	PushInt(result);
}
Esempio n. 7
0
int DeletePID(const char *name)
{
    char file[256];

    if (isChroot()) {
        snprintf(file, 255, "%s/%s-%d.pid", OS_PIDFILE, name, (int)getpid());
    } else {
        snprintf(file, 255, "%s%s/%s-%d.pid", DEFAULTDIR,
                 OS_PIDFILE, name, (int)getpid());
    }

    if (File_DateofChange(file) < 0) {
        return (-1);
    }

    if (unlink(file)) {
        log2file(
            DELETE_ERROR,
            __local_name,
            file,
            errno,
            strerror(errno)
        );
    }

    return (0);
}
Esempio n. 8
0
File: script.c Progetto: EXio4/Lex4
void cmd_play_sample(Ttoken *t) {
	int vol = 100;
	int loop = 0;
	int freq = 1000;
	int id;

	if (t != NULL) {
		Ttoken *tmp = (Ttoken *)t->next;
		if (tmp != NULL) {
			vol = atoi(tmp->word);
			tmp = (Ttoken *)tmp->next;
			if (tmp != NULL) {
				freq = atoi(tmp->word);
				tmp = (Ttoken *)tmp->next;
				if (tmp != NULL) {
					loop = atoi(tmp->word);
					tmp = (Ttoken *)tmp->next;
				}
			}
		}

		id = atoi(t->word);
		if (remember_sound(id)) play_sound_id_ex(id, vol, freq, loop);
		else log2file("*** cannot play sample %d, buffer full", id);
	}
}
Esempio n. 9
0
/* Run a cmd.exe command */
int run_cmd(char *cmd, HWND hwnd)
{
    int result;
    int cmdlen;
    char *comspec;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    DWORD exit_code;

    /* Get cmd location from environment */
    comspec = getenv("COMSPEC");
    if (comspec == NULL || strncmp(comspec, "", strlen(comspec) == 0))
    {
        MessageBox(hwnd, "Could not determine the location of "
                   "cmd.exe using the COMSPEC environment variable.",
                   "Error -- Failure Locating cmd.exe",MB_OK);
        return(0);
    }

    /* Build command */
    cmdlen = strlen(comspec) + 5 + strlen(cmd);
    char finalcmd[cmdlen];
    snprintf(finalcmd, cmdlen, "%s /c %s", comspec, cmd);

    /* Log command being run */
    log2file("%s: INFO: Running the following command (%s)", ARGV0, finalcmd);

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if(!CreateProcess(NULL, finalcmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL,
                      &si, &pi))
    {
        MessageBox(hwnd, "Unable to run command.",
                   "Error -- Failure Running Command",MB_OK);
        return(0);
    }

    /* Wait until process exits */
    WaitForSingleObject(pi.hProcess, INFINITE);

    /* Get exit code from command */
    result = GetExitCodeProcess(pi.hProcess, &exit_code);

    /* Close process and thread */
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    if (!result)
    {
        MessageBox(hwnd, "Could not determine exit code from command.",
                   "Error -- Failure Running Command",MB_OK);

        return(0);
    }

    return(exit_code);
}
Esempio n. 10
0
/* Create a temporary file */
int mkstemp_ex(char *tmp_path)
{
    int fd;

    fd = mkstemp(tmp_path);

    if (fd == -1) {
        log2file(
            MKSTEMP_ERROR,
            __local_name,
            tmp_path,
            errno,
            strerror(errno)
        );

        return (-1);
    }

    /* mkstemp() only implicitly does this in POSIX 2008 */
    if (fchmod(fd, 0600) == -1) {
        close(fd);

        log2file(
            CHMOD_ERROR,
            __local_name,
            tmp_path,
            errno,
            strerror(errno)
        );

        if (unlink(tmp_path)) {
            log2file(
                DELETE_ERROR,
                __local_name,
                tmp_path,
                errno,
                strerror(errno)
            );
        }

        return (-1);
    }

    close(fd);
    return (0);
}
Esempio n. 11
0
void
do_motd(dbref player, char *text)
{
	time_t lt;

	if (!*text || !Wizard(OWNER(player))) {
		spit_file(player, MOTD_FILE);
		return;
	}
	if (!string_compare(text, "clear")) {
		unlink(MOTD_FILE);
		log2file(MOTD_FILE, "%s %s", "- - - - - - - - - - - - - - - - - - -",
				 "- - - - - - - - - - - - - - - - - - -");
		notify(player, "MOTD cleared.");
		return;
	}
	lt = time(NULL);
	log2file(MOTD_FILE, "%.16s", ctime(&lt));
	add_motd_text_fmt(text);
	log2file(MOTD_FILE, "%s %s", "- - - - - - - - - - - - - - - - - - -",
			 "- - - - - - - - - - - - - - - - - - -");
	notify(player, "MOTD updated.");
}
Esempio n. 12
0
/* Rename file or directory */
int rename_ex(const char *source, const char *destination)
{
    if (!MoveFileEx(source, destination, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
        log2file(
            "%s: ERROR: Could not move (%s) to (%s) which returned (%lu)",
            __local_name,
            source,
            destination,
            GetLastError()
        );

        return (-1);
    }

    return (0);
}
Esempio n. 13
0
/* Rename file or directory */
int rename_ex(const char *source, const char *destination)
{
    if (rename(source, destination)) {
        log2file(
            RENAME_ERROR,
            __local_name,
            source,
            destination,
            errno,
            strerror(errno)
        );

        return (-1);
    }

    return (0);
}
Esempio n. 14
0
void
prim_unblessprop(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper2 = POP();
	oper1 = POP();
	if (oper2->type != PROG_STRING)
		abort_interp("Non-string argument (2)");
	if (!oper2->data.string)
		abort_interp("Empty string argument (2)");
	if (!valid_object(oper1))
		abort_interp("Non-object argument (1)");
	CHECKREMOTE(oper1->data.objref);

	if (mlev < 4)
		abort_interp("Permission denied.");

	{
		char *tmpe;
		char tname[BUFFER_LEN];
		int len = oper2->data.string->length;

		tmpe = oper2->data.string->data;
		while (*tmpe && *tmpe != '\r' && *tmpe != ':')
			tmpe++;
		if (*tmpe)
			abort_interp("Illegal propname");

		strcpyn(tname, sizeof(tname), oper2->data.string->data);
		while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) {
			tname[len] = '\0';
		}

		clear_property_flags(oper1->data.objref, tname, PROP_BLESSED);

#ifdef LOG_PROPS
		log2file("props.log", "#%d (%d) BLESSPROP: o=%d n=\"%s\"",
				 program, pc->line, oper1->data.objref, tname);
#endif

		ts_modifyobject(oper1->data.objref);
	}
	CLEAR(oper1);
	CLEAR(oper2);
}
Esempio n. 15
0
static void
add_motd_text_fmt(const char *text)
{
    char buf[80];
    const char *p = text;
    int count = 4;

    buf[0] = buf[1] = buf[2] = buf[3] = ' ';
    while (*p) {
	while (*p && (count < 68))
	    buf[count++] = *p++;
	while (*p && !isspace(*p) && (count < 76))
	    buf[count++] = *p++;
	buf[count] = '\0';
	log2file(tp_file_motd, "%s", buf);
	skip_whitespace(&p);
	count = 0;
    }
}
Esempio n. 16
0
void
prim_remove_prop(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if (oper1->type != PROG_STRING)
		abort_interp("Non-string argument (2)");
	if (!valid_object(oper2))
		abort_interp("Non-object argument (1)");

	CHECKREMOTE(oper2->data.objref);

	strncpy(buf, DoNullInd(oper1->data.string), BUFFER_LEN);
	buf[BUFFER_LEN - 1] = '\0';

	{
		int	len = strlen(buf);
		char*	ptr = buf + len;

		while((--len >= 0) && (*--ptr == PROPDIR_DELIMITER))
			*ptr = '\0';
	}

	if (!*buf)
		abort_interp("Can't remove root propdir (2)");

	if (!prop_write_perms(ProgUID, oper2->data.objref, buf, mlev))
		abort_interp("Permission denied.");

	remove_property(oper2->data.objref, buf);

#ifdef LOG_PROPS
	log2file("props.log", "#%d (%d) REMOVEPROP: o=%d n=\"%s\"",
		program, pc->line, oper2->data.objref, buf);
#endif

	ts_modifyobject(oper2->data.objref);

	CLEAR(oper1);
	CLEAR(oper2);
}
Esempio n. 17
0
void
add_motd_text_fmt(const char *text)
{
	char buf[80];
	const char *p = text;
	int count = 4;

	buf[0] = buf[1] = buf[2] = buf[3] = ' ';
	while (*p) {
		while (*p && (count < 68))
			buf[count++] = *p++;
		while (*p && !isspace(*p) && (count < 76))
			buf[count++] = *p++;
		buf[count] = '\0';
		log2file(MOTD_FILE, "%s", buf);
		while (*p && isspace(*p))
			p++;
		count = 0;
	}
}
Esempio n. 18
0
void
log_user(dbref player, dbref program, char *logmessage)
{
	char logformat[BUFFER_LEN];
	char buf[40];
	time_t lt = 0;
	int len = 0;

	*buf='\0';
	*logformat='\0';

	lt=time(NULL);
	format_time(buf, 32, "%c", MUCK_LOCALTIME(lt));

	snprintf(logformat,BUFFER_LEN,"%s(#%d) [%s(#%d)] at %.32s: ", NAME(player), player, NAME(program), program, buf);
	len = BUFFER_LEN - strlen(logformat)-1;
	strncat (logformat, logmessage, len);
	strip_evil_characters(logformat);
	log2file(USER_LOG,"%s",logformat);
}
Esempio n. 19
0
void
prim_getpropfval(PRIM_PROTOTYPE)
{
	double fresult;

	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if (oper1->type != PROG_STRING)
		abort_interp("Non-string argument (2)");
	if (!oper1->data.string)
		abort_interp("Empty string argument (2)");
	if (!valid_object(oper2))
		abort_interp("Non-object argument (1)");
	CHECKREMOTE(oper2->data.objref);

	if (!prop_read_perms(ProgUID, oper2->data.objref, oper1->data.string->data, mlev))
		abort_interp("Permission denied.");

	{
		char type[BUFFER_LEN];
		int len = oper1->data.string->length;

		strcpyn(type, sizeof(type), oper1->data.string->data);
		while (len-- > 0 && type[len] == PROPDIR_DELIMITER) {
			type[len] = '\0';
		}
		fresult = get_property_fvalue(oper2->data.objref, type);

#ifdef LOG_PROPS
		log2file("props.log", "#%d (%d) GETPROPFVAL: o=%d n=\"%s\" v=%d",
				 program, pc->line, oper2->data.objref, type, result);
#endif

		/* if (Typeof(oper2->data.objref) != TYPE_PLAYER)
		   ts_lastuseobject(oper2->data.objref); */
	}
	CLEAR(oper1);
	CLEAR(oper2);
	PushFloat(fresult);
}
Esempio n. 20
0
int KSGLogBackend::log(ACE_Log_Record& log_record)
{
	if(log_record.type() < _priority )
		return 0;
	ACE_TCHAR msg_data[ACE_Log_Record::MAXVERBOSELOGMSGLEN];
	ACE_OS::sprintf(msg_data,"P[%d]F[%s]L[%d]- %s\n",ACE_OS::thr_self(),ACE_LOG_MSG->file()
		,ACE_LOG_MSG->linenum(),log_record.msg_data());
	log_record.msg_data(msg_data);
	log_record.format_msg(ACE_LOG_MSG->local_host(),ACE_LOG_MSG->flags()
		,msg_data);
	int len = ACE_OS::strlen(msg_data);
	if(_log_app & laStdout)
		ACE_OS::printf(msg_data);
	if(_log_app & laFile)
		log2file(msg_data,len);

#ifndef WIN32
	if(_log_app & laSyslog)
		log2syslog(log_record);
#endif

	return 0;
}
Esempio n. 21
0
void
process_command(int descr, dbref player, char *command)
{
	char *arg1;
	char *arg2;
	char *full_command;
	char *p;					/* utility */
	char pbuf[BUFFER_LEN];
	char xbuf[BUFFER_LEN];
	char ybuf[BUFFER_LEN];
	struct timeval starttime;
	struct timeval endtime;
	double totaltime;

	if (command == 0)
		abort();

	/* robustify player */
	if (player < 0 || player >= db_top ||
		(Typeof(player) != TYPE_PLAYER && Typeof(player) != TYPE_THING)) {
		log_status("process_command: bad player %d", player);
		return;
	}

	if ((tp_log_commands || Wizard(OWNER(player)))) {
		if (!(FLAGS(player) & (INTERACTIVE | READMODE))) {
			if (!*command) {
				return; 
			}
			log_command("%s: %s", whowhere(player), command);
		} else {
			if (tp_log_interactive) {
				log_command("%s: %s%s", whowhere(player),
						(FLAGS(player) & (READMODE)) ? "[READ] " : "[INTERP] ", command);
			}
		}
	}

	if (FLAGS(player) & INTERACTIVE) {
		interactive(descr, player, command);
		return;
	}
	/* eat leading whitespace */
	while (*command && isspace(*command))
		command++;

	/* Disable null command once past READ line */
	if (!*command)
		return;

	/* check for single-character commands */
	if (!tp_enable_prefix) {
		if (*command == SAY_TOKEN) {
			snprintf(pbuf, sizeof(pbuf), "say %s", command + 1);
			command = &pbuf[0];
		} else if (*command == POSE_TOKEN) {
			snprintf(pbuf, sizeof(pbuf), "pose %s", command + 1);
			command = &pbuf[0];
		} else if (*command == EXIT_DELIMITER) {
			snprintf(pbuf, sizeof(pbuf), "delimiter %s", command + 1);
			command = &pbuf[0];
		}
	}

	/* profile how long command takes. */
	gettimeofday(&starttime, NULL);

	/* if player is a wizard, and uses overide token to start line... */
	/* ... then do NOT run actions, but run the command they specify. */
	if (!(TrueWizard(OWNER(player)) && (*command == OVERIDE_TOKEN))) {
		if (can_move(descr, player, command, 0)) {
			do_move(descr, player, command, 0);	/* command is exact match for exit */
			*match_args = 0;
			*match_cmdname = 0;
		} else {
			if (tp_enable_prefix) {
				if (*command == SAY_TOKEN) {
					snprintf(pbuf, sizeof(pbuf), "say %s", command + 1);
					command = &pbuf[0];
				} else if (*command == POSE_TOKEN) {
					snprintf(pbuf, sizeof(pbuf), "pose %s", command + 1);
					command = &pbuf[0];
				} else if (*command == EXIT_DELIMITER) {
					snprintf(pbuf, sizeof(pbuf), "delimiter %s", command + 1);
					command = &pbuf[0];
				} else {
					goto bad_pre_command;
				}
				if (can_move(descr, player, command, 0)) {
					do_move(descr, player, command, 0);	/* command is exact match for exit */
					*match_args = 0;
					*match_cmdname = 0;
				} else {
					goto bad_pre_command;
				}
			} else {
				goto bad_pre_command;
			}
		}
	} else {
	  bad_pre_command:
		if (TrueWizard(OWNER(player)) && (*command == OVERIDE_TOKEN))
			command++;
		full_command = strcpyn(xbuf, sizeof(xbuf), command);
		for (; *full_command && !isspace(*full_command); full_command++) ;
		if (*full_command)
			full_command++;

		/* find arg1 -- move over command word */
		command = strcpyn(ybuf, sizeof(ybuf), command);
		for (arg1 = command; *arg1 && !isspace(*arg1); arg1++) ;
		/* truncate command */
		if (*arg1)
			*arg1++ = '\0';

		/* remember command for programs */
		strcpyn(match_args, sizeof(match_args), full_command);
		strcpyn(match_cmdname, sizeof(match_cmdname), command);

		/* move over spaces */
		while (*arg1 && isspace(*arg1))
			arg1++;

		/* find end of arg1, start of arg2 */
		for (arg2 = arg1; *arg2 && *arg2 != ARG_DELIMITER; arg2++) ;

		/* truncate arg1 */
		for (p = arg2 - 1; p >= arg1 && isspace(*p); p--)
			*p = '\0';

		/* go past delimiter if present */
		if (*arg2)
			*arg2++ = '\0';
		while (*arg2 && isspace(*arg2))
			arg2++;

		switch (command[0]) {
		case '@':
			switch (command[1]) {
			case 'a':
			case 'A':
				/* @action, @armageddon, @attach */
				switch (command[2]) {
				case 'c':
				case 'C':
					Matched("@action");
					NOGUEST("@action", player);
					BUILDERONLY("@action", player);
					do_action(descr, player, arg1, arg2);
					break;
				case 'r':
				case 'R':
					if (strcmp(command, "@armageddon"))
						goto bad;
/*
					WIZARDONLY("@armageddon", player);
					PLAYERONLY("@armageddon", player);
*/
					do_armageddon(player, full_command);
					break;
				case 't':
				case 'T':
					Matched("@attach");
					NOGUEST("@attach", player);
					BUILDERONLY("@attach", player);
					do_attach(descr, player, arg1, arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'b':
			case 'B':
				/* @bless, @boot */
				switch (command[2]) {
				case 'l':
				case 'L':
					Matched("@bless");
					WIZARDONLY("@bless", player);
					PLAYERONLY("@bless", player);
					NOFORCE("@bless", force_level, player);
					do_bless(descr, player, arg1, arg2);
					break;
				case 'o':
				case 'O':
					Matched("@boot");
					WIZARDONLY("@boot", player);
					PLAYERONLY("@boot", player);
					do_boot(player, arg1);
					break;
				default:
					goto bad;
				}
				break;
			case 'c':
			case 'C':
				/* @chlock, @chown, @chown_lock, @clone,
				   @conlock, @contents, @create, @credits */
				switch (command[2]) {
				case 'h':
				case 'H':
					switch (command[3]) {
					case 'l':
					case 'L':
						Matched("@chlock");
						NOGUEST("@chlock", player);
						set_standard_lock(descr, player, arg1, MESGPROP_CHLOCK, "Chown Lock", arg2);
						break;
					case 'o':
					case 'O':
						if(strlen(command) < 7) {
							Matched("@chown");
							do_chown(descr, player, arg1, arg2);
						} else {
							Matched("@chown_lock");
							NOGUEST("@chown_lock", player);
							set_standard_lock(descr, player, arg1, MESGPROP_CHLOCK, "Chown Lock", arg2);
						}
						break;
					default:
						goto bad;
					}
					break;
				case 'l':
				case 'L':
					Matched("@clone");
					NOGUEST("@clone", player);
					BUILDERONLY("@clone", player);
					do_clone(descr, player, arg1);
					break;
				case 'o':
				case 'O':
					switch (command[4]) {
					case 'l':
					case 'L':
						Matched("@conlock");
						NOGUEST("@conlock", player);
						set_standard_lock(descr, player, arg1, MESGPROP_CONLOCK, "Container Lock", arg2);
						break;
					case 't':
					case 'T':
						Matched("@contents");
						do_contents(descr, player, arg1, arg2);
						break;
					default:
						goto bad;
					}
					break;
				case 'r':
				case 'R':
					if (string_compare(command, "@credits")) {
						Matched("@create");
						NOGUEST("@create", player);
						BUILDERONLY("@create", player);
						do_create(player, arg1, arg2);
					} else {
						do_credits(player);
					}
					break;
				default:
					goto bad;
				}
				break;
			case 'd':
			case 'D':
				/* @dbginfo, @describe, @dig, @doing,
				   @drop, @dump */
				switch (command[2]) {
#ifdef DISKBASE
				case 'b':
				case 'B':
					Matched("@dbginfo");
					WIZARDONLY("@dbginfo", player);
					diskbase_debug(player);
					break;
#endif
				case 'e':
				case 'E':
					Matched("@describe");
					NOGUEST("@describe", player);
					set_standard_property(descr, player, arg1, MESGPROP_DESC, "Object Description", arg2);
					break;
				case 'i':
				case 'I':
					Matched("@dig");
					NOGUEST("@dig", player);
					BUILDERONLY("@dig", player);
					do_dig(descr, player, arg1, arg2);
					break;
				case 'o':
				case 'O':
					Matched("@doing");
					if (!tp_who_doing)
						goto bad;
					NOGUEST("@doing", player);
					set_standard_property(descr, player, arg1, MESGPROP_DOING, "Doing", arg2);
					break;
				case 'r':
				case 'R':
					Matched("@drop");
					NOGUEST("@drop", player);
					set_standard_property(descr, player, arg1, MESGPROP_DROP, "Drop Message", arg2);
					break;
				case 'u':
				case 'U':
					Matched("@dump");
					WIZARDONLY("@dump", player);
					PLAYERONLY("@dump", player);
					do_dump(player, full_command);
					break;
				default:
					goto bad;
				}
				break;
			case 'e':
			case 'E':
				/* @edit, @entrances, @examine */
				switch (command[2]) {
				case 'd':
				case 'D':
					Matched("@edit");
					NOGUEST("@edit", player);
					PLAYERONLY("@edit", player);
					MUCKERONLY("@edit", player);
					do_edit(descr, player, arg1);
					break;
				case 'n':
				case 'N':
					Matched("@entrances");
					do_entrances(descr, player, arg1, arg2);
					break;
				case 'x':
				case 'X':
					Matched("@examine");
					GODONLY("@examine", player);
					sane_dump_object(player, arg1);
					break;
				default:
					goto bad;
				}
				break;
			case 'f':
			case 'F':
				/* @fail, @find, @flock, @force, @force_lock */
				switch (command[2]) {
				case 'a':
				case 'A':
					Matched("@fail");
					NOGUEST("@fail", player);
					set_standard_property(descr, player, arg1, MESGPROP_FAIL, "Fail Message", arg2);
					break;
				case 'i':
				case 'I':
					Matched("@find");
					do_find(player, arg1, arg2);
					break;
				case 'l':
				case 'L':
					Matched("@flock");
					NOGUEST("@flock", player);
					NOFORCE("@flock", force_level, player);
					set_standard_lock(descr, player, arg1, MESGPROP_FLOCK, "Force Lock", arg2);
					break;
				case 'o':
				case 'O':
					if(strlen(command) < 7) {
						Matched("@force");
						do_force(descr, player, arg1, arg2);
					} else {
						Matched("@force_lock");
						NOGUEST("@force_lock", player);
						NOFORCE("@force_lock", force_level, player);
						set_standard_lock(descr, player, arg1, MESGPROP_FLOCK, "Force Lock", arg2);
					}
					break;
				default:
					goto bad;
				}
				break;
			case 'h':
			case 'H':
				/* @hashes */
				Matched("@hashes");
				do_hashes(player, arg1);
				break;
			case 'i':
			case 'I':
				/* @idescribe */
				Matched("@idescribe");
				NOGUEST("@idescribe", player);
				set_standard_property(descr, player, arg1, MESGPROP_IDESC, "Inside Description", arg2);
				break;
			case 'k':
			case 'K':
				/* @kill */
				Matched("@kill");
				do_dequeue(descr, player, arg1);
				break;
			case 'l':
			case 'L':
				/* @link, @list, @lock */
				switch (command[2]) {
				case 'i':
				case 'I':
					switch (command[3]) {
					case 'n':
					case 'N':
						Matched("@link");
						NOGUEST("@link", player);
						do_link(descr, player, arg1, arg2);
						break;
					case 's':
					case 'S':
						Matched("@list");
						match_and_list(descr, player, arg1, arg2);
						break;
					default:
						goto bad;
					}
					break;
				case 'o':
				case 'O':
					Matched("@lock");
					NOGUEST("@lock", player);
					set_standard_lock(descr, player, arg1, MESGPROP_LOCK, "Lock", arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'm':
			case 'M':
				/* @mcpedit, @mcpprogram, @memory, @mpitops,
				   @muftops */
				switch (command[2]) {
#ifdef MCP_SUPPORT
				case 'c':
				case 'C':
					if (string_prefix("@mcpedit", command)) {
						Matched("@mcpedit");
						NOGUEST("@mcpedit", player);
						PLAYERONLY("@mcpedit", player);
						MUCKERONLY("@mcpedit", player);
						do_mcpedit(descr, player, arg1);
						break;
					} else {
						Matched("@mcpprogram");
						NOGUEST("@mcpprogram", player);
						PLAYERONLY("@mcpprogram", player);
						MUCKERONLY("@mcpprogram", player);
						do_mcpprogram(descr, player, arg1);
						break;
					}
#endif
#ifndef NO_MEMORY_COMMAND
				case 'e':
				case 'E':
					Matched("@memory");
					WIZARDONLY("@memory", player);
					do_memory(player);
					break;
#endif
				case 'p':
			    case 'P':
			        Matched("@mpitops");
				WIZARDONLY("@mpitops", player);
			        do_mpi_topprofs(player, arg1);
			        break;
			    case 'u':
			    case 'U':
			        Matched("@muftops");
				WIZARDONLY("@muftops", player);
			        do_muf_topprofs(player, arg1);
			        break;
				default:
					goto bad;
				}
				break;
			case 'n':
			case 'N':
				/* @name, @newpassword */
				switch (command[2]) {
				case 'a':
				case 'A':
					Matched("@name");
					NOGUEST("@name", player);
					do_name(descr, player, arg1, arg2);
					break;
				case 'e':
				case 'E':
					if (strcmp(command, "@newpassword"))
						goto bad;
					WIZARDONLY("@newpassword", player);
					PLAYERONLY("@newpassword", player);
					do_newpassword(player, arg1, arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'o':
			case 'O':
				/* @odrop, @oecho, @ofail, @open, @osuccess,
				   @owned */
				switch (command[2]) {
				case 'd':
				case 'D':
					Matched("@odrop");
					NOGUEST("@odrop", player);
					set_standard_property(descr, player, arg1, MESGPROP_ODROP, "ODrop Message", arg2);
					break;
				case 'e':
				case 'E':
					Matched("@oecho");
					NOGUEST("@oecho", player);
					set_standard_property(descr, player, arg1, MESGPROP_OECHO, "Outside-echo Prefix", arg2);
					break;
				case 'f':
				case 'F':
					Matched("@ofail");
					NOGUEST("@ofail", player);
					set_standard_property(descr, player, arg1, MESGPROP_OFAIL, "OFail Message", arg2);
					break;
				case 'p':
				case 'P':
					Matched("@open");
					NOGUEST("@open", player);
					BUILDERONLY("@open", player);
					do_open(descr, player, arg1, arg2);
					break;
				case 's':
				case 'S':
					Matched("@osuccess");
					NOGUEST("@osuccess", player);
					set_standard_property(descr, player, arg1, MESGPROP_OSUCC, "OSuccess Message", arg2);
					break;
				case 'w':
				case 'W':
					Matched("@owned");
					do_owned(player, arg1, arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'p':
			case 'P':
				/* @password, @pcreate, @pecho, @program, 
				   @propset, @ps */
				switch (command[2]) {
				case 'a':
				case 'A':
					Matched("@password");
					PLAYERONLY("@password", player);
					NOGUEST("@password", player);
					do_password(player, arg1, arg2);
					break;
				case 'c':
				case 'C':
					Matched("@pcreate");
					WIZARDONLY("@pcreate", player);
					PLAYERONLY("@pcreate", player);
					do_pcreate(player, arg1, arg2);
					break;
				case 'e':
				case 'E':
					Matched("@pecho");
					NOGUEST("@pecho", player);
					set_standard_property(descr, player, arg1, MESGPROP_PECHO, "Puppet-echo Prefix", arg2);
					break;
				case 'r':
				case 'R':
					if (string_prefix("@program", command)) {
						Matched("@program");
						NOGUEST("@program", player);
						PLAYERONLY("@program", player);
						MUCKERONLY("@program", player);
						do_prog(descr, player, arg1);
						break;
					} else {
						Matched("@propset");
						NOGUEST("@propset", player);
						do_propset(descr, player, arg1, arg2);
						break;
					}
				case 's':
				case 'S':
					Matched("@ps");
					list_events(player);
					break;
				default:
					goto bad;
				}
				break;
			case 'r':
			case 'R':
				/* @recycle, @reconfiguressl, @relink, @restart, @restrict */
				switch (command[3]) {
				case 'c':
				case 'C':
#ifdef USE_SSL
                                        if (!strcmp(command, "@reconfiguressl")) {
                                                WIZARDONLY("@reconfiguressl", player);
                                                PLAYERONLY("@reconfiguressl", player);
                                                do_reconfigure_ssl(player);
                                                break;
                                        }
#endif
                                        Matched("@recycle");
                                        NOGUEST("@recycle", player);
                                        do_recycle(descr, player, arg1);
                                        break;
				case 'l':
				case 'L':
					Matched("@relink");
					NOGUEST("@relink", player);
					do_relink(descr, player, arg1, arg2);
					break;
				case 's':
				case 'S':
					if (!strcmp(command, "@restart")) {
/*
						WIZARDONLY("@restart", player);
						PLAYERONLY("@restart", player);
*/
						do_restart(player);
					} else if (!strcmp(command, "@restrict")) {
						WIZARDONLY("@restrict", player);
						PLAYERONLY("@restrict", player);
						do_restrict(player, arg1);
					} else {
						goto bad;
					}
					break;
				default:
					goto bad;
				}
				break;
			case 's':
			case 'S':
				/* @sanity, @sanchange, @sanfix, @set,
				   @shutdown, @stats, @success, @sweep */
				switch (command[2]) {
				case 'a':
				case 'A':
					if (!strcmp(command, "@sanity")) {
						GODONLY("@sanity", player);
						sanity(player);
					} else if (!strcmp(command, "@sanchange")) {
						GODONLY("@sanchange", player);
						sanechange(player, full_command);
					} else if (!strcmp(command, "@sanfix")) {
						GODONLY("@sanfix", player);
						sanfix(player);
					} else {
						goto bad;
					}
					break;
				case 'e':
				case 'E':
					Matched("@set");
					NOGUEST("@set", player);
					do_set(descr, player, arg1, arg2);
					break;
				case 'h':
				case 'H':
					if (strcmp(command, "@shutdown"))
						goto bad;
/*
					WIZARDONLY("@shutdown", player);
					PLAYERONLY("@shutdown", player);
*/
					do_shutdown(player);
					break;
				case 't':
				case 'T':
					Matched("@stats");
					do_stats(player, arg1);
					break;
				case 'u':
				case 'U':
					Matched("@success");
					NOGUEST("@success", player);
					set_standard_property(descr, player, arg1, MESGPROP_SUCC, "Success Message", arg2);
					break;
				case 'w':
				case 'W':
					Matched("@sweep");
					do_sweep(descr, player, arg1);
					break;
				default:
					goto bad;
				}
				break;
			case 't':
			case 'T':
				/* @teleport, @toad, @trace, @tune */
				switch (command[2]) {
				case 'e':
				case 'E':
					Matched("@teleport");
					do_teleport(descr, player, arg1, arg2);
					break;
				case 'o':
				case 'O':
					if (!strcmp(command, "@toad")) {
						WIZARDONLY("@toad", player);
						PLAYERONLY("@toad", player);
						do_toad(descr, player, arg1, arg2);
					} else if (!strcmp(command, "@tops")) {
						WIZARDONLY("@tops", player);
						do_all_topprofs(player, arg1);
					} else {
						goto bad;
					}
					break;
				case 'r':
				case 'R':
					Matched("@trace");
					do_trace(descr, player, arg1, atoi(arg2));
					break;
				case 'u':
				case 'U':
					Matched("@tune");
					WIZARDONLY("@tune", player);
					PLAYERONLY("@tune", player);
					do_tune(player, arg1, arg2, !!strchr(full_command, ARG_DELIMITER));
					break;
				default:
					goto bad;
				}
				break;
			case 'u':
			case 'U':
				/* @unbless, @unlink, @unlock, @uncompile,
				   @usage */
				switch (command[2]) {
				case 'N':
				case 'n':
					if (string_prefix(command, "@unb")) {
						Matched("@unbless");
						WIZARDONLY("@unbless", player);
						PLAYERONLY("@unbless", player);
						NOFORCE("@unbless", force_level, player);
						do_unbless(descr, player, arg1, arg2);
					} else if (string_prefix(command, "@unli")) {
						Matched("@unlink");
						NOGUEST("@unlink", player);
						do_unlink(descr, player, arg1);
					} else if (string_prefix(command, "@unlo")) {
						Matched("@unlock");
						NOGUEST("@unlock", player);
						set_standard_lock(descr, player, arg1, MESGPROP_LOCK, "Lock", "");
					} else if (string_prefix(command, "@uncom")) {
						Matched("@uncompile");
						WIZARDONLY("@uncompile", player);
						PLAYERONLY("@uncompile", player);
						do_uncompile(player);
					} else {
						goto bad;
					}
					break;
#ifndef NO_USAGE_COMMAND
				case 'S':
				case 's':
					Matched("@usage");
					WIZARDONLY("@usage", player);
					do_usage(player);
					break;
#endif
				default:
					goto bad;
					break;
				}
				break;
			case 'v':
			case 'V':
				/* @version */
				Matched("@version");
				do_version(player);
				break;
			case 'w':
			case 'W':
				/* @wall */
				if (strcmp(command, "@wall"))
					goto bad;
				WIZARDONLY("@wall", player);
				PLAYERONLY("@wall", player);
				do_wall(player, full_command);
				break;
			default:
				goto bad;
			}
			break;
		case 'd':
		case 'D':
			/* disembark, drop */
			switch (command[1]) {
			case 'i':
			case 'I':
				Matched("disembark");
				do_leave(descr, player);
				break;
			case 'r':
			case 'R':
				Matched("drop");
				do_drop(descr, player, arg1, arg2);
				break;
			default:
				goto bad;
			}
			break;
		case 'e':
		case 'E':
			/* examine */
			Matched("examine");
			do_examine(descr, player, arg1, arg2);
			break;
		case 'g':
		case 'G':
			/* get, give, goto, gripe */
			switch (command[1]) {
			case 'e':
			case 'E':
				Matched("get");
				do_get(descr, player, arg1, arg2);
				break;
			case 'i':
			case 'I':
				Matched("give");
				do_give(descr, player, arg1, atoi(arg2));
				break;
			case 'o':
			case 'O':
				Matched("goto");
				do_move(descr, player, arg1, 0);
				break;
			case 'r':
			case 'R':
				if (string_compare(command, "gripe"))
					goto bad;
				do_gripe(player, full_command);
				break;
			default:
				goto bad;
			}
			break;
		case 'h':
		case 'H':
			/* help */
			Matched("help");
			do_help(player, arg1, arg2);
			break;
		case 'i':
		case 'I':
			/* inventory, info */
			if (string_compare(command, "info")) {
				Matched("inventory");
				do_inventory(player);
			} else {
				Matched("info");
				do_info(player, arg1, arg2);
			}
			break;
		case 'k':
		case 'K':
			/* kill */
			Matched("kill");
			do_kill(descr, player, arg1, atoi(arg2));
			break;
		case 'l':
		case 'L':
			/* leave, look */
			if (string_prefix("look", command)) {
				Matched("look");
				do_look_at(descr, player, arg1, arg2);
				break;
			} else {
				Matched("leave");
				do_leave(descr, player);
				break;
			}
		case 'm':
		case 'M':
			/* man, motd, move, mpi */
			if (string_prefix(command, "move")) {
				do_move(descr, player, arg1, 0);
				break;
			} else if (!string_compare(command, "motd")) {
				do_motd(player, full_command);
				break;
			} else if (!string_compare(command, "mpi")) {
				do_mpihelp(player, arg1, arg2);
				break;
			} else {
				if (string_compare(command, "man"))
					goto bad;
				do_man(player, (!*arg1 && !*arg2 && arg1 != arg2) ? "=" : arg1, arg2);
			}
			break;
		case 'n':
		case 'N':
			/* news */
			Matched("news");
			do_news(player, arg1, arg2);
			break;
		case 'p':
		case 'P':
			/* page, pose, put */
			switch (command[1]) {
			case 'a':
			case 'A':
				Matched("page");
				do_page(player, arg1, arg2);
				break;
			case 'o':
			case 'O':
				Matched("pose");
				do_pose(player, full_command);
				break;
			case 'u':
			case 'U':
				Matched("put");
				do_drop(descr, player, arg1, arg2);
				break;
			default:
				goto bad;
			}
			break;
		case 'r':
		case 'R':
			/* read, rob */
			switch (command[1]) {
			case 'e':
			case 'E':
				Matched("read");	/* undocumented alias for look */
				do_look_at(descr, player, arg1, arg2);
				break;
			case 'o':
			case 'O':
				Matched("rob");
				do_rob(descr, player, arg1);
				break;
			default:
				goto bad;
			}
			break;
		case 's':
		case 'S':
			/* say, score */
			switch (command[1]) {
			case 'a':
			case 'A':
				Matched("say");
				do_say(player, full_command);
				break;
			case 'c':
			case 'C':
				Matched("score");
				do_score(player);
				break;
			default:
				goto bad;
			}
			break;
		case 't':
		case 'T':
			/* take, throw */
			switch (command[1]) {
			case 'a':
			case 'A':
				Matched("take");
				do_get(descr, player, arg1, arg2);
				break;
			case 'h':
			case 'H':
				Matched("throw");
				do_drop(descr, player, arg1, arg2);
				break;
			default:
			goto bad;
			}
			break;
		case 'w':
		case 'W':
			/* whisper */
			Matched("whisper");
			do_whisper(descr, player, arg1, arg2);
			break;
		default:
		  bad:
			if (tp_m3_huh != 0)
			{
				char hbuf[BUFFER_LEN];
				snprintf(hbuf,BUFFER_LEN,"HUH? %s", command);
				if(can_move(descr, player, hbuf, 3)) {
					do_move(descr, player, hbuf, 3);
					*match_args = 0;
					*match_cmdname = 0;
					break;
				}
			}	
			notify(player, tp_huh_mesg);
			if (tp_log_failed_commands && !controls(player, LOCATION(player))) {
				log_status("HUH from %s(%d) in %s(%d)[%s]: %s %s",
						   NAME(player), player, NAME(LOCATION(player)),
						   LOCATION(player),
						   NAME(OWNER(LOCATION(player))), command, full_command);
			}
			break;
		}
	}

	/* calculate time command took. */
	gettimeofday(&endtime, NULL);
	if (starttime.tv_usec > endtime.tv_usec) {
		endtime.tv_usec += 1000000;
		endtime.tv_sec -= 1;
	}
	endtime.tv_usec -= starttime.tv_usec;
	endtime.tv_sec -= starttime.tv_sec;

	totaltime = endtime.tv_sec + (endtime.tv_usec * 1.0e-6);
	if (totaltime > (tp_cmd_log_threshold_msec / 1000.0)) {
		log2file(LOG_CMD_TIMES, "%6.3fs, %.16s: %s: %s",
					totaltime, ctime((time_t *)&starttime.tv_sec),
					whowhere(player), command);
	}
}
/* Update the log position of a bookmark */
int update_bookmark(EVT_HANDLE evt, os_channel *channel)
{
	DWORD size = 0;
	DWORD count = 0;
	wchar_t *buffer = NULL;
	int result = 0;
	EVT_HANDLE bookmark = NULL;
	FILE *fp = NULL;
	char tmp_file[OS_MAXSTR];

	/* Create bookmark temporary file name */
	snprintf(
		tmp_file,
		sizeof(tmp_file),
		"%s/%s-XXXXXX",
		TMP_DIR,
		channel->evt_log
	);

	replace_slash(tmp_file);

	if ((bookmark = EvtCreateBookmark(NULL)) == NULL)
	{
		log2file(
			"%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	if (!EvtUpdateBookmark(bookmark, evt))
	{
		log2file(
			"%s: ERROR: Could not EvtUpdateBookmark() bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	/* Make initial call to determine buffer size */
	result = EvtRender(NULL, bookmark, EvtRenderBookmark, 0, NULL, &size, &count);

	if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
	{
		log2file(
			"%s: ERROR: Could not EvtRender() to get buffer size to update bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	if ((buffer = calloc(size, 1)) == NULL)
	{
		log2file(
			"%s: ERROR: Could not calloc() memory to save bookmark (%s) for (%s) which returned [(%d)-(%s)]",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			errno,
			strerror(errno)
		);

		return(0);
	}

	if (!EvtRender(NULL, bookmark, EvtRenderBookmark, size, buffer, &size, &count))
	{
		log2file(
			"%s: ERROR: Could not EvtRender() bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	if (mkstemp_ex(tmp_file))
	{
		log2file(
			"%s: ERROR: Could not mkstemp_ex() temporary bookmark (%s) for (%s)",
			ARGV0,
			tmp_file,
			channel->evt_log
		);

		return(0);
	}

	if ((fp = fopen(tmp_file, "w")) == NULL)
	{
		log2file(
			"%s: ERROR: Could not fopen() temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
			ARGV0,
			tmp_file,
			channel->evt_log,
			errno,
			strerror(errno)
		);

		goto error;
	}

	if ((fwrite(buffer, 1, size, fp)) < size)
	{
		log2file(
			"%s: ERROR: Could not fwrite() to temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
			ARGV0,
			tmp_file,
			channel->evt_log,
			errno,
			strerror(errno)
		);

		goto error;
	}

	fclose(fp);

	if (rename_ex(tmp_file, channel->bookmark_filename))
	{
		log2file(
			"%s: ERROR: Could not rename_ex() temporary bookmark (%s) to (%s) for (%s)",
			ARGV0,
			tmp_file,
			channel->bookmark_filename,
			channel->evt_log
		);

		goto error;
	}

	/* success */
	return(1);

error:
	if (fp)
		fclose(fp);

	if (unlink(tmp_file))
	{
		log2file(DELETE_ERROR, ARGV0, tmp_file, errno, strerror(errno));
	}

	return(0);
}
void win_start_event_channel(char *evt_log, char future, char *query)
{
    wchar_t *wchannel = NULL;
    wchar_t *wquery = NULL;
    os_channel *channel = NULL;
    DWORD flags = EvtSubscribeToFutureEvents;
    EVT_HANDLE bookmark = NULL;
    EVT_HANDLE result = NULL;
    int status = 0;

    if ((channel = calloc(1, sizeof(os_channel))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory for channel to start reading (%s) which returned [(%d)-(%s)]",
            ARGV0,
            evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    channel->evt_log = evt_log;

    /* Create copy of event log string */
    if ((channel->bookmark_name = strdup(channel->evt_log)) == NULL) {
        log2file(
            "%s: ERROR: Could not strdup() event log name to start reading (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Replace '/' with '_' */
    if (strchr(channel->bookmark_name, '/')) {
        *(strrchr(channel->bookmark_name, '/')) = '_';
    }

    /* Convert evt_log to Windows string */
    if ((wchannel = convert_unix_string(channel->evt_log)) == NULL) {
        log2file(
            "%s: ERROR: Could not convert_unix_string() evt_log for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Convert query to Windows string */
    if (query) {
        if ((wquery = convert_unix_string(query)) == NULL) {
            log2file(
                "%s: ERROR: Could not convert_unix_string() query for (%s) which returned [(%d)-(%s)]",
                ARGV0,
                channel->evt_log,
                errno,
                strerror(errno));
            goto cleanup;
        }
    }

    channel->bookmark_enabled = !future;

    if (channel->bookmark_enabled) {
        /* Create bookmark file name */
        snprintf(channel->bookmark_filename,
                 sizeof(channel->bookmark_filename), "%s/%s", BOOKMARKS_DIR,
                 channel->bookmark_name);

        /* Try to read existing bookmark */
        if ((bookmark = read_bookmark(channel)) != NULL) {
            flags = EvtSubscribeStartAfterBookmark;
        }
    }

    result = EvtSubscribe(NULL,
                          NULL,
                          wchannel,
                          wquery,
                          bookmark,
                          channel,
                          (EVT_SUBSCRIBE_CALLBACK)event_channel_callback,
                          flags);

    if (result == NULL && flags == EvtSubscribeStartAfterBookmark) {
        result = EvtSubscribe(NULL,
                              NULL,
                              wchannel,
                              wquery,
                              NULL,
                              channel,
                              (EVT_SUBSCRIBE_CALLBACK)event_channel_callback,
                              EvtSubscribeToFutureEvents);
    }

    if (result == NULL) {
        log2file(
            "%s: ERROR: Could not EvtSubscribe() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Success */
    status = 1;

cleanup:
    free(wchannel);
    free(wquery);

    if (status == 0) {
        free(channel->bookmark_name);
        free(channel);

        if (result != NULL) {
            EvtClose(result);
        }
    }

    if (bookmark != NULL) {
        EvtClose(bookmark);
    }

    return;
}
/* Format Timestamp from EventLog */
char *WinEvtTimeToString(ULONGLONG ulongTime)
{
    SYSTEMTIME sysTime;
    FILETIME fTime, lfTime;
    ULARGE_INTEGER ulargeTime;
    struct tm tm_struct;
    char *timestamp = NULL;
    int size = 80;

    if ((timestamp = malloc(size)) == NULL) {
        log2file(
            "%s: ERROR: Could not malloc() memory to convert timestamp which returned [(%d)-(%s)]",
            ARGV0,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Zero out structure */
    memset(&tm_struct, 0, sizeof(tm_struct));

    /* Convert from ULONGLONG to usable FILETIME value */
    ulargeTime.QuadPart = ulongTime;

    fTime.dwLowDateTime = ulargeTime.LowPart;
    fTime.dwHighDateTime = ulargeTime.HighPart;

    /* Adjust time value to reflect current timezone then convert to a
     * SYSTEMTIME
     */
    if (FileTimeToLocalFileTime(&fTime, &lfTime) == 0) {
        log2file(
            "%s: ERROR: Could not FileTimeToLocalFileTime() to convert timestamp which returned (%lu)",
            ARGV0,
            GetLastError());
        goto cleanup;
    }

    if (FileTimeToSystemTime(&lfTime, &sysTime) == 0) {
        log2file(
            "%s: ERROR: Could not FileTimeToSystemTime() to convert timestamp which returned (%lu)",
            ARGV0,
            GetLastError());
        goto cleanup;
    }

    /* Convert SYSTEMTIME to tm */
    tm_struct.tm_year = sysTime.wYear - 1900;
    tm_struct.tm_mon  = sysTime.wMonth - 1;
    tm_struct.tm_mday = sysTime.wDay;
    tm_struct.tm_hour = sysTime.wHour;
    tm_struct.tm_wday = sysTime.wDayOfWeek;
    tm_struct.tm_min  = sysTime.wMinute;
    tm_struct.tm_sec  = sysTime.wSecond;

    /* Format timestamp string */
    strftime(timestamp, size, "%Y %b %d %H:%M:%S", &tm_struct);

    return (timestamp);

cleanup:
    free(timestamp);

    return (NULL);
}
void send_channel_event(EVT_HANDLE evt, os_channel *channel)
{
    DWORD buffer_length = 0;
    PEVT_VARIANT properties_values = NULL;
    DWORD count = 0;
    EVT_HANDLE context = NULL;
    os_event event = {0};
    char final_msg[OS_MAXSTR];
    int result = 0;

    if ((context = EvtCreateRenderContext(count, NULL, EvtRenderContextSystem)) == NULL) {
        log2file(
            "%s: ERROR: Could not EvtCreateRenderContext() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size necessary */
    result = EvtRender(context,
                       evt,
                       EvtRenderEventValues,
                       0,
                       NULL,
                       &buffer_length,
                       &count);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtRender() to determine buffer size for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if ((properties_values = malloc(buffer_length)) == NULL) {
        log2file(
            "%s: ERROR: Could not malloc() memory to process event (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    if (!EvtRender(context,
                   evt,
                   EvtRenderEventValues,
                   buffer_length,
                   properties_values,
                   &buffer_length,
                   &count)) {
        log2file(
            "%s: ERROR: Could not EvtRender() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    event.name = get_property_value(&properties_values[EvtSystemChannel]);
    event.id = properties_values[EvtSystemEventID].UInt16Val;
    event.source = get_property_value(&properties_values[EvtSystemProviderName]);
    event.uid = properties_values[EvtSystemUserID].Type == EvtVarTypeNull ? NULL : properties_values[EvtSystemUserID].SidVal;
    event.computer = get_property_value(&properties_values[EvtSystemComputer]);
    event.time_created = properties_values[EvtSystemTimeCreated].FileTimeVal;
    event.keywords = properties_values[EvtSystemKeywords].Type == EvtVarTypeNull ? 0 : properties_values[EvtSystemKeywords].UInt64Val;
    event.level = properties_values[EvtSystemLevel].Type == EvtVarTypeNull ? -1 : properties_values[EvtSystemLevel].ByteVal;

    switch (event.level) {
        case WINEVENT_CRITICAL:
            event.category = "CRITICAL";
            break;
        case WINEVENT_ERROR:
            event.category = "ERROR";
            break;
        case WINEVENT_WARNING:
            event.category = "WARNING";
            break;
        case WINEVENT_INFORMATION:
            event.category = "INFORMATION";
            break;
        case WINEVENT_VERBOSE:
            event.category = "DEBUG";
            break;
        case WINEVENT_AUDIT:
            if (event.keywords & WINEVENT_AUDIT_FAILURE) {
                event.category = "AUDIT_FAILURE";
                break;
            } else if (event.keywords & WINEVENT_AUDIT_SUCCESS) {
                event.category = "AUDIT_SUCCESS";
                break;
            }
        default:
            event.category = "Unknown";
            break;
    }

    if ((event.timestamp = WinEvtTimeToString(event.time_created)) == NULL) {
        log2file(
            "%s: ERROR: Could not convert timestamp for (%s)",
            ARGV0,
            channel->evt_log);
        goto cleanup;
    }

    /* Determine user and domain */
    get_username_and_domain(&event);

    /* Get event log message */
    if ((event.message = get_message(evt, properties_values[EvtSystemProviderName].StringVal, EvtFormatMessageEvent)) == NULL) {
        log2file(
            "%s: ERROR: Could not get message for (%s)",
            ARGV0,
            channel->evt_log);
    } else {
        /* Format message */
        win_format_event_string(event.message);
    }

    snprintf(
        final_msg,
        sizeof(final_msg),
        "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s",
        event.timestamp,
        event.name,
        event.category,
        event.id,
        event.source && strlen(event.source) ? event.source : "no source",
        event.user && strlen(event.user) ? event.user : "******",
        event.domain && strlen(event.domain) ? event.domain : "no domain",
        event.computer && strlen(event.computer) ? event.computer : "no computer",
        event.message && strlen(event.message) ? event.message : "(no message)"
    );

    if (SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) {
        merror(QUEUE_SEND, ARGV0);
    }

    if (channel->bookmark_enabled) {
        update_bookmark(evt, channel);
    }

cleanup:
    free(properties_values);
    free_event(&event);

    if (context != NULL) {
        EvtClose(context);
    }

    return;
}
/* Update the log position of a bookmark */
int update_bookmark(EVT_HANDLE evt, os_channel *channel)
{
    DWORD size = 0;
    DWORD count = 0;
    wchar_t *buffer = NULL;
    int result = 0;
    int status = 0;
    int clean_tmp = 0;
    EVT_HANDLE bookmark = NULL;
    FILE *fp = NULL;
    char tmp_file[OS_MAXSTR];

    /* Create temporary bookmark file name */
    snprintf(tmp_file,
             sizeof(tmp_file),
             "%s/%s-XXXXXX",
             TMP_DIR,
             channel->bookmark_name);

    if ((bookmark = EvtCreateBookmark(NULL)) == NULL) {
        log2file(
            "%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if (!EvtUpdateBookmark(bookmark, evt)) {
        log2file(
            "%s: ERROR: Could not EvtUpdateBookmark() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size */
    result = EvtRender(NULL,
                       bookmark,
                       EvtRenderBookmark,
                       0,
                       NULL,
                       &size,
                       &count);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtRender() to get buffer size to update bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if ((buffer = calloc(size, sizeof(char))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory to save bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    if (!EvtRender(NULL,
                   bookmark,
                   EvtRenderBookmark,
                   size,
                   buffer,
                   &size,
                   &count)) {
        log2file(
            "%s: ERROR: Could not EvtRender() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0, channel->bookmark_filename, channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if (mkstemp_ex(tmp_file)) {
        log2file(
            "%s: ERROR: Could not mkstemp_ex() temporary bookmark (%s) for (%s)",
            ARGV0,
            tmp_file,
            channel->evt_log);
        goto cleanup;
    }

    if ((fp = fopen(tmp_file, "w")) == NULL) {
        log2file(
            "%s: ERROR: Could not fopen() temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            tmp_file,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Help to determine whether or not temporary file needs to be removed when
     * function cleans up after itself
     */
    clean_tmp = 1;

    if ((fwrite(buffer, 1, size, fp)) < size) {
        log2file(
            "%s: ERROR: Could not fwrite() to temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            tmp_file,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    fclose(fp);

    if (rename_ex(tmp_file, channel->bookmark_filename)) {
        log2file(
            "%s: ERROR: Could not rename_ex() temporary bookmark (%s) to (%s) for (%s)",
            ARGV0,
            tmp_file,
            channel->bookmark_filename,
            channel->evt_log);
        goto cleanup;
    }

    /* Success */
    status = 1;

cleanup:
    free(buffer);

    if (bookmark != NULL) {
        EvtClose(bookmark);
    }

    if (fp) {
        fclose(fp);
    }

    if (status == 0 && clean_tmp == 1 && unlink(tmp_file)) {
        log2file(DELETE_ERROR,
                 ARGV0,
                 tmp_file,
                 errno,
                 strerror(errno));
    }

    return (status);
}
Esempio n. 27
0
/* Create a temporary file */
int mkstemp_ex(char *tmp_path)
{
    DWORD dwResult;
    int result;
    int status = -1;

    HANDLE h = NULL;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea[2];
    SECURITY_ATTRIBUTES sa;

    PSID pAdminGroupSID = NULL;
    PSID pSystemGroupSID = NULL;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};

#if defined(_MSC_VER) && _MSC_VER >= 1500
    result = _mktemp_s(tmp_path, strlen(tmp_path) + 1);

    if (result != 0) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned (%d)",
            __local_name,
            tmp_path,
            result
        );

        return (-1);
    }
#else
    if (_mktemp(tmp_path) == NULL) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]",
            __local_name,
            tmp_path,
            errno,
            strerror(errno)
        );

        return (-1);
    }
#endif

    /* Create SID for the BUILTIN\Administrators group */
    result = AllocateAndInitializeSid(
                 &SIDAuthNT,
                 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pAdminGroupSID
             );

    if (!result) {
        log2file(
            "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Create SID for the SYSTEM group */
    result = AllocateAndInitializeSid(
                 &SIDAuthNT,
                 1,
                 SECURITY_LOCAL_SYSTEM_RID,
                 0, 0, 0, 0, 0, 0, 0,
                 &pSystemGroupSID
             );

    if (!result) {
        log2file(
            "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Initialize an EXPLICIT_ACCESS structure for an ACE */
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));

    /* Add Administrators group */
    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID;

    /* Add SYSTEM group */
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID;

    /* Set entries in ACL */
    dwResult = SetEntriesInAcl(2, ea, NULL, &pACL);

    if (dwResult != ERROR_SUCCESS) {
        log2file(
            "%s: ERROR: Could not set ACL entries which returned (%lu)",
            __local_name,
            dwResult
        );

        goto cleanup;
    }

    /* Initialize security descriptor */
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
              LPTR,
              SECURITY_DESCRIPTOR_MIN_LENGTH
          );

    if (pSD == NULL) {
        log2file(
            "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
        log2file(
            "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Set owner */
    if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set owner which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Set group owner */
    if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set group owner which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Add ACL to security descriptor */
    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Initialize security attributes structure */
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = FALSE;

    h = CreateFileA(
            tmp_path,
            GENERIC_WRITE,
            0,
            &sa,
            CREATE_NEW,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );

    if (h == INVALID_HANDLE_VALUE) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned (%lu)",
            __local_name,
            tmp_path,
            GetLastError()
        );

        goto cleanup;
    }

    if (!CloseHandle(h)) {
        log2file(
            "%s: ERROR: Could not close file handle to (%s) which returned (%lu)",
            __local_name,
            tmp_path,
            GetLastError()
        );

        goto cleanup;
    }

    /* Success */
    status = 0;

cleanup:
    if (pAdminGroupSID) {
        FreeSid(pAdminGroupSID);
    }

    if (pSystemGroupSID) {
        FreeSid(pSystemGroupSID);
    }

    if (pACL) {
        LocalFree(pACL);
    }

    if (pSD) {
        LocalFree(pSD);
    }

    return (status);
}
char *get_message(EVT_HANDLE evt, LPCWSTR provider_name, DWORD flags)
{
    char *message = NULL;
    EVT_HANDLE publisher = NULL;
    DWORD size = 0;
    wchar_t *buffer = NULL;
    int result = 0;

    publisher = EvtOpenPublisherMetadata(NULL,
                                         provider_name,
                                         NULL,
                                         0,
                                         0);
    if (publisher == NULL) {
        log2file(
            "%s: ERROR: Could not EvtOpenPublisherMetadata() with flags (%lu) which returned (%lu)",
            ARGV0,
            flags,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size */
    result = EvtFormatMessage(publisher,
                              evt,
                              0,
                              0,
                              NULL,
                              flags,
                              0,
                              NULL,
                              &size);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtFormatMessage() to determine buffer size with flags (%lu) which returned (%lu)",
            ARGV0,
            flags,
            GetLastError());
        goto cleanup;
    }

    if ((buffer = calloc(size, sizeof(wchar_t))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory which returned [(%d)-(%s)]",
            ARGV0,
            errno,
            strerror(errno));
        goto cleanup;
    }

    result = EvtFormatMessage(publisher,
                              evt,
                              0,
                              0,
                              NULL,
                              flags,
                              size,
                              buffer,
                              &size);
    if (result == FALSE) {
        log2file(
            "%s: ERROR: Could not EvtFormatMessage() with flags (%lu) which returned (%lu)",
            ARGV0,
            flags,
            GetLastError());
        goto cleanup;
    }

    message = convert_windows_string(buffer);

cleanup:
    free(buffer);

    if (publisher != NULL) {
        EvtClose(publisher);
    }

    return (message);
}
int get_username_and_domain(os_event *event)
{
    int result = 0;
    int status = 0;
    DWORD user_length = 0;
    DWORD domain_length = 0;
    SID_NAME_USE account_type;
    LPTSTR StringSid = NULL;

    /* Try to convert SID to a string. This isn't necessary to make
     * things work but it is nice to have for error and debug logging.
     */
    if (!ConvertSidToStringSid(event->uid, &StringSid)) {
        debug1(
            "%s: WARN: Could not convert SID to string which returned (%lu)",
            ARGV0,
            GetLastError());
    }

    debug1("%s: DEBUG: Performing a LookupAccountSid() on (%s)",
           ARGV0,
           StringSid ? StringSid : "unknown");

    /* Make initial call to get buffer size */
    result = LookupAccountSid(NULL,
                              event->uid,
                              NULL,
                              &user_length,
                              NULL,
                              &domain_length,
                              &account_type);

    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        /* Not having a user can be normal */
        goto cleanup;
    }

    if ((event->user = calloc(user_length, sizeof(char))) == NULL) {
        log2file(
            "%s: ERROR: Could not lookup SID (%s) due to calloc() failure on user which returned [(%d)-(%s)]",
            ARGV0,
            StringSid ? StringSid : "unknown",
            errno,
            strerror(errno));
        goto cleanup;
    }

    if ((event->domain = calloc(domain_length, sizeof(char))) == NULL) {
        log2file(
            "%s: ERROR: Could not lookup SID (%s) due to calloc() failure on domain which returned [(%d)-(%s)]",
            ARGV0,
            StringSid ? StringSid : "unknown",
            errno,
            strerror(errno));
        goto cleanup;
    }

    result = LookupAccountSid(NULL,
                              event->uid,
                              event->user,
                              &user_length,
                              event->domain,
                              &domain_length,
                              &account_type);
    if (result == FALSE) {
        log2file(
            "%s: ERROR: Could not LookupAccountSid() for (%s) which returned (%lu)",
            ARGV0,
            StringSid ? StringSid : "unknown",
            GetLastError());
        goto cleanup;
    }

    /* Success */
    status = 1;

cleanup:
    if (status == 0) {
        free(event->user);
        free(event->domain);

        event->user = NULL;
        event->domain = NULL;
    }

    if (StringSid) {
        LocalFree(StringSid);
    }

    return (status);
}
Esempio n. 30
0
RETSIGTYPE sig_reap(int i)
{
	/* If DISKBASE is not defined, then there are two types of
	 * children that can die.  First is the nameservice resolver.
	 * Second is the database dumper.  If resolver exits, we should
	 * note it in the log -- at least give the admin the option of
	 * knowing about it, and dealing with it as necessary. */

	/* The fix for SSL connections getting closed when databases were
	 * saved with DISKBASE disabled required closing all sockets 
	 * when the server fork()ed.  This made it impossible for that
	 * process to spit out the "save done" message.  However, because
	 * that process dies as soon as it finishes dumping the database,
	 * can detect that the child died, and broadcast the "save done"
	 * message anyway. */

	int status = 0;
	int reapedpid = 0;

	reapedpid = waitpid(-1, &status, WNOHANG);
	if(!reapedpid)
	{
#ifdef DETACH
		log2file(LOG_ERR_FILE,"SIG_CHILD signal handler called with no pid!");
#else
		fprintf(stderr, "SIG_CHILD signal handler called with no pid!\n");
#endif
	} else {
		if (reapedpid == global_resolver_pid) {
			log_status("resolver exited with status %d", status);
			if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
				/* If the resolver exited with an error, respawn it. */
				spawn_resolver();
			} else if (WIFSIGNALED(status)) {
				/* If the resolver exited due to a signal, respawn it. */
				spawn_resolver();
			}
#ifndef DISKBASE
		} else if(reapedpid == global_dumper_pid) {
			int warnflag = 0;

			log_status("forked DB dump task exited with status %d", status);

			if (WIFSIGNALED(status)) {
				warnflag = 1;
			} else if (WIFEXITED(status)) {
				/* In case NOCOREDUMP is defined, check for panic()s exit codes. */
				int statres = WEXITSTATUS(status);
				if (statres == 135 || statres == 136) {
					warnflag = 1;
				}
			}
			if (warnflag) {
				wall_wizards("# WARNING: The forked DB save process crashed while saving the database.");
				wall_wizards("# This is probably due to memory corruption, which can crash this server.");
				wall_wizards("# Unless you have a REALLY good unix programmer around who can try to fix");
				wall_wizards("# this process live with a debugger, you should try to restart this Muck");
				wall_wizards("# as soon as possible, and accept the data lost since the previous DB save.");
			}
			global_dumpdone = 1;
			global_dumper_pid = 0;
#endif
		} else {
			fprintf(stderr, "unknown child process (pid %d) exited with status %d\n", reapedpid, status);
		}
	}
	return RETSIGVAL;
}