1,7 → 1,7 |
/****************************************************************** |
* rebootd. |
* |
* A daemon which waits on specified TCP port for special string |
* A daemon which waits on specified UDP port for special string |
* (password) and reboots the computer. |
* |
* Command line: rebootd [--version] [--help] [--interface IP] [--port PORT] [--config CONFIG_FILE] |
15,7 → 15,7 |
* -------------------------- |
* |
* Usage example (from any other host): |
* echo -n "some password" | nc host_to_rebot 19 |
* echo -n "some password" | nc -uo host_to_rebot 19 |
* |
* Copyleft 2005 Anatoli Klassen |
* |
121,7 → 121,7 |
sa.sin_port = htons(cfg->port); |
sa.sin_addr.s_addr = (cfg->interface.s_addr ? cfg->interface.s_addr : INADDR_ANY); |
|
if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) |
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) |
return -1; |
|
if(bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { |
129,54 → 129,38 |
return -1; |
} |
|
if(listen(s, 1) != 0) { |
close(s); |
return -1; |
} |
|
return s; |
} |
|
static void listen_socket(const struct config *cfg, int soc) |
{ |
int t; |
char cmd[CMDSIZE]; |
char buf[BUFSIZE]; |
int br; |
struct sockaddr_in sa; |
socklen_t sa_len; |
int cmdlen; |
char buf[BUFSIZE]; |
int br; |
struct sockaddr_storage ss; |
socklen_t ss_size; |
|
for(;;) { |
sa_len = sizeof(sa); |
if((t = accept(soc, (struct sockaddr *)&sa, &sa_len)) < 0) { |
if(errno == EINTR) { /* EINTR might happen on accept(), */ |
if(reconfig_needed) return; |
} |
else { |
syslog(LOG_ERR, "cannot get connection, %s", strerror(errno)); |
} |
ss_size = sizeof(ss); |
br = recvfrom(soc, buf, sizeof(buf)-1, 0, (struct sockaddr *)&ss, &ss_size); |
|
if(br == 0) { |
if(reconfig_needed) return; |
continue; |
} |
else if(br < 0) { |
syslog(LOG_INFO, "cannot receive: %s", strerror(errno)); |
continue; |
} |
|
syslog(LOG_INFO, "connect from %s", inet_ntoa(sa.sin_addr)); |
|
cmd[0] = '\0'; |
cmdlen = 0; |
while((br = recv(t, buf, BUFSIZE, 0)) > 0) { |
strncat(cmd, buf, min((uint)br, sizeof(cmd) - cmdlen - 1)); |
cmdlen += min((uint)br, sizeof(cmd) - cmdlen - 1); |
} |
buf[br] = '\0'; |
sleep(1); |
close(t); |
|
syslog(LOG_INFO, "got command"); |
|
if(0 == strncmp(cmd, cfg->password, sizeof(cmd))) { |
if(0 == strncmp(buf, cfg->password, sizeof(buf))) { |
syslog(LOG_EMERG, "REBOOT"); |
sleep(5); |
if(reboot(RB_AUTOBOOT) < 0) { |
syslog(LOG_ERR, "cannot reboot, %s", strerror(errno)); |
syslog(LOG_ERR, "cannot reboot, %s", strerror(errno)); |
} |
} |
} |
190,7 → 174,7 |
static void pring_usage(int argc, const char* argv[]) |
{ |
print_version(); |
printf("\nA daemon which waits on specified TCP port for special"); |
printf("\nA daemon which waits on specified UDP port for special"); |
printf(" string (password) and reboots the computer.\n\n"); |
printf("Usage: %s [--interface IP] [--port PORT] [--config CONFIG_FILE]\n", argv[0]); |
printf(" or: %s --version\n", argv[0]); |
198,7 → 182,7 |
printf("Defaults are port 19 and config /etc/rebootd.conf.\n\n"); |
printf("Config file looks like:\n--------------------------\n"); |
printf("interface=192.168.0.1\nport=19\npassword=\"some password\"\n--------------------------\n\n"); |
printf("Then run from any other host:\necho -n \"some password\" | nc host_to_rebot 19\n"); |
printf("Then run from any other host:\necho -n \"some password\" | nc -uo host_to_rebot 19\n"); |
} |
|
static int print_error(const char *msg, const char *value) |