Linux Q3 Server - How to send console messages?

Locked
NjR_Shrapnel
Posts: 18
Joined: Fri Sep 23, 2005 6:36 pm

Linux Q3 Server - How to send console messages?

Post by NjR_Shrapnel »

Hello, all!

Well, I've searched and searched and can't find anything about this. Something tells me it should be simple, though.

I want to send a console message (and/or command) to my linux server from a cron command. It needs to be at a set time, so pb_sv_task won't do it for me.

Is there any way to send commands to the q3 program as if I were typing them in on the server console itself? I don't need to do this remotely, just want the same machine to do it at a specified time.

Any ideas?

Thanks!!!!

- Shrapnel
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

Compile with: $ gcc -O2 -s -D_GNU_SOURCE -Wall -ansi -o q3rcon q3rcon.c
Run as: $ ./q3rcon localhost 27960 your_rconpassword "say hello, quake3world"

Note that this will (briefly) reveal your rconpassword to other users on your Linux box by means of `ps aux`. Hardcode the password if you want to prevent that (though there is always `strings q3rcon`, obviously).

Code: Select all

/* q3rcon
 *
 * Send rcon commands to a remote Q3A server.
 * Likely works for for Q3A-derived games too.
 * Written by B.W.R "misantropia" Noordhuis.
 * Released under the BSD License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

int main(int argc, char **argv) {
	struct sockaddr_in peer;
	struct hostent *pent;
	char command[512];
	int sock, retval;

	if (argc != 5) {
		printf("q3rcon  hostname  port  rconpassword  \"command\"\n");
		return EXIT_FAILURE;
	}

	/* DNS lookup target host. */
	if (!(pent = gethostbyname(argv[1]))) {
		herror("gethostbyname");
		return EXIT_FAILURE;
	}

	/* Create UDP socket. */
	if (!(sock = socket(PF_INET, SOCK_DGRAM, 0))) {
		perror("socket");
		return EXIT_FAILURE;
	}

	peer.sin_port = htons(atoi(argv[2]));
	peer.sin_addr = *((struct in_addr *)pent->h_addr);
	peer.sin_family = AF_INET;
	memset(peer.sin_zero, 0, sizeof(peer.sin_zero));

	/* See ftp://ftp.idsoftware.com/idstuff/quake3/docs/server.txt for details. */
	if (snprintf(command, sizeof(command), "\xff\xff\xff\xffrcon %s %s\r\n", argv[3], argv[4]) == sizeof(command) - 1) {
		printf("Rcon password and/or command too long.\n");
		retval = EXIT_FAILURE;
	} else if (sendto(sock, command, strlen(command), 0, (struct sockaddr *)&peer, sizeof(struct sockaddr)) < 0) {
		perror("sendto");
		retval = EXIT_FAILURE;
	} else {
		retval = EXIT_SUCCESS;
	}

	close(sock);
	return retval;
}
NjR_Shrapnel
Posts: 18
Joined: Fri Sep 23, 2005 6:36 pm

Post by NjR_Shrapnel »

Awesome! Works like a charm!!

:icon14: :icon14: :icon14: :icon14: :icon14: :icon14:

Thanks!

- Shrapnel
Underpants?
Posts: 4755
Joined: Mon Oct 22, 2001 7:00 am

Post by Underpants? »

I never knew charlieantropia, I knever new... :headshakecolon
Locked