1,7 → 1,7 |
/****************************************************************** |
* |
* Daemon which waiting on specified TCP port for special string |
* and reboot the computer. |
* Daemon which waits on specified TCP port for special string |
* and reboots the computer. |
* |
* Command line: rebootdaemon [--port PORT] [--config CONFIG_FILE] |
* Defaults are port 19 and config /etc/rebootdaemon.conf. |
35,8 → 35,8 |
#include <netinet/in.h> |
#include <arpa/inet.h> |
|
#define PORT 19 |
#define CFG_FILE "/etc/rebootdaemon.conf" |
#define DEFAULT_PORT 19 |
#define DEFAULT_CFG_FILE "/etc/rebootdaemon.conf" |
#define CMDSIZE 4096 |
#define BUFSIZE 4096 |
#define MAX_CONFIG_LINE 4096 |
55,8 → 55,6 |
char password[MAX_CONFIG_LINE]; |
}; |
|
static struct config cfg; |
|
static int parse_cmd_line(int argc, char* argv[], long *port, char *config_name); |
static int parse_config_file(char *config_name, long *port, char *password); |
|
89,7 → 87,7 |
return s; |
} |
|
static void listen_socket(int socket) |
static void listen_socket(struct config *cfg, int socket) |
{ |
int t; |
char cmd[CMDSIZE]; |
122,7 → 120,7 |
|
syslog(LOG_INFO, "got command [%s]", cmd); |
|
if(0 == strncmp(cmd, cfg.password, sizeof(cmd))) { |
if(0 == strncmp(cmd, cfg->password, sizeof(cmd))) { |
syslog(LOG_EMERG, "REBOOT"); |
sleep(5); |
if(reboot(RB_AUTOBOOT) < 0) { |
151,27 → 149,29 |
return 0; |
} |
|
static int read_config(int argc, char* argv[]) |
static int read_config(struct config *cfg, int argc, char* argv[]) |
{ |
long cmd_port; |
long file_port; |
char cmd_config[MAX_CONFIG_LINE]; |
|
if(!parse_cmd_line(argc, argv, &cmd_port, cmd_config)) return 0; |
if(!parse_cmd_line(argc, argv, &cmd_port, cmd_config)) |
return 0; |
|
if(!parse_config_file(cmd_config[0] != '\0' ? cmd_config : CFG_FILE, &file_port, cfg.password)) return 0; |
if(!parse_config_file(cmd_config[0] != '\0' ? cmd_config : DEFAULT_CFG_FILE, &file_port, cfg->password)) |
return 0; |
|
if(cfg.password[0] == '\0') { |
if(cfg->password[0] == '\0') { |
fprintf(stderr, "Password is not set\n"); |
return 0; |
} |
|
if(cmd_port > 0) |
cfg.port = (int)cmd_port; |
cfg->port = (int)cmd_port; |
else if(file_port > 0) |
cfg.port = (int)file_port; |
cfg->port = (int)file_port; |
else |
cfg.port = PORT; |
cfg->port = DEFAULT_PORT; |
|
return 1; |
} |
305,19 → 305,79 |
return 1; |
} |
|
static int create_child(int socket) |
{ |
pid_t child; |
|
child = fork(); |
if(child == -1) { |
fprintf(stderr, "Cannot fork: %s\n", strerror(errno)); |
return 2; /* an unexpected error */ |
} |
else if(child > 0) { |
if(close(socket) != 0) { |
fprintf(stderr, "Cannot close socket: %s\n", strerror(errno)); |
return 2; /* an unexpected error */ |
} |
return 0; /* we are the parent */ |
} |
else { |
return 1; /* we are the child */ |
} |
} |
|
static int close_descr(int d) |
{ |
if(close(d) != 0) { |
syslog(LOG_ERR, "Cannot close descriptor %d: %s\n", d, strerror(errno)); |
return 0; |
} |
return 1; |
} |
|
int main(int argc, char* argv[]) |
{ |
int s; |
int socket; |
struct config cfg; |
|
if(!read_config(argc, argv)) return 1; |
|
if((s = establish(cfg.port)) < 0) { |
/* get config */ |
if(!read_config(&cfg, argc, argv)) return 1; |
|
/* try to listen the port */ |
if((socket = establish(cfg.port)) < 0) { |
fprintf(stderr, "Cannot listen to port %i\n", cfg.port); |
return 1; |
} |
|
listen_socket(s); |
/* fork and release the console */ |
switch(create_child(socket)) { |
case 0: return 0; |
case 2: return 2; |
} |
|
/* continue as first child */ |
if(setsid() == -1) { |
fprintf(stderr, "Cannot create session: %s\n", strerror(errno)); |
return 2; |
} |
|
/* fork the second time */ |
switch(create_child(socket)) { |
case 0: return 0; |
case 2: return 2; |
} |
|
/* continue as final child, from now do not use console for error output */ |
chdir("/"); |
umask(0); |
if(!close_descr(0)) return 2; |
if(!close_descr(1)) return 2; |
if(!close_descr(2)) return 2; |
|
syslog(LOG_INFO, "listen on %d", cfg.port); |
listen_socket(&cfg, socket); |
|
return 0; |
} |
|