75,20 → 75,20 |
#define CONFIG_PASSWORD "password" |
|
struct config { |
int port; |
char password[MAX_CONFIG_LINE]; |
ushort port; |
char password[MAX_CONFIG_LINE]; |
}; |
|
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); |
static int get_revision(); |
static int parse_cmd_line(int argc, const char* argv[], long *port, char *config_name); |
static int parse_config_file(const char *config_name, long *port, char *password); |
static int get_revision(void); |
|
static int min(int a, int b) |
static uint min(uint a, uint b) |
{ |
return (a < b) ? a : b; |
} |
|
static int establish(unsigned short portnum) |
static int establish(ushort port) |
{ |
int s; |
struct sockaddr_in sa; |
96,7 → 96,7 |
memset(&sa, 0, sizeof(struct sockaddr_in)); |
|
sa.sin_family = AF_INET; |
sa.sin_port = htons(portnum); |
sa.sin_port = htons(port); |
sa.sin_addr.s_addr = INADDR_ANY; |
|
if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) |
115,7 → 115,7 |
return s; |
} |
|
static void listen_socket(struct config *cfg, int socket) |
static void listen_socket(const struct config *cfg, int soc) |
{ |
int t; |
char cmd[CMDSIZE]; |
127,7 → 127,7 |
|
for(;;) { |
sa_len = sizeof(sa); |
if((t = accept(socket, (struct sockaddr *)&sa, &sa_len)) < 0) { |
if((t = accept(soc, (struct sockaddr *)&sa, &sa_len)) < 0) { |
if(errno == EINTR) /* EINTR might happen on accept(), */ |
continue; /* try again */ |
|
140,8 → 140,8 |
cmd[0] = '\0'; |
cmdlen = 0; |
while((br = recv(t, buf, BUFSIZE, 0)) > 0) { |
strncat(cmd, buf, min(br, sizeof(cmd) - cmdlen - 1)); |
cmdlen += min(br, sizeof(cmd) - cmdlen - 1); |
strncat(cmd, buf, min((uint)br, sizeof(cmd) - cmdlen - 1)); |
cmdlen += min((uint)br, sizeof(cmd) - cmdlen - 1); |
} |
sleep(1); |
close(t); |
158,12 → 158,12 |
} |
} |
|
static void print_version() |
static void print_version(void) |
{ |
printf("%s %s.%d\n", APP_NAME, VERSION, get_revision()); |
} |
|
static void pring_usage(int argc, char* argv[]) |
static void pring_usage(int argc, const char* argv[]) |
{ |
print_version(); |
printf("\nA daemon which waits on specified TCP port for special string and reboots the computer.\n\n"); |
176,7 → 176,7 |
printf("Then run from any other host:\necho -n \"some password\" | nc host_to_rebot 19\n"); |
} |
|
static int print_cmd_error(int argc, char* argv[], char *msg, char *value) |
static int print_cmd_error(int argc, const char* argv[], const char *msg, const char *value) |
{ |
fprintf(stderr, "%s", msg); |
if(value) fprintf(stderr, " - %s\n", value); |
187,7 → 187,7 |
return RESULT_ERROR; |
} |
|
static int print_config_error(char *config_name, int line, char *msg, char *value) |
static int print_config_error(const char *config_name, int line, const char *msg, const char *value) |
{ |
fprintf(stderr, "Error in %s, line %d: %s", config_name, line, msg); |
if(value) fprintf(stderr, " - %s", value); |
197,7 → 197,7 |
} |
|
/* return: 0 - no error, continue; 1 - no error, but exit; 2 - user error, exit; 3 - unexpected error, exit */ |
static int read_config(struct config *cfg, int argc, char* argv[]) |
static int read_config(struct config *cfg, int argc, const char* argv[]) |
{ |
int res_cmd_line; |
int res_config_file; |
218,9 → 218,9 |
} |
|
if(cmd_port > 0) |
cfg->port = (int)cmd_port; |
cfg->port = (ushort)cmd_port; |
else if(file_port > 0) |
cfg->port = (int)file_port; |
cfg->port = (ushort)file_port; |
else |
cfg->port = DEFAULT_PORT; |
|
227,7 → 227,7 |
return RESULT_OK; |
} |
|
static int parse_cmd_line(int argc, char* argv[], long *port, char *config_name) |
static int parse_cmd_line(int argc, const char* argv[], long *port, char *config_name) |
{ |
char *end; |
int i; |
281,7 → 281,7 |
} |
|
|
static int parse_config_file(char *config_name, long *port, char *password) |
static int parse_config_file(const char *config_name, long *port, char *password) |
{ |
FILE *config_file; |
char buf[MAX_CONFIG_LINE]; |
289,6 → 289,7 |
char *subline; |
char *cur; |
int count; |
uint len; |
|
config_file = fopen(config_name, "r"); |
if(!config_file) { |
302,7 → 303,7 |
line = buf; |
|
/* skip end spaces */ |
int len = strlen(line); |
len = strlen(line); |
if(len == MAX_CONFIG_LINE-1) |
return print_config_error(config_name, count, "Line is too long", NULL); |
while(len && isspace(line[len-1])) --len; |
372,21 → 373,21 |
return RESULT_OK; |
} |
|
static int get_revision() |
static int get_revision(void) |
{ |
int r; |
char *begin; |
int r; |
const char *begin; |
|
begin = REVISION; |
while(begin[0] != '\0' && begin[0] != ':') begin++; |
if(begin[0] == '\0') return 0; |
begin++; |
r = strtol(begin, (char**)NULL, 10); |
r = (int)strtol(begin, (char**)NULL, 10); |
|
return r; |
} |
|
static int create_child(int socket) |
static int create_child(int soc) |
{ |
pid_t child; |
|
396,7 → 397,7 |
return RESULT_UNEXPECTED; /* an unexpected error */ |
} |
else if(child > 0) { |
if(close(socket) != 0) { |
if(close(soc) != 0) { |
fprintf(stderr, "Cannot close socket: %s\n", strerror(errno)); |
return RESULT_UNEXPECTED; /* an unexpected error */ |
} |
416,29 → 417,29 |
return RESULT_OK; |
} |
|
int main(int argc, char* argv[]) |
int main(int argc, const char* argv[]) |
{ |
int socket; |
int soc; |
struct config cfg; |
|
/* get config */ |
switch(read_config(&cfg, argc, argv)) { |
case RESULT_EXIT: return EXIT_OK; // no error but exit |
case RESULT_ERROR: return EXIT_USER_ERROR; // user error |
case RESULT_UNEXPECTED: return EXIT_UNEXPECTED; // unexpected error |
case RESULT_EXIT: return EXIT_OK; /* no error but exit */ |
case RESULT_ERROR: return EXIT_USER_ERROR; /* user error */ |
case RESULT_UNEXPECTED: return EXIT_UNEXPECTED; /* unexpected error */ |
} |
|
/* try to listen the port */ |
if((socket = establish(cfg.port)) < 0) { |
if((soc = establish(cfg.port)) < 0) { |
fprintf(stderr, "Cannot listen to port %i\n", cfg.port); |
return EXIT_USER_ERROR; |
} |
|
/* fork and release the console */ |
switch(create_child(socket)) { |
case RESULT_EXIT: return EXIT_OK; // no error but exit |
case RESULT_ERROR: return EXIT_USER_ERROR; // user error |
case RESULT_UNEXPECTED: return EXIT_UNEXPECTED; // unexpected error |
switch(create_child(soc)) { |
case RESULT_EXIT: return EXIT_OK; /* no error but exit */ |
case RESULT_ERROR: return EXIT_USER_ERROR; /* user error */ |
case RESULT_UNEXPECTED: return EXIT_UNEXPECTED; /* unexpected error */ |
} |
|
/* continue as first child */ |
448,10 → 449,10 |
} |
|
/* fork the second time */ |
switch(create_child(socket)) { |
case RESULT_EXIT: return EXIT_OK; // no error but exit |
case RESULT_ERROR: return EXIT_USER_ERROR; // user error |
case RESULT_UNEXPECTED: return EXIT_UNEXPECTED; // unexpected error |
switch(create_child(soc)) { |
case RESULT_EXIT: return EXIT_OK; /* no error but exit */ |
case RESULT_ERROR: return EXIT_USER_ERROR; /* user error */ |
case RESULT_UNEXPECTED: return EXIT_UNEXPECTED; /* unexpected error */ |
} |
|
/* continue as final child, from now do not use console for error output */ |
462,8 → 463,8 |
if(close_descr(2) != RESULT_OK) return EXIT_UNEXPECTED; |
|
syslog(LOG_INFO, "listen on %d", cfg.port); |
listen_socket(&cfg, socket); |
listen_socket(&cfg, soc); |
|
return EXIT_OK; // unreachedable |
return EXIT_OK; /* unreachedable */ |
} |
|